85
High-Quality High-Quality Programming Code Programming Code Construction – Part Construction – Part I I Revealing the Secrets of Self- Revealing the Secrets of Self- Documenting Code Documenting Code Svetlin Nakov Svetlin Nakov Telerik Telerik Corporation Corporation www.telerik. com For C# Developers For C# Developers

21 high-quality programming code construction part-i

Embed Size (px)

DESCRIPTION

High-quality programming code construction part 1

Citation preview

Page 1: 21 high-quality programming code construction part-i

High-Quality High-Quality Programming Code Programming Code

Construction – Part IConstruction – Part IRevealing the Secrets of Self-Revealing the Secrets of Self-

Documenting CodeDocumenting Code

Svetlin NakovSvetlin NakovTelerik Telerik

CorporationCorporationwww.telerik.com

For C# DevelopersFor C# Developers

Page 2: 21 high-quality programming code construction part-i

Table of ContentsTable of Contents What is High-Quality Programming What is High-Quality Programming

Code?Code? External and Internal Code QualityExternal and Internal Code Quality

Naming IdentifiersNaming Identifiers Naming Types, Classes, Interfaces, Naming Types, Classes, Interfaces,

Enumerations, Properties, Methods, Enumerations, Properties, Methods, Parameters, Variables, Constants, etc.Parameters, Variables, Constants, etc.

Code FormattingCode Formatting Designing High-Quality ClassesDesigning High-Quality Classes

Abstraction, Encapsulation,Abstraction, Encapsulation, Inheritance, Reasons to Create a ClassInheritance, Reasons to Create a Class

2

Page 3: 21 high-quality programming code construction part-i

What is High-Quality What is High-Quality Programming Code?Programming Code?

Page 4: 21 high-quality programming code construction part-i

Why the Code Quality Is Why the Code Quality Is Important?Important?

What does this code do? Is it correct?What does this code do? Is it correct?

4

static void Main()static void Main(){{ int value=010, i=5, w;int value=010, i=5, w; switch(value){case switch(value){case 10:w=5;Console.WriteLine(w);break;case 9:i=0;break;10:w=5;Console.WriteLine(w);break;case 9:i=0;break; case 8:Console.WriteLine("8 ");break;case 8:Console.WriteLine("8 ");break; default:Console.WriteLine("def ");{default:Console.WriteLine("def ");{

Console.WriteLine("hoho ");Console.WriteLine("hoho "); }} for (int k = 0; k < i; k++, Console.WriteLine(k for (int k = 0; k < i; k++, Console.WriteLine(k - 'f'));break;} { Console.WriteLine("loop!"); }- 'f'));break;} { Console.WriteLine("loop!"); }}}

Page 5: 21 high-quality programming code construction part-i

Why the Code Quality Is Why the Code Quality Is Important? (2)Important? (2)

Now the code is formatted, but is still unclear.Now the code is formatted, but is still unclear.5

static void Main()static void Main(){{ int value = 010, i = 5, w;int value = 010, i = 5, w; switch (value)switch (value) {{ case 10: w = 5; Console.WriteLine(w); break;case 10: w = 5; Console.WriteLine(w); break; case 9: i = 0; break;case 9: i = 0; break; case 8: Console.WriteLine("8 "); break;case 8: Console.WriteLine("8 "); break; default:default: Console.WriteLine("def ");Console.WriteLine("def "); Console.WriteLine("hoho ");Console.WriteLine("hoho "); for (int k = 0; k < i; k++, Console.WriteLine(k - for (int k = 0; k < i; k++, Console.WriteLine(k - 'f')) ; 'f')) ; break;break; }} Console.WriteLine("loop!");Console.WriteLine("loop!");}}

Page 6: 21 high-quality programming code construction part-i

Software QualitySoftware Quality External qualityExternal quality

Does the software behave correctly?Does the software behave correctly? Are the produced results correct?Are the produced results correct? Does the software runDoes the software run fast?fast? Is the software UI easy-to-use?Is the software UI easy-to-use?

Internal qualityInternal quality It the code easy to read and It the code easy to read and

understand?understand? It the code well structured?It the code well structured? Is the code easy to modify?Is the code easy to modify?

6

Page 7: 21 high-quality programming code construction part-i

What is High-Quality What is High-Quality Programming Code?Programming Code?

High-quality programming code:High-quality programming code: Easy to read and understandEasy to read and understand

Easy to modify and maintainEasy to modify and maintain

Correct behavior in all casesCorrect behavior in all cases Well testedWell tested

Well architectured and designedWell architectured and designed Well documentedWell documented

Self-documenting code Self-documenting code

Well formattedWell formatted7

Page 8: 21 high-quality programming code construction part-i

Code ConventionsCode Conventions Code conventionsCode conventions are formal guidelines are formal guidelines

about the style of the source code:about the style of the source code: Code formatting conventionsCode formatting conventions

Indentation, whitespace, etc.Indentation, whitespace, etc.

Naming conventionsNaming conventions PascalCasePascalCase or or camelCasecamelCase, prefixes, suffixes, , prefixes, suffixes,

etc.etc.

Best practicesBest practices Classes, interfaces, enumerations, Classes, interfaces, enumerations,

structures, inheritance, exceptions, structures, inheritance, exceptions, properties, events, constructors, fields, properties, events, constructors, fields, operators, etc.operators, etc.

8

Page 9: 21 high-quality programming code construction part-i

Code Conventions (2)Code Conventions (2) Microsoft has official code conventions calledMicrosoft has official code conventions called

Design Guidelines for Developing Class Design Guidelines for Developing Class Libraries: Libraries: http://msdn.microsoft.com/en-us/library/ms229042.aspx

Large organizations follow strict Large organizations follow strict conventionsconventions Code conventions can vary in different teamsCode conventions can vary in different teams

Most conventions developers follow the official Most conventions developers follow the official Microsoft's recommendations but extend themMicrosoft's recommendations but extend them

High-quality code goes beyond code High-quality code goes beyond code conventionsconventions Software quality is not just a set of Software quality is not just a set of

conventions – its is a way of thinkingconventions – its is a way of thinking 9

Page 10: 21 high-quality programming code construction part-i

Managing ComplexityManaging Complexity Managing complexity Managing complexity plays a central role plays a central role

in software constructionin software construction Minimize the amount of complexity that Minimize the amount of complexity that

anyone’s brain has to deal with at certain anyone’s brain has to deal with at certain time time

Architecture and design challengesArchitecture and design challenges Design modules and classes to reduce Design modules and classes to reduce

complexitycomplexity Code construction challengesCode construction challenges

Apply good software construction Apply good software construction practices: classes, methods, variables, practices: classes, methods, variables, naming, statements, error handling, naming, statements, error handling, formatting, comments, etc.formatting, comments, etc. 10

Page 11: 21 high-quality programming code construction part-i

Managing Complexity Managing Complexity (2)(2)

Key to being an effective Key to being an effective programmer:programmer: Maximizing the portion of a Maximizing the portion of a

program that you can safely ignore program that you can safely ignore while working on any one section of while working on any one section of codecode

Most practices discussed later Most practices discussed later propose ways to achieve this propose ways to achieve this important goalimportant goal

11

Page 12: 21 high-quality programming code construction part-i

Key Key Characteristics Characteristics of High-Quality of High-Quality

CodeCode Correct behaviorCorrect behavior

Conforming to the requirementsConforming to the requirements Stable, no hangs, no crashesStable, no hangs, no crashes Bug freeBug free Correct response to incorrect usageCorrect response to incorrect usage

