Writing Code for People James Downing 17 th February 2011.

47
Writing Code for People James Downing 17 th February 2011
  • date post

    19-Dec-2015
  • Category

    Documents

  • view

    217
  • download

    3

Transcript of Writing Code for People James Downing 17 th February 2011.

Writing Code for People

James Downing 17th February 2011

About Me

• University: MPhys (2002 to 2006)

• Tessella (2006 to …)• ITER

• Nominet

• Wellcome Trust

FUSION Research Project

Building a fusion Tokamak in the South of France

30 Years to demonstrate scientific feasibility and economic attractiveness

100 Million Parts to design, build and assemble

7 Parties collaborating, requiring exchange of ideas, designs and parts across 3 continents

ITER Software

Technical Website

Interfacing Management

Document Management

Engineering Database

Joint European Torus

Nominet UK

.uk Domain Name registry

Creates master Zone File

99% Uptime

Millions of requests/day

7 Million users

Overhaul and addition to all systems

Registrations

Online Registrant services

Online Registrar services

Finance

Dispute Resolution

ENUM

Cataloguing the structure of Protein Complexes

SPINE2 Target Tracker

Tracking Progress on Target Proteins

Modeling the Experimental Pipeline

Multiple Branches at Each Stage

Modelling the Entry Descent and

Landing System for ExoMars

Conclusions

Variety of Technologies

Variety of Domains

Lots of Different and Interesting Challenges

Always need other people to be able to understand the code

WRITING CODE FOR PEOPLE

Why write software?How does a business keep on making money?

DOCUMENTATION

Documents

• Requirements

• Design/Architecture

• Test Scripts

• Installation Guide

• Manual

• Maintenance Guide

Comments

// We need to check if the approver of the // document still has permission to see itDocument doc = gateway.GetDocumentById(documentId);

PermissionSet perm = new PermissionSet(user, doc);

// Changed by John (August)

return perm.CanView();