Easy to readEasy to read Easy to understandEasy to understand Maintainable – easy to modify Maintainable – easy to modify

when requiredwhen required 12

Page 13: 21 high-quality programming code construction part-i

Naming IdentifiersNaming IdentifiersNaming Classes, Interfaces, Naming Classes, Interfaces,

Enumerations, Methods, Variables Enumerations, Methods, Variables and Constantsand Constants

Page 14: 21 high-quality programming code construction part-i

General Naming General Naming GuidelinesGuidelines

Always use EnglishAlways use English How you will feel if you read How you will feel if you read

Vietnamese code with variables Vietnamese code with variables named in Vietnamese?named in Vietnamese?

English is the only language that all English is the only language that all software developers speaksoftware developers speak

Avoid abbreviationsAvoid abbreviations Example: Example: scrpCntscrpCnt vs. vs. scriptsCountscriptsCount

Avoid hard-to-pronounce namesAvoid hard-to-pronounce names Example: Example: dtbgRegExPtrndtbgRegExPtrn vs. vs. dateTimeBulgarianRegExPatterndateTimeBulgarianRegExPattern 14

Page 15: 21 high-quality programming code construction part-i

Use Meaningful NamesUse Meaningful Names Always prefer using meaningful namesAlways prefer using meaningful names

Names should answer these questions:Names should answer these questions: What does this class do? What is the intent What does this class do? What is the intent

of this variable? What is this variable / class of this variable? What is this variable / class used for?used for?

Examples:Examples: FactorialCalculatorFactorialCalculator, , studentsCountstudentsCount, , Math.PIMath.PI, , configFileNameconfigFileName, , CreateReportCreateReport

Incorrect examples: Incorrect examples: kk, , k2k2,, k3k3,, junkjunk,, f33f33,, KJJKJJ,, button1button1, , variablevariable,, temp temp, , tmptmp, , temp_vartemp_var, , somethingsomething, , someValuesomeValue

15

Page 16: 21 high-quality programming code construction part-i

Names Should be Names Should be Meaningful in Their Meaningful in Their

ContextContext Whether a name is meaningful or not Whether a name is meaningful or not

depends on its context (its enclosing type)depends on its context (its enclosing type) Examples of meaningful names:Examples of meaningful names:

Generate()Generate() in the class in the class LabyrinthGeneratorLabyrinthGenerator

Find(stringFind(string fileName)fileName) in the class in the class FileFinderFileFinder

Deposit(decimalDeposit(decimal amount)amount) in the class in the class AccountAccount Examples of meaningless names:Examples of meaningless names:

Generate()Generate() in the class in the class ProgramProgram

Find(stringFind(string fileName)fileName) in the class in the class ProgramProgram

16

Page 17: 21 high-quality programming code construction part-i

Fake Meaningful NamesFake Meaningful Names Junior developers often use Junior developers often use

meaningful names that are in fact meaningful names that are in fact meaninglessmeaningless Bad naming examples:Bad naming examples:

Topic6Exercise12Topic6Exercise12, , LoopsExercise12LoopsExercise12,, Problem7Problem7, , OOPLecture_LastExerciseOOPLecture_LastExercise

Yes, Yes, Topic6Exercise12Topic6Exercise12 indicates that indicates that this is solution to exercise 12, but this is solution to exercise 12, but what is it about?what is it about?

Better naming:Better naming: MaximalNumbersSubsequenceMaximalNumbersSubsequence 17

Page 18: 21 high-quality programming code construction part-i

Naming TypesNaming Types Naming types (classes, structures, Naming types (classes, structures,

etc.)etc.) Use Use PascalCasePascalCase character casing character casing Examples:Examples:

RecursiveFactorialCalculatorRecursiveFactorialCalculator, , TreeSetTreeSet, , XmlDocumentXmlDocument, , IEnumerableIEnumerable, , ColorColor, , TreeNodeTreeNode, , InvalidTransactionExceptionInvalidTransactionException, , MainFormMainForm

Incorrect examples: Incorrect examples: recursiveFactorialCalculatorrecursiveFactorialCalculator, , recursive_factorial_calculatorrecursive_factorial_calculator, , RECURSIVE_FACTORIAL_CALCULATORRECURSIVE_FACTORIAL_CALCULATOR 18

Page 19: 21 high-quality programming code construction part-i

Naming Classes and Naming Classes and StructuresStructures

Use the following formats:Use the following formats: [Noun][Noun] [Adjective] + [Noun][Adjective] + [Noun]

Examples:Examples: StudentStudent, , FileSystemFileSystem, , BinaryTreeNodeBinaryTreeNode, , ConstantsConstants, , MathUtilsMathUtils, , TextBoxTextBox, , CalendarCalendar

Incorrect examples:Incorrect examples: MoveMove, , FindUsersFindUsers, , FastFast, , OptimizeOptimize, , ExtremlyExtremly, , FastFindInDatabaseFastFindInDatabase, , CheckCheck

19

Page 20: 21 high-quality programming code construction part-i

Naming InterfacesNaming Interfaces Following formats are acceptable:Following formats are acceptable:

''II' + [Verb] + '' + [Verb] + 'ableable'' ''II' + [Noun], '' + [Noun], 'II' + [Adjective] + [Noun]' + [Adjective] + [Noun]

Examples:Examples: IEnumerableIEnumerable, , IFormattableIFormattable, , IDataReaderIDataReader,, IList IList, , IHttpModuleIHttpModule,, ICommandExecutorICommandExecutor

Incorrect examples:Incorrect examples: ListList, , FindUsersFindUsers, , IFastIFast, , IMemoryOptimizeIMemoryOptimize, , OptimizerOptimizer, , FastFindInDatabaseFastFindInDatabase, , CheckBoxCheckBox 20

Page 21: 21 high-quality programming code construction part-i

Naming EnumerationsNaming Enumerations Several formats are acceptable:Several formats are acceptable:

[Noun] or [Verb] or [Adjective][Noun] or [Verb] or [Adjective] Use the same style for all membersUse the same style for all members Examples:Examples:

enum Day {Monday,enum Day {Monday, Tuesday,Tuesday, Wednesday,Wednesday, …}…}, , enum AppState {Running,enum AppState {Running, Finished,Finished, …}…}, ,

enum WindowState {Normal,enum WindowState {Normal, Maximized,Maximized, …}…}

Incorrect examples:Incorrect examples: enum Color {red, green, blue, white}enum Color {red, green, blue, white}, , enum PAGE_FORMAT {A4, A5, A3, LEGAL, …}enum PAGE_FORMAT {A4, A5, A3, LEGAL, …}

21

Page 22: 21 high-quality programming code construction part-i

Naming Special ClassesNaming Special Classes ExceptionsExceptions

Add Add ''ExceptionException' as suffix' as suffix

Use informative nameUse informative name

Example: Example: FileNotFoundExceptionFileNotFoundException

Incorrect example: Incorrect example: FileNotFoundErrorFileNotFoundError Delegate ClassesDelegate Classes

Add Add ''DelegateDelegate' or '' or 'EventHandlerEventHandler' as ' as suffixsuffix

Example: Example: DownloadFinishedDelegateDownloadFinishedDelegate

Incorrect example: Incorrect example: WakeUpNotificationWakeUpNotification22

Page 23: 21 high-quality programming code construction part-i

The Length of Class The Length of Class NamesNames

How long could be the name of a class How long could be the name of a class / struct / interface / enum?/ struct / interface / enum? The name should be as long as The name should be as long as

requiredrequired Don't abbreviate the names if this Don't abbreviate the names if this

could make them unclearcould make them unclear Your IDE has autocomplete, right?Your IDE has autocomplete, right?

Examples: Examples: FileNotFoundExceptionFileNotFoundException, , CustomerSupportNotificationServiceCustomerSupportNotificationService

Incorrect examples: Incorrect examples: FNFExceptionFNFException, , CustSuppNotifSrvcCustSuppNotifSrvc

23

Page 24: 21 high-quality programming code construction part-i

Naming NamespacesNaming Namespaces Namespaces naming guidelinesNamespaces naming guidelines

Use PascalCaseUse PascalCase Following formats are acceptable:Following formats are acceptable:

Company.Product.Component. …Company.Product.Component. … Product.Component.…Product.Component.…

Example:Example: Telerik.WinControls.GridViewTelerik.WinControls.GridView

Incorrect example:Incorrect example: Telerik_WinControlsGridViewTelerik_WinControlsGridView, , ClassesClasses

24

Page 25: 21 high-quality programming code construction part-i

Naming AssembliesNaming Assemblies Assembly names should follow the Assembly names should follow the

root namespace in its class root namespace in its class hierarchyhierarchy

Examples:Examples: Telerik.WinControls.GridView.dllTelerik.WinControls.GridView.dll Oracle.DataAccess.dllOracle.DataAccess.dll Interop.CAPICOM.dllInterop.CAPICOM.dll

Incorrect examples:Incorrect examples: Telerik_WinControlsGridView.dllTelerik_WinControlsGridView.dll OracleDataAccess.dllOracleDataAccess.dll 25

Page 26: 21 high-quality programming code construction part-i

Naming MethodsNaming Methods Methods naming guidelinesMethods naming guidelines

Method names should be meaningfulMethod names should be meaningful Should answer the question:Should answer the question:

What does this method do?What does this method do?

If you cannot find a good name for a If you cannot find a good name for a method, think about does it have clear method, think about does it have clear intentintent

Examples: Examples: FindStudentFindStudent, , LoadReportLoadReport, , SinusSinus Incorrect examples: Incorrect examples: Method1Method1, , DoSomethingDoSomething, , HandleStuffHandleStuff, , SampleMethodSampleMethod, , DirtyHackDirtyHack

26

Page 27: 21 high-quality programming code construction part-i

Naming Methods (2)Naming Methods (2) Use PascalCase character casingUse PascalCase character casing

Example: Example: LoadSettingsLoadSettings, not , not loadSettingsloadSettings Prefer the following formats:Prefer the following formats:

[Verb][Verb] [Verb] + [Noun], [Verb] + [Adjective] + [Verb] + [Noun], [Verb] + [Adjective] +

[Noun][Noun] Examples: Examples: ShowShow, , LoadSettingsFileLoadSettingsFile, , FindNodeByPatternFindNodeByPattern, , ToStringToString, , PrintListPrintList

Incorrect examples: Incorrect examples: StudentStudent, , CounterCounter, , WhiteWhite, , GeneratorGenerator, , ApproximationApproximation, , MathUtilsMathUtils

27

Page 28: 21 high-quality programming code construction part-i

Methods Returning a Methods Returning a ValueValue

Methods returning values should Methods returning values should describe the returned valuedescribe the returned value

Examples:Examples: ConvertMetersToInchesConvertMetersToInches, not , not MetersInchesMetersInches

or or ConvertConvert or or ConvertUnitConvertUnit Meters2InchesMeters2Inches is still acceptable is still acceptable CalculateSinusCalculateSinus is good is good

SinusSinus is also acceptable is also acceptable

Ensure that the unit of measure of Ensure that the unit of measure of obviousobvious

Prefer Prefer MeasureFontInPixelsMeasureFontInPixels to to MeasureFontMeasureFont28

Page 29: 21 high-quality programming code construction part-i

Single Purpose of All Single Purpose of All MethodsMethods

Methods should have a single purpose!Methods should have a single purpose! Otherwise they cannot be named wellOtherwise they cannot be named well How to name a method that creates How to name a method that creates

annual incomes report, downloads annual incomes report, downloads updates from internet and scans the updates from internet and scans the system for viruses?system for viruses?

CreateAnnualIncomesReportDownloadUpdatCreateAnnualIncomesReportDownloadUpdatesAndScanForVirusesesAndScanForViruses is a nice name, is a nice name, right?right?

Methods that have multiple purposes Methods that have multiple purposes (weak cohesion) are hard to be named(weak cohesion) are hard to be named Need to be refactored instead of namedNeed to be refactored instead of named 29

Page 30: 21 high-quality programming code construction part-i

Consistency in Methods Consistency in Methods NamingNaming

Use consistent naming in the entire Use consistent naming in the entire projectproject LoadFileLoadFile, , LoadImageFromFileLoadImageFromFile, , LoadSettingsLoadSettings, , LoadFontLoadFont, , LoadLibraryLoadLibrary, but not , but not ReadTextFileReadTextFile

Use consistently the opposites at the Use consistently the opposites at the same level of abstraction:same level of abstraction: LoadLibraryLoadLibrary vs. vs. UnloadLibraryUnloadLibrary, but not , but not FreeHandleFreeHandle

OpenFileOpenFile vs. vs. CloseFileCloseFile, but not , but not DeallocateResourceDeallocateResource

GetNameGetName vs. vs. SetNameSetName, but not , but not AssignNameAssignName 30

Page 31: 21 high-quality programming code construction part-i

The Length of Method The Length of Method NamesNames

How long could be the name of a How long could be the name of a method?method? The name should be as long as The name should be as long as

requiredrequired Don't abbreviateDon't abbreviate Your IDE has autocompleteYour IDE has autocomplete

Examples:Examples: LoadCustomerSupportNotificationServiceLoadCustomerSupportNotificationService, , CreateMonthlyAndAnnualIncomesReportCreateMonthlyAndAnnualIncomesReport

Incorrect examples:Incorrect examples: LoadCustSuppSrvcLoadCustSuppSrvc, , CreateMonthIncReportCreateMonthIncReport31

Page 32: 21 high-quality programming code construction part-i

Naming Method Naming Method ParametersParameters

Method parameters namesMethod parameters names Preferred form: [Noun] or [Adjective] + Preferred form: [Noun] or [Adjective] +

[Noun][Noun] Should be in camelCaseShould be in camelCase Should be meaningfulShould be meaningful Unit of measure should be obviousUnit of measure should be obvious

Examples: Examples: firstNamefirstName, , reportreport, , usersListusersList, , fontSizeInPixelsfontSizeInPixels, , speedKmHspeedKmH, , fontfont

Incorrect examples: Incorrect examples: pp, , p1p1, , p2p2, , populatepopulate, , LastNameLastName, , last_namelast_name, , convertImageconvertImage 32

Page 33: 21 high-quality programming code construction part-i

Naming VariablesNaming Variables Variable namesVariable names

Should be in camelCaseShould be in camelCase Preferred form: [Noun] or [Adjective] + Preferred form: [Noun] or [Adjective] +

[Noun][Noun] Should explain the purpose of the variableShould explain the purpose of the variable

If you can't find good name for a variable If you can't find good name for a variable check if it has a single purposecheck if it has a single purpose