Comments/* ********************************** * r23 21-Jan-2009 John * Created class * * r23 12-Feb-2009 Bob * Added Co-Author property * * r23 01-Mar-2009 Dave * Created class * * r23 21-June-2010 John * Implemented new Workflow * * **************************************/public class Document{

Comments

public class Class1{    private int x;

    public bool Check(Document d)    {        int t = 0;        for (int i = 0; i < d.Sections.Count; i++)        {            for (int j = 0; j < d.Sections[i].Paras.Count; j++)            {                t += d.Sections[i].Paras[j].Words.Count;            }        }        return t <= x;    }}

public class Class1{    // Declare the max integer X    public int x;

    // Checks the document    public bool Check(Document d)    {        // Keeps a running count, start at 0        int t = 0;        // Loop over the sections        for (int i = 0; i < d.Sections.Count; i++)        {            // Loop over the paragraphs in the section            for (int j = 0; j < d.Sections[i].Paras.Count; j++)            {                // Increment the total count                t += d.Sections[i].Paras[j].Words.Count;            }        }        // Check that t is less than or equal to x        return t <= x;    }}

public class Class1{    // The word limit    public int x;

    // Checks the document is within the word limit    public bool Check(Document d)    {        // To check that the document is in the word limit we have to add up        //  all of the number of words in each paragraph in each section of the document.        //  We can then compare this to the word limit.        int t = 0;        for (int i = 0; i < d.Sections.Count; i++)        {            for (int j = 0; j < d.Sections[i].Paras.Count; j++)            {                t += d.Sections[i].Paras[j].Words.Count;            }        }        // Check that the document word count is within the word limit        return t <= x;    }}

public class WordLimitValidator{       public int wordLimit;            public bool IsWithinWordLimit(Document d)    {             return document.WordCount <= this.wordLimit;    }}

READABILITY

Re-Factoring

Readability

Do not use booleans as arguments!

String CreateFile(String filename, Boolean overwriteExisting, Boolean keepOpen){

String CreateFile(String filename, CreateMode fileMode, LockMode lockMode){

CreateFile("file.csv", true, false);

CreateFile("file.csv", CreateMode.OverwriteExisting, LockMode.KeepOpen);

Readability

Does it fit on one screen?

AndAlso (document.Author.Department.Head = currentUser.Manager OrElse version.

Readability

Does your code describe the domain?

String

Public

Integer

XmlDocument

Class

Float

DateTimeDocument

Document

Public

Author

Signature

ClassS

tring

VersionXmlDocument

SMELLS

Smells

• Duplicated code: identical or very similar code exists in more than one location.

• Long method: a method, function, or procedure that has grown too large.• Large class: a class that has grown too large. See God object.• Feature envy: a class that uses methods of another class excessively.• Inappropriate intimacy: a class that has dependencies on implementation

details of another class.• Refused bequest: a class that overrides a method of a base class in such a

way that the contract of the base class is not honoured by the derived class. See Liskov substitution principle.

• Lazy class / Freeloader: a class that does too little.• Contrived complexity: forced usage of overly complicated design

patterns where simpler design would suffice.• Excessively long identifiers: in particular, the use of naming conventions to

provide disambiguation that should be implicit in the software architecture.• Excessive use of literals: these should be coded as named constants, to

improve readability and to avoid programming errors.

PATTERNS

Null Object

void NotifyDepartmentHead(IPerson person) { if (person.Section != null && person.Section.Division != null && person.Section.Division.Department != null && person.Section.Division.Department.Manager != null) { if (! string.IsNullOrEmpty(

person.Section.Division.Department.Manager.EmailAddress)) { SendEmail(person.Section.Division.Department.Manager.EmailAddress); } } }

Null Object

public class NullSection : ISection {

public IDivision Division { get { return new NullDivision(); } }

public IPerson Manager { get { return new NullPerson(); } } }

public class NullDivision : IDivision {

public IDepartment Department { get { return new NullDepartment(); } }

public IPerson Manager { get { return new NullPerson() } } }

Null Object

void NotifyDepartmentHead(IPerson person){ String address = person.Section.Division.Department.Manager.EmailAddress; if (!String.IsNullOrEmpty(address)) SendMail(address);}

Factory Pattern

Adapters and Decorators

Conclusion

• Software needs to change, so it must be EASY to change

• The CODE is always right

• Write your code so it is easy to understand

• You can use patterns to solve common problems

• Agile methodologies embrace change

Suggested Reading

• 97 Things Every Programmer Should Know [O’Reilly]

• Patterns of Enterprise Application Architecture, by Martin Fowler

• Head First Design Patterns, by Eric T Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra

• Java Puzzlers: Traps, Pitfalls, and Corner Cases, by Joshua Bloch, Neal Gafter

IF VALUE-RESET ="Y" OR VALUE-RESET = "T" MOVE 0 TO VAL

function GetPosString(position) { switch (position) { case 0: return "1st"; case 1: return "2nd"; case 2: return "3rd" ; default: return (position + 1) + "th"; }}

if (!$email){ global $Email; $email=$Email; if (!$email){ global $Email_Address; $email=$Email_Address; if (!$email){ global $email_address; $email=$email_address; if (!$email){ global $EmailAddress; $email = $EmailAddress; if (!$email){ global $emailaddress; $email = $emailaddress; if (!$email){ global $EMailAddress; $email = $EMailAddress; } } } } }}

public class Document {

// Creates a new document object that is not yet in the database public Document(String id, int version) { // ... }

// Loads a document object from the database public Document(int version, String id) { // ... }

onreadystatechange = function(){

switch(httpReq.readyState){ case 0: if(httpReq.readyState == 0){ break; } case 1: if(httpReq.readyState == 1){ break; } case 2: if(httpReq.readyState == 2){ break; } case 3: if(httpReq.readyState == 3){ break; } case 4: if(httpReq.readyState == 4){ if(httpReq.status == 200){ var val = httpReq.responseText;

alert(httpReq.responseText) dataInsert(val); break; } else{ alert("Error "+httpReq.status); break; } } }};

// assign variableslogFile.info("START: Assigning variables.");logFile.debug("Getting particular drug information.");

// gets drugsbrandNameDrugs = Utils.formatDrugList(dl.getDrugsByLabel(calculateBean.getDrugName())); logFile.debug("Getting major classifications.");

// get all major classifications (usage)majorClassifications = cl.getMajorClassifications(); logFile.debug("Getting classifications.");

// get all classificationsclassifications = cl.getClassifications(); logFile.debug("Getting all classifications.");

// gets all the major classifications and classificationsallClassifications = cl.getAllClassifications(); logFile.info("END: Assigning variables.");

// assign variables to session for search.jsplogFile.info("START: Assigning variables to the session.");logFile.debug("Storing brandNameDrugs to the session.");request.setAttribute("brandNameDrugs", brandNameDrugs);logFile.debug("Storing majorClassifications to the session.");request.setAttribute("majorClassifications", majorClassifications);logFile.debug("Storing classifications to the session.");request.setAttribute("classifications", classifications);logFile.debug("Storing allClassifications to the session.");request.setAttribute("allClassifications", allClassifications);logFile.info("END: Assigning variables to the session.");

// "true" or "false"public static string Bool2Str(bool b){ switch(b) { case true: return System.Boolean.TrueString; case false: return System.Boolean.FalseString; default: return "error"; }}

Public Shared Sub isValidQuery(ByVal query As String) ‘…End Sub

‘'To Get date from SAP XMl as they are providing date like 20090330        Public Shared Function Getformateddate(ByVal strDate As String) As Date            Dim month As String = strDate.Substring(4, 2)            Dim year As String = strDate.Substring(0, 4)            Dim day As String = strDate.Substring(6, 2)            Dim tempdate As Date = Convert.ToDateTime(day + "/" + month + "/" + year)            Return CDate(tempdate.ToShortDateString)        End Function

''çatch exception incase the date is null not correct format.            Try                If strDate.Trim.Length = 8 AndAlso IsNumeric(strDate) Then                    Dim month As String = strDate.Substring(4, 2)                    Dim year As String = strDate.Substring(0, 4)                    Dim day As String = strDate.Substring(6, 2)                    Dim tempdate As Date = New Date(CInt(year), CInt(month), CInt(day))                    Return CDate(tempdate.ToShortDateString)                End If            Catch ex As Exception                Return Nothing            End Try

Dim user As IPerson = icp.ContentDispatcher.user            Dim super As Boolean = user.IsDBManager            user.setAsDbManager()            ‘ Snip

            If Not super Then                user.removeAsDbManager()            End If

Public Overrides Sub HandleAction(ByVal action As IAction)         Dim ct As IContentType = Me.getContentType()            Select Case action.Name                Case EIDMActions.CoverPage                    handleCoverPage()

                Case EIDMActions.RemoveCoverPage                    RemoveCoverPage()

                Case EActions.copy                    If icp.ContentDispatcher.User IsNot Nothing Then _                    TSQLDataAccessLayer.saveInterfaceValue(icp.ContentDispatcher.User.Uid & ButtonAction.Action_Copy, doc.uid)

                Case EIDMActions.DocumentObsolete                    Me.version_status = EVersion_status.version_obsolete                    Me.save()                    doc.setCurrentVersion()

                Case EIDMActions.DocumentSign           ''for sign action                    signDocument()

                Case EIDMActions.DocumentRecommend                    HandleRecommendAction()

                Case EIDMActions.DocumentApproved         ''for approve document                    If Check_AllReviewersRecommended() Then                        HandleApproveAction()                    Else  System.Web.HttpContext.Current.Response.Redirect("ApproveComment.aspx?uid=" & Me.uid & "&commenttype=" & EDocumentComments.ApproveComment)                    End If