Exception: variables with very small scope, Exception: variables with very small scope, e.g. the index variable in a 3-lines long for-e.g. the index variable in a 3-lines long for-looploop

Names should be consistent in the projectNames should be consistent in the project

33

Page 34: 21 high-quality programming code construction part-i

Naming Variables – Naming Variables – ExampleExample

Examples:Examples: firstNamefirstName, , reportreport, , usersListusersList , , fontSizefontSize, , maxSpeedmaxSpeed, , fontfont, , startIndexstartIndex, , endIndexendIndex, , charsCountcharsCount, , configSettingsXmlconfigSettingsXml, , configconfig, , dbConnectiondbConnection, , sqlCommandCreateUsersqlCommandCreateUser

Incorrect examples:Incorrect examples: foofoo, , barbar, , pp, , p1p1, , p2p2, , populatepopulate, , LastNameLastName, , last_namelast_name, , LAST_NAMELAST_NAME, , convertImageconvertImage, , moveMarginmoveMargin, , MAXSpeedMAXSpeed, , _firstName_firstName, , __temp__temp, , firstNameMiddleNameAndLastNamefirstNameMiddleNameAndLastName 34

Page 35: 21 high-quality programming code construction part-i

More about Naming More about Naming VariablesVariables

The name should be addressed to the The name should be addressed to the problem we solve, not to the means problem we solve, not to the means we use to solve itwe use to solve it Prefer nouns from the business domain Prefer nouns from the business domain

to computer termsto computer terms Examples:Examples:

accountsaccounts, , customerscustomers, , customerAddresscustomerAddress, , accountHolderaccountHolder, , paymentPlanpaymentPlan, , vipPlayervipPlayer

Incorrect examples:Incorrect examples: accountsLinkedListaccountsLinkedList, , customersHashtablecustomersHashtable, , paymentsPriorityQueuepaymentsPriorityQueue, , playersArrayplayersArray

35

Page 36: 21 high-quality programming code construction part-i

Naming Boolean Naming Boolean VariablesVariables

Boolean variables should imply Boolean variables should imply truetrue or or falsefalse

Prefixes like Prefixes like isis, , hashas and and cancan are useful are useful Use positive boolean variable namesUse positive boolean variable names

Incorrect example:Incorrect example: Examples:Examples:

hasPendingPaymenthasPendingPayment, , customerFoundcustomerFound, , validAddressvalidAddress, , positiveBalancepositiveBalance, , isPrimeisPrime

Incorrect examples:Incorrect examples: notFoundnotFound, , runrun, , programStopprogramStop, , playerplayer, , listlist, , findCustomerByIdfindCustomerById, , isUnsuccessfullisUnsuccessfull

36

if (! notFound) { … if (! notFound) { … }}

Page 37: 21 high-quality programming code construction part-i

Naming Special Naming Special VariablesVariables

Naming CountersNaming Counters Establish a convention, e.g. [Noun] + Establish a convention, e.g. [Noun] +

''CountCount'' Examples: Examples: ticketsCountticketsCount, , customersCountcustomersCount

StateState Establish a convention, e.g. [Noun] + Establish a convention, e.g. [Noun] +

''StateState'' Examples: Examples: blogParseStateblogParseState, , threadStatethreadState

Variables with small scope and spanVariables with small scope and span Short names can be used, e.g. Short names can be used, e.g. indexindex, , ii, , uu 37

Page 38: 21 high-quality programming code construction part-i

Temporary VariablesTemporary Variables

Do really Do really temporary variables temporary variables exist?exist? All variables in a program are All variables in a program are

temporary because they are used temporary because they are used temporarily only during the temporarily only during the program execution, right?program execution, right?

Temporary variables can always be Temporary variables can always be named better than named better than temptemp or or tmptmp::

38

// Swap a[i] and // Swap a[i] and a[j]a[j]int int temptemp = a[i]; = a[i];a[i] = a[j];a[i] = a[j];a[j] = a[j] = temptemp;;

// Swap a[i] and // Swap a[i] and a[j]a[j]int int oldValueoldValue = a[i]; = a[i];a[i] = a[j];a[i] = a[j];a[j] = a[j] = oldValueoldValue;;

Page 39: 21 high-quality programming code construction part-i

The Length of Variable The Length of Variable NamesNames

How long could be the name of a How long could be the name of a variable?variable? Depends on the variable scope and Depends on the variable scope and

lifetimelifetime

More "famous" variables should have More "famous" variables should have longer and more self-explaining namelonger and more self-explaining name

Acceptable naming examples:Acceptable naming examples:

Unacceptable naming examples:Unacceptable naming examples:

39

for (int i=0; i<users.Length; for (int i=0; i<users.Length; i++)i++) if (i % 2 == 0)if (i % 2 == 0) sum += users[i].Weight;sum += users[i].Weight;

class Student {class Student { public string public string lastName;lastName;}}

class Student {class Student { private int i;private int i;}}

class PairOfLists {class PairOfLists { public int Count { get; public int Count { get; set; }set; }}}

Page 40: 21 high-quality programming code construction part-i

Prefixes / Suffixes and Prefixes / Suffixes and Hungarian NotationHungarian Notation

In C# prefix / suffix notations are not In C# prefix / suffix notations are not popularpopular

Hungarian notationHungarian notation Using prefixes to denote the variable Using prefixes to denote the variable

types, e.g. types, e.g. lpcstrTextlpcstrText, , lpdwFlagslpdwFlags, , cbMultiBytecbMultiByte, , hWndhWnd

The Hungarian notation works well in The Hungarian notation works well in unmanaged languages like C++unmanaged languages like C++ Do not use Hungarian notation in C# Do not use Hungarian notation in C#

and .NETand .NET Don't use prefixes / suffixes to denote the Don't use prefixes / suffixes to denote the

variable data typevariable data type 40

Page 41: 21 high-quality programming code construction part-i

Naming PropertiesNaming Properties Name properties in C# using a noun, Name properties in C# using a noun,

noun phrase, or an adjectivenoun phrase, or an adjective Use Pascal CaseUse Pascal Case Examples:Examples:

Incorrect examples:Incorrect examples:

41

public int Length { … }public int Length { … }public Color BackgroundColor { … }public Color BackgroundColor { … }public CacheMode CacheMode { … }public CacheMode CacheMode { … }public bool Loaded { … }public bool Loaded { … }

public int Load { … }public int Load { … }public Color backgroundColor { … }public Color backgroundColor { … }public bool Font { … }public bool Font { … }

Page 42: 21 high-quality programming code construction part-i

Naming ConstantsNaming Constants Use CAPITAL_LETTERS for Use CAPITAL_LETTERS for constconst fields fields

and and PascalCasePascalCase for for readonlyreadonly fields fields Use meaningful names that describe Use meaningful names that describe

their valuetheir value Examples:Examples:

Incorrect examples:Incorrect examples:

42

private const int READ_BUFFER_SIZE = 8192;private const int READ_BUFFER_SIZE = 8192;public static readonly PageSize DefaultPageSize = public static readonly PageSize DefaultPageSize = PageSize.A4;PageSize.A4;private const int FONT_SIZE_IN_POINTS = 16;private const int FONT_SIZE_IN_POINTS = 16;

public const int MAX = 512; // Max what? Apples or public const int MAX = 512; // Max what? Apples or Oranges?Oranges?public const int BUF256 = 256; // What about BUF256 = public const int BUF256 = 256; // What about BUF256 = 1024?1024?public const string GREATER = "&gt;"; // public const string GREATER = "&gt;"; // GREATER_HTML_ENTITYGREATER_HTML_ENTITYpublic const int FONT_SIZE = 16; // 16pt or 16px?public const int FONT_SIZE = 16; // 16pt or 16px?public const PageSize PAGE = PageSize.A4; // Maybe public const PageSize PAGE = PageSize.A4; // Maybe PAGE_SIZE?PAGE_SIZE?

Page 43: 21 high-quality programming code construction part-i

Names to AvoidNames to Avoid Don't use numbers in the identifiers Don't use numbers in the identifiers

namesnames Example: Example:

PrintReportPrintReport and and PrintReport2PrintReport2

What is the difference?What is the difference?

Exceptions:Exceptions: When the number is part of the name When the number is part of the name

itself, e.g. itself, e.g. RS232PortRS232Port, , COM3COM3, , Win32APIFunctionsWin32APIFunctions

Don't use Cyrillic or letters from other Don't use Cyrillic or letters from other alphabetsalphabets E.g. E.g. FindСтудентByNameFindСтудентByName, , CalcΩ2ProteinCalcΩ2Protein 43

Page 44: 21 high-quality programming code construction part-i

Never Give a Never Give a Misleading Name!Misleading Name!

Giving a misleading name is worse Giving a misleading name is worse than giving a totally unclear namethan giving a totally unclear name

Example:Example: Consider a method that calculates the Consider a method that calculates the

sum of all elements in an arraysum of all elements in an array Its should be named Its should be named SumSum or or CalculateSumCalculateSum

What about naming it What about naming it CalculateAverageCalculateAverage or or MaxMax or or CheckForNegativeNumberCheckForNegativeNumber??

It's crazy, but be careful with "copy-It's crazy, but be careful with "copy-paste"paste"

44

Page 45: 21 high-quality programming code construction part-i

Don't Believe Microsoft!Don't Believe Microsoft! Microsoft sometimes use really bad Microsoft sometimes use really bad

naming in their API libraries (especially naming in their API libraries (especially in Win32 API)in Win32 API) Examples:Examples:

NavigateNavigate and and Navigate2Navigate2 methods in methods in Internet Explorer ActiveX control Internet Explorer ActiveX control ((MSHTML.DLLMSHTML.DLL))

WNetAddConnection3WNetAddConnection3 method in Multiple method in Multiple Provider Router Networking API (Provider Router Networking API (MPR.DLLMPR.DLL))

LPWKSTA_USER_INFO_1LPWKSTA_USER_INFO_1 structure in Win32 structure in Win32

Don't follow them blindly, just think a Don't follow them blindly, just think a bit!bit!

45

Page 46: 21 high-quality programming code construction part-i

What's Wrong with This What's Wrong with This Code?Code?

46

FileStream fs = new FileStream(FILE_NAME, FileMode.CreateNew);FileStream fs = new FileStream(FILE_NAME, FileMode.CreateNew);

// Create the writer for data.// Create the writer for data.BinaryWriter w = new BinaryWriter(fs);BinaryWriter w = new BinaryWriter(fs);

// Write data to Test.data.// Write data to Test.data.for (int i = 0; i < 11; i++) for (int i = 0; i < 11; i++) {{ w.Write( (int) i);w.Write( (int) i);}}

w.Close();w.Close();fs.Close();fs.Close();

// Create the reader for data.// Create the reader for data.fs = new FileStream(FILE_NAME, FileMode.Open, fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);FileAccess.Read);BinaryReader r = new BinaryReader(fs);BinaryReader r = new BinaryReader(fs);

// Read data from Test.data.// Read data from Test.data.for (int i = 0; i < 11; i++) for (int i = 0; i < 11; i++) {{ Console.WriteLine(r.ReadInt32());Console.WriteLine(r.ReadInt32());}}

r.Close();r.Close();fs.Close();fs.Close();

Source: http://msdn.microsoft.com/en-us/library/36b93480.aspx

Page 47: 21 high-quality programming code construction part-i

Code Code FormattingFormatting

Page 48: 21 high-quality programming code construction part-i

Why Code Needs Why Code Needs Formatting?Formatting?

48

public const string public const string FILE_NAMEFILE_NAME="example.bin" ; static void Main ( ="example.bin" ; static void Main ( ){ ){FileStream fs= new FileStream fs= new FileStream(FILE_NAME,FileModeFileStream(FILE_NAME,FileMode. CreateNew) // Create the writer for . CreateNew) // Create the writer for data .data .;BinaryWriter w=new BinaryWriter ( fs ;BinaryWriter w=new BinaryWriter ( fs );// Write data to );// Write data to Test.data.Test.data.for( int i=0;i<11;i++)for( int i=0;i<11;i++){w.Write((int)i);}w .Close();{w.Write((int)i);}w .Close();fs . Close ( ) // Create the reader for fs . Close ( ) // Create the reader for data.data.;fs=new FileStream(FILE_NAME,FileMode. ;fs=new FileStream(FILE_NAME,FileMode. OpenOpen, FileAccess.Read) ;BinaryReader , FileAccess.Read) ;BinaryReader r r= new BinaryReader(fs); // Read data from = new BinaryReader(fs); // Read data from Test.data.Test.data. for (int i = 0; i < 11; i++)for (int i = 0; i < 11; i++){ Console .WriteLine{ Console .WriteLine(r.ReadInt32 (r.ReadInt32 ()) ());}r . Close ( ); fs . Close ( ) ;}r . Close ( ); fs . Close ( ) ; }; }

Page 49: 21 high-quality programming code construction part-i

Code Formatting Code Formatting FundamentalsFundamentals

Good formatting goalsGood formatting goals To improve code readabilityTo improve code readability To improve code maintainabilityTo improve code maintainability

Fundamental principle of code Fundamental principle of code formatting:formatting:

Any formatting style that follows Any formatting style that follows the above principle is goodthe above principle is good

Any other formatting is not goodAny other formatting is not good 49

The formating of the source The formating of the source code should disclose its logical code should disclose its logical structure.structure.

Page 50: 21 high-quality programming code construction part-i

Formatting Blocks in Formatting Blocks in C#C#

Put Put {{ and and }} alone on a line under alone on a line under the corresponding parent blockthe corresponding parent block

Indent the block contents by a Indent the block contents by a single [Tab]single [Tab] Don't indent with spacesDon't indent with spaces

Example:Example:

50

if ( some condition )if ( some condition ){{ // Block contents indented by a single [Tab]// Block contents indented by a single [Tab] // Don't use spaces for indentation// Don't use spaces for indentation}}

Page 51: 21 high-quality programming code construction part-i

Methods IndentationMethods Indentation

Methods should be indented with a Methods should be indented with a single [Tab] from the class bodysingle [Tab] from the class body

Methods body should be indented Methods body should be indented with a single [Tab] as wellwith a single [Tab] as well

51

public class IndentationExamplepublic class IndentationExample{{ private int Zero()private int Zero() {{ return 0;return 0; }}}}

The entire method The entire method is indented with a is indented with a

single [Tab]single [Tab]

Method body is also Method body is also indentedindented

Page 52: 21 high-quality programming code construction part-i

Brackets in Methods Brackets in Methods DeclarationDeclaration

Brackets in the method declaration Brackets in the method declaration should be formatted as follows:should be formatted as follows:

Don't use spaces between the Don't use spaces between the brackets:brackets:

The same applies for The same applies for ifif-conditions -conditions and and forfor-loops:-loops:

52

private static ulong CalcFactorial(uint num)private static ulong CalcFactorial(uint num)

private static ulong CalcFactorial ( uint num ) private static ulong CalcFactorial ( uint num )

private static ulong CalcFactorial (uint num) private static ulong CalcFactorial (uint num)

if (condition) …if (condition) …

Page 53: 21 high-quality programming code construction part-i

Separating ParametersSeparating Parameters Separate method parameters by Separate method parameters by

comma followed by a spacecomma followed by a space Don't put comma before the spaceDon't put comma before the space Examples:Examples:

Incorrect examples:Incorrect examples:

53

private void RegisterUser(string username, string private void RegisterUser(string username, string password)password)

private void RegisterUser(string username,string private void RegisterUser(string username,string password)password)private void RegisterUser(string username ,string private void RegisterUser(string username ,string password)password)private void RegisterUser(string username , string private void RegisterUser(string username , string password)password)

RegisterUser("nakov", "s3cr3t!p@ssw0rd");RegisterUser("nakov", "s3cr3t!p@ssw0rd");

Page 54: 21 high-quality programming code construction part-i

Empty Lines between Empty Lines between MethodsMethods

Use empty line for separation Use empty line for separation between methods:between methods:

54

public class Factorialpublic class Factorial{{ private static ulong CalcFactorial(uint num)private static ulong CalcFactorial(uint num) {{ if (num == 0)if (num == 0) return 1;return 1; elseelse return num * CalcFactorial(num - 1);return num * CalcFactorial(num - 1); }} static void Main()static void Main() {{ ulong factorial = CalcFactorial(5);ulong factorial = CalcFactorial(5); Console.WriteLine(factorial);Console.WriteLine(factorial); }}}}

Empty Empty lineline

Always use Always use {{ and and }} after after ifif

(there is no space to (there is no space to do it here)do it here)

Page 55: 21 high-quality programming code construction part-i

Empty Lines in Method Empty Lines in Method BodyBody

Use an empty line to separate Use an empty line to separate logically related sequences of lines:logically related sequences of lines:

55

private List<Report> PrepareReports()private List<Report> PrepareReports(){{ List<Report> reports = new List<Report>();List<Report> reports = new List<Report>();

// Create incomes reports// Create incomes reports Report incomesSalesReport = PrepareIncomesSalesReport();Report incomesSalesReport = PrepareIncomesSalesReport(); reports.Add(incomesSalesReport);reports.Add(incomesSalesReport); Report incomesSupportReport = PrepareIncomesSupportReport();Report incomesSupportReport = PrepareIncomesSupportReport(); reports.Add(incomesSupportReport);reports.Add(incomesSupportReport);

// Create expenses reports// Create expenses reports Report expensesPayrollReport = PrepareExpensesPayrollReport();Report expensesPayrollReport = PrepareExpensesPayrollReport(); reports.Add(expensesPayrollReport);reports.Add(expensesPayrollReport); Report expensesMarketingReport = Report expensesMarketingReport = PrepareExpensesMarketingReport();PrepareExpensesMarketingReport(); reports.Add(expensesMarketingReport);reports.Add(expensesMarketingReport);

return reports;return reports;}}

Empty Empty lineline

Empty Empty lineline

Empty Empty lineline

Page 56: 21 high-quality programming code construction part-i

Misplaced Empty Lines – Misplaced Empty Lines – ExampleExample

56

public static void PrintList(List<int> ints) public static void PrintList(List<int> ints) {{ Console.Write("{ ");Console.Write("{ "); foreach (int item in ints)foreach (int item in ints) {{ Console.Write(item);Console.Write(item);

Console.Write(" ");Console.Write(" ");

}} Console.WriteLine("}");Console.WriteLine("}");}}static void Main()static void Main(){{ // ...// ...}}

Page 57: 21 high-quality programming code construction part-i

Formatting TypesFormatting Types Formatting classes / structures / Formatting classes / structures /

interfaces / enumerationsinterfaces / enumerations Indent the class body with a single Indent the class body with a single

[Tab][Tab] Use the following order of definitions:Use the following order of definitions:

Constants, delegates, inner types, Constants, delegates, inner types, fields, constructors, properties, methodsfields, constructors, properties, methods

Static members, public members, Static members, public members, protected members, internal members, protected members, internal members, private membersprivate members

The above order of definitions is not The above order of definitions is not the only possible correct onethe only possible correct one 57

Page 58: 21 high-quality programming code construction part-i

Formatting Types – Formatting Types – ExampleExample

58

public class Dogpublic class Dog{{ // Static variables// Static variables

public const string SPECIES = public const string SPECIES = "Canis Lupus Familiaris";"Canis Lupus Familiaris";

// Instance variables// Instance variables

private int age;private int age;

// Constructors// Constructors

public Dog(string name, int age)public Dog(string name, int age) {{ this.Name = name;this.Name = name; this.age = age;this.age = age; } }

(continues on the next slide)

Page 59: 21 high-quality programming code construction part-i

Formatting Types – Formatting Types – Example (2)Example (2)

59

// Properties// Properties

public string Name { get; set; }public string Name { get; set; }

// Methods// Methods

public void Breath()public void Breath() {{ // TODO: breathing process// TODO: breathing process }}

public void Bark()public void Bark() {{ Console.WriteLine("wow-wow");Console.WriteLine("wow-wow"); }}

}}

Page 60: 21 high-quality programming code construction part-i

Formatting Conditional Formatting Conditional Statements and LoopsStatements and Loops

Formatting conditional statements and Formatting conditional statements and loopsloops Always use Always use { }{ } block after block after ifif / / forfor / / whilewhile, even when a single operator , even when a single operator followsfollows

Indent the block body after Indent the block body after ifif / / forfor / / whilewhile

Never put the block after Never put the block after ifif / / forfor / / whilewhile on the same line!on the same line!

Always put the Always put the {{ on the next line on the next line

Never indent with more than one [Tab]Never indent with more than one [Tab] 60

Page 61: 21 high-quality programming code construction part-i

Conditional Statements Conditional Statements and Loops Formatting – and Loops Formatting –

ExamplesExamples Example:Example:

Incorrect examples:Incorrect examples:

61

for (int i=0; i<10; i++)for (int i=0; i<10; i++){{ Console.WriteLine("i={0}", i);Console.WriteLine("i={0}", i);}}

for (int i=0; i<10; i++)for (int i=0; i<10; i++) Console.WriteLine("i={0}", i);Console.WriteLine("i={0}", i);

for (int i=0; i<10; i++) Console.WriteLine("i={0}", for (int i=0; i<10; i++) Console.WriteLine("i={0}", i);i);

for (int i=0; i<10; i++) {for (int i=0; i<10; i++) { Console.WriteLine("i={0}", i);Console.WriteLine("i={0}", i);}}

Page 62: 21 high-quality programming code construction part-i

Breaking Long LinesBreaking Long Lines Break long lines after punctuationBreak long lines after punctuation Indent the second line by single [Tab]Indent the second line by single [Tab] Do not additionally indent the third Do not additionally indent the third

lineline Examples:Examples:

62

DictionaryEntry<K, V> newEntry = DictionaryEntry<K, V> newEntry = new DictionaryEntry<K, V>(new DictionaryEntry<K, V>( oldEntry.Key, oldEntry.Value);oldEntry.Key, oldEntry.Value);

if (matrix[x, y] == 0 || matrix[x-1, y] == 0 if (matrix[x, y] == 0 || matrix[x-1, y] == 0 |||| matrix[x+1, y] == 0 || matrix[x, y-1] == 0 matrix[x+1, y] == 0 || matrix[x, y-1] == 0 |||| matrix[x, y+1] == 0)matrix[x, y+1] == 0){ …{ …

Page 63: 21 high-quality programming code construction part-i

Incorrect Ways ToIncorrect Ways ToBreak Long LinesBreak Long Lines

63

if (matrix[x, y] == 0 || matrix[x-1, y] ==if (matrix[x, y] == 0 || matrix[x-1, y] == 0 || matrix[x+1, y] == 0 || matrix[x, 0 || matrix[x+1, y] == 0 || matrix[x, y-1] == 0 || matrix[x, y+1] == 0)y-1] == 0 || matrix[x, y+1] == 0){ …{ …

if (matrix[x, y] == 0 || matrix[x-1, y] == 0 || if (matrix[x, y] == 0 || matrix[x-1, y] == 0 || matrix[x+1, y] == 0 || matrix[x, y-1] == matrix[x+1, y] == 0 || matrix[x, y-1] == 0 || 0 || matrix[x, y+1] == 0)matrix[x, y+1] == 0){ …{ …

DictionaryEntry<K, V> newEntry DictionaryEntry<K, V> newEntry = new DictionaryEntry<K, V>(oldEntry= new DictionaryEntry<K, V>(oldEntry .Key, oldEntry.Value);.Key, oldEntry.Value);

Page 64: 21 high-quality programming code construction part-i

AlignmentsAlignments All types of alignments are All types of alignments are

considered harmfulconsidered harmful Alignments are hard-to-maintain!Alignments are hard-to-maintain!

Incorrect examples:Incorrect examples:

64

DateTime date = DateTime.Now.Date;DateTime date = DateTime.Now.Date;int count = 0;int count = 0;Student student = new Strudent();Student student = new Strudent();List<Student> students = new List<Student>();List<Student> students = new List<Student>();

matrix[x, y] == 0;matrix[x, y] == 0;matrix[x + 1, y + 1] == 0;matrix[x + 1, y + 1] == 0;matrix[2 * x + y, 2 * y + x] == 0;matrix[2 * x + y, 2 * y + x] == 0;matrix[x * y, x * y] == 0;matrix[x * y, x * y] == 0;

Page 65: 21 high-quality programming code construction part-i

High-Quality ClassesHigh-Quality ClassesHow to Design High-Quality Classes? How to Design High-Quality Classes? Abstraction, Cohesion and CouplingAbstraction, Cohesion and Coupling

Page 66: 21 high-quality programming code construction part-i

High-Quality Classes: High-Quality Classes: AbstractionAbstraction

Present a consistent level of Present a consistent level of abstractionabstraction in the class contract (publicly visible in the class contract (publicly visible members)members) What abstraction the class is What abstraction the class is

implementing?implementing?

Does it represent only one thing?Does it represent only one thing?

Does the class name well describe its Does the class name well describe its purpose?purpose?

Does the class define clear and easy to Does the class define clear and easy to understand public interface?understand public interface?

Does the class hide all its implementation Does the class hide all its implementation details?details? 66

Page 67: 21 high-quality programming code construction part-i

Good Abstraction – Good Abstraction – ExampleExample

67

public class Fontpublic class Font{{ public string Name { get; set; }public string Name { get; set; } public float SizeInPoints { get; set; }public float SizeInPoints { get; set; } public FontStyle Style { get; set; }public FontStyle Style { get; set; }

public Font(string name, float sizeInPoints, FontStyle public Font(string name, float sizeInPoints, FontStyle style)style) {{ this.Name = name;this.Name = name; this.SizeInPoints = sizeInPoints;this.SizeInPoints = sizeInPoints; this.Style = style;this.Style = style; }}

public void DrawString(DrawingSurface surface, public void DrawString(DrawingSurface surface, string str, int x, int y) { ... }string str, int x, int y) { ... }

public Size MeasureString(string str) { ... }public Size MeasureString(string str) { ... }}}

Page 68: 21 high-quality programming code construction part-i

Bad Abstraction – Bad Abstraction – ExampleExample

68

public class Programpublic class Program

{{

public string title;public string title;

public int size;public int size;

public Color color;public Color color;

public void InitializeCommandStack();public void InitializeCommandStack();

public void PushCommand(Command command);public void PushCommand(Command command);

public Command PopCommand();public Command PopCommand();

public void ShutdownCommandStack();public void ShutdownCommandStack();

public void InitializeReportFormatting();public void InitializeReportFormatting();

public void FormatReport(Report report);public void FormatReport(Report report);

public void PrintReport(Report report);public void PrintReport(Report report);

public void InitializeGlobalData();public void InitializeGlobalData();

public void ShutdownGlobalData();public void ShutdownGlobalData();

}}

Does this class Does this class really represent really represent a "program"? Is a "program"? Is this name good?this name good?

Does this Does this class really class really

have a have a single single

purpose?purpose?

Page 69: 21 high-quality programming code construction part-i

Establishing Good Establishing Good AbstractionAbstraction

Define operations along with their Define operations along with their oppositesopposites

Example:Example:

Open()Open() and and Close()Close()

Move unrelated methods in another classMove unrelated methods in another class

Example:Example:

In class In class EmployeeEmployee if you need to calculate if you need to calculate AgeAge

by given by given DateOfBirthDateOfBirth

Create static method Create static method CalcAgeCalcAge in a separate in a separate

class class DateUtilsDateUtils69

Page 70: 21 high-quality programming code construction part-i

Establishing Good Establishing Good Abstraction (2)Abstraction (2)

Beware of breaking the interface Beware of breaking the interface abstraction due to evolutionabstraction due to evolution Don't add public members Don't add public members

inconsistent with class abstractioninconsistent with class abstraction Example: in class called Employee Example: in class called Employee

at some time we add method for at some time we add method for accessing the DB with SQLaccessing the DB with SQL

70

class Employeeclass Employee{{ public string firstName;public string firstName; public string lastName;public string lastName; … … public SqlCommand FindByPrimaryKeySqlCommand(int public SqlCommand FindByPrimaryKeySqlCommand(int id);id);}}

Page 71: 21 high-quality programming code construction part-i

EncapsulationEncapsulation Minimize the visibility of classes and Minimize the visibility of classes and

membersmembers

Start from Start from privateprivate and move to and move to internalinternal, , protectedprotected and and publicpublic if required if required

Classes should hide their implementation Classes should hide their implementation detailsdetails

Anything which is not part of the class Anything which is not part of the class interface should be declared interface should be declared privateprivate

Classes with good encapsulated classes are: Classes with good encapsulated classes are: less complex, easier to maintain, more loosely less complex, easier to maintain, more loosely coupledcoupled

Never declare fields public (except constants)Never declare fields public (except constants)

Use methods or properties to access fieldsUse methods or properties to access fields 71

Page 72: 21 high-quality programming code construction part-i

Encapsulation (2)Encapsulation (2) Don't violate encapsulation Don't violate encapsulation

semantically!semantically! Don't rely on non-documented internal Don't rely on non-documented internal

behavior or side effectsbehavior or side effects

Wrong example: Wrong example:

Skip calling Skip calling ConnectToDB()ConnectToDB() because you because you just called just called FindEmployeeById()FindEmployeeById() which which should open connectionshould open connection

Another wrong example:Another wrong example:

Use Use String.EmptyString.Empty instead of instead of Titles.NoTitleTitles.NoTitle because you know both because you know both values are the samevalues are the same 72

Page 73: 21 high-quality programming code construction part-i

InheritanceInheritance Don't hide methods in a subclassDon't hide methods in a subclass

Example: if the class Example: if the class TimerTimer has private has private method method Start()Start(), don't define , don't define Start()Start() in in AtomTimerAtomTimer

Move common interfaces, data, and Move common interfaces, data, and behavior as high as possible in the behavior as high as possible in the inheritance treeinheritance tree This maximizes the code reuseThis maximizes the code reuse

Be suspicious of base classes of which Be suspicious of base classes of which there is only one derived classthere is only one derived class Do you really need this additional level Do you really need this additional level

of inheritance?of inheritance? 73

Page 74: 21 high-quality programming code construction part-i

Inheritance (2)Inheritance (2) Be suspicious of classes that override Be suspicious of classes that override

a routine and do nothing insidea routine and do nothing inside Is the overridden routine used Is the overridden routine used

correctly?correctly? Avoid deep inheritance treesAvoid deep inheritance trees

Don't create more than 6 levels of Don't create more than 6 levels of inheritanceinheritance

Avoid using a base class’s protected Avoid using a base class’s protected data fields in a derived classdata fields in a derived class Provide protected accessor methods Provide protected accessor methods

or properties insteador properties instead 74

Page 75: 21 high-quality programming code construction part-i

Inheritance (3)Inheritance (3) Prefer inheritance to extensive type Prefer inheritance to extensive type

checking:checking:

Consider inheriting Consider inheriting CircleCircle and and SquareSquare from from ShapeShape and override the abstract and override the abstract action action Draw()Draw() 75

switch (shape.Type)switch (shape.Type)

{{

case Shape.Circle:case Shape.Circle:

shape.DrawCircle();shape.DrawCircle();

break;break;

case Shape.Square:case Shape.Square:

shape.DrawSquare();shape.DrawSquare();

break;break;

......

}}

Page 76: 21 high-quality programming code construction part-i

Class Methods and DataClass Methods and Data Keep the number of methods in a class Keep the number of methods in a class

as small as possible as small as possible reduce complexity reduce complexity Minimize direct method calls to other Minimize direct method calls to other

classesclasses Minimize indirect method calls to other Minimize indirect method calls to other

classesclasses

Less external method calls == less Less external method calls == less couplingcoupling

Minimize the extent to which a class Minimize the extent to which a class collaborates with other classescollaborates with other classes Reduce coupling between classesReduce coupling between classes

76

Page 77: 21 high-quality programming code construction part-i

Class ConstructorsClass Constructors Initialize all member data in all Initialize all member data in all

constructors, if possibleconstructors, if possible Uninitialized data is error proneUninitialized data is error prone Partially initialized data is even more Partially initialized data is even more

evilevil Incorrect example: assign Incorrect example: assign FirstNameFirstName in in

class class PersonPerson but leave but leave LastNameLastName empty empty Initialize data members in the same Initialize data members in the same

order in which they are declaredorder in which they are declared Prefer deep copies to shallow copies Prefer deep copies to shallow copies

((ICloneableICloneable should make deep copy) should make deep copy)77

Page 78: 21 high-quality programming code construction part-i

Use Design PatternsUse Design Patterns Use private constructor to prohibit Use private constructor to prohibit

direct class instantiationdirect class instantiation Use deign patterns for common Use deign patterns for common

design situationsdesign situations Creational patterns like singleton, Creational patterns like singleton,

factory method, abstract factoryfactory method, abstract factory

Structural patterns like adapter, Structural patterns like adapter, bridge, composite, decorator, façadebridge, composite, decorator, façade

Behavioral patterns like command, Behavioral patterns like command, iterator, observer, strategy, template iterator, observer, strategy, template methodmethod

78

Page 79: 21 high-quality programming code construction part-i

Top Reasons to Create Top Reasons to Create ClassClass

Model real-world objects with OOP Model real-world objects with OOP classesclasses

Model abstract objects, processes, etc.Model abstract objects, processes, etc. Reduce complexityReduce complexity

Work at higher levelWork at higher level Isolate complexityIsolate complexity

Hide it in a classHide it in a class Hide implementation details Hide implementation details

encapsulationencapsulation Limit effects of changesLimit effects of changes

Changes affect only their classChanges affect only their class 79

Page 80: 21 high-quality programming code construction part-i

Top Reasons to Create Top Reasons to Create Class (2)Class (2)

Hide global dataHide global data Work through methodsWork through methods

Group variables that are used togetherGroup variables that are used together Make central points of controlMake central points of control

Single task should be done at single Single task should be done at single placeplace

Avoid duplicating codeAvoid duplicating code Facilitate code reuseFacilitate code reuse

Use class hierarchies and virtual Use class hierarchies and virtual methodsmethods

Package related operations togetherPackage related operations together80

Page 81: 21 high-quality programming code construction part-i

NamespacesNamespaces Group related classes together in Group related classes together in

namespacesnamespaces Follow consistent naming Follow consistent naming

conventionconvention

81

namespace Utilsnamespace Utils{{ class MathUtils { … }class MathUtils { … } class StringUtils { … }class StringUtils { … } class DateUtils { … }class DateUtils { … }}}

namespace DataAccessLayernamespace DataAccessLayer{{ class GenericDAO<Key, Entity> { … }class GenericDAO<Key, Entity> { … } class EmployeeDAO<int, Employee> { … }class EmployeeDAO<int, Employee> { … } class AddressDAO<int, Address> { … }class AddressDAO<int, Address> { … }}}

Page 82: 21 high-quality programming code construction part-i

Code Reformatting Code Reformatting and Identifiers and Identifiers

RefactoringRefactoringLive DemoLive Demo

Page 83: 21 high-quality programming code construction part-i

ResourcesResources

The bible of high-quality software construction:The bible of high-quality software construction:

83

Code Complete, 2Code Complete, 2ndnd edition, Steve McConnell, edition, Steve McConnell, Microsoft Press, 2004, Microsoft Press, 2004, ISBN ISBN 07356196700735619670, , http://www.cc2e.comhttp://www.cc2e.com

The "High-Quality Programming The "High-Quality Programming Code" course at Telerik Academy:Code" course at Telerik Academy: http://codecourse.telerik.com

Page 84: 21 high-quality programming code construction part-i

QuestionsQuestions??

QuestionsQuestions??

High-Quality High-Quality Programming Code Programming Code

Construction – Part IConstruction – Part I

Page 85: 21 high-quality programming code construction part-i

ExercisesExercises1.1. You are given a source code trying to solve You are given a source code trying to solve

the "Game 15" puzzle. Your task is to the "Game 15" puzzle. Your task is to improve the code quality without changing improve the code quality without changing its functionality (only bug fixes are its functionality (only bug fixes are allowed):allowed):

a)a) Reformat the code following the guidelines Reformat the code following the guidelines defined in the "Code Formatting" section.defined in the "Code Formatting" section.

b)b) Following the guidelines in the "Naming Following the guidelines in the "Naming Identifiers" section rename the identifiers in Identifiers" section rename the identifiers in the program: solution name, project name, the program: solution name, project name, class names, method names, parameter class names, method names, parameter names, variables, etc.names, variables, etc.

c)c) Split the functionality into classes with good Split the functionality into classes with good abstraction and strong cohesion.abstraction and strong cohesion.

85