SlideShare a Scribd company logo
1 of 169
Download to read offline
High-Quality Programming Code Construction,[object Object],Revealing the Secrets of Self-Documenting Code,[object Object],http://schoolacademy.telerik.com,[object Object],For C# Developers,[object Object],Svetlin Nakov,[object Object],Telerik Corporation,[object Object],www.telerik.com,[object Object]
Table of Contents,[object Object],What is High-Quality Programming Code?,[object Object],Naming Identifiers,[object Object],Naming classes, methods, variables, etc.,[object Object],Code Formatting,[object Object],Designing High-Quality Classes,[object Object],High-Quality Methods,[object Object],Cohesion and Coupling,[object Object],Using Variables Correctly,[object Object],Using Expressions Correctly,[object Object],2,[object Object]
Table of Contents (2),[object Object],Using Constants,[object Object],Using Control-Flow Constructs Correctly,[object Object],Conditional Statements,[object Object],Loops,[object Object],Defensive Programming,[object Object],Assertions and Exceptions,[object Object],Comments and Documentation,[object Object],Code Refactoring,[object Object],3,[object Object]
What is High-Quality Programming Code?,[object Object]
Why the Code Quality Is Important?,[object Object],static void Main(),[object Object],{,[object Object],  int value=010, i=5, w;,[object Object],  switch(value){case 10:w=5;Console.WriteLine(w);break;case 9:i=0;break;,[object Object],          case 8:Console.WriteLine("8 ");break;,[object Object],     default:Console.WriteLine("def ");{,[object Object],	        Console.WriteLine("hoho ");	},[object Object],     for (int k = 0; k < i; k++, Console.WriteLine(k - 'f'));break;} { Console.WriteLine("loop!"); },[object Object],},[object Object],What does this code do? Is it correct?,[object Object],5,[object Object]
Why the Code Quality Is Important? (2),[object Object],static void Main(),[object Object],{,[object Object],  int value = 010, i = 5, w;,[object Object],  switch (value),[object Object],  {,[object Object],    case 10: w = 5; Console.WriteLine(w); break;,[object Object],    case 9: i = 0; break;,[object Object],    case 8: Console.WriteLine("8 "); break;,[object Object],    default:,[object Object],      Console.WriteLine("def ");,[object Object],      Console.WriteLine("hoho ");,[object Object],      for (int k = 0; k < i; k++, Console.WriteLine(k -'f')); ,[object Object],      break;,[object Object],    },[object Object],    Console.WriteLine("loop!");,[object Object],},[object Object],Now the code is formatted, but is still unclear.,[object Object],6,[object Object]
Software Quality,[object Object],External quality,[object Object],Does the software behave correctly?,[object Object],Are the produced results correct?,[object Object],Does the software runfast?,[object Object],Is the software UI easy-to-use?,[object Object],Internal quality,[object Object],It the code easy to read and understand?,[object Object],It the code well structured?,[object Object],Is the code easy to modify?,[object Object],7,[object Object]
What is High-Quality Programming Code?,[object Object],High-quality programming code:,[object Object],Easy to read and understand,[object Object],Easy to modify and maintain,[object Object],Correct behavior in all cases,[object Object],Well tested,[object Object],Well architectured and designed,[object Object],Well documented,[object Object],Self-documenting code ,[object Object],Well formatted,[object Object],8,[object Object]
Code Conventions,[object Object],Code conventions are formal guidelines about the style of the source code:,[object Object],Code formatting conventions,[object Object],Indentation, whitespace, etc.,[object Object],Naming conventions,[object Object],PascalCase or camelCase, prefixes, suffixes, …,[object Object],Best practices,[object Object],Classes, interfaces, enumerations, structures, inheritance, exceptions, properties, events, constructors, fields, operators, etc.,[object Object],9,[object Object]
Code Conventions (2),[object Object],Microsoft has official code conventions called,[object Object],Design Guidelines for Developing Class Libraries: http://msdn.microsoft.com/en-us/library/ms229042.aspx,[object Object],Large organizations follow strict conventions,[object Object],Code conventions can vary in different teams,[object Object],Most conventions developers follow the official Microsoft's recommendations but extend them,[object Object],High-quality code goes beyond code conventions,[object Object],Software quality is not just a set of conventions – its is a way of thinking,[object Object],10,[object Object]
Naming Identifiers,[object Object],Naming Classes, Interfaces, Enumerations, Methods, Variables and Constants,[object Object]
General Naming Guidelines,[object Object],Always use English,[object Object],How you will feel if you read Vietnamese code with variables named in Vietnamese?,[object Object],English is the only language that all software developers speak,[object Object],Avoid abbreviations,[object Object],Example: scrpCnt vs. scriptsCount,[object Object],Avoid hard-to-pronounce names,[object Object],Example:  dtbgRegExPtrn vs. dateTimeBulgarianRegExPattern,[object Object],12,[object Object]
Use Meaningful Names,[object Object],Always prefer using meaningful names,[object Object],Names should answer these questions:,[object Object],What does this class do? What is the intent of this variable? What is this variable / class used for?,[object Object],Examples:,[object Object],FactorialCalculator, studentsCount, Math.PI, configFileName, CreateReport,[object Object],Incorrect examples: ,[object Object],k, k2,k3,junk,f33,KJJ,button1, variable, temp, tmp, temp_var, something, someValue,[object Object],13,[object Object]
Fake Meaningful Names,[object Object],Junior developers often use meaningful names that are in fact meaningless,[object Object],Bad naming examples:,[object Object],Topic6Exercise12, LoopsExercise12,Problem7, OOPLecture_LastExercise,[object Object],Yes, Topic6Exercise12 indicates that this is solution to exercise 12, but what is it about?,[object Object],Better naming:,[object Object],MaximalNumbersSubsequence,[object Object],14,[object Object]
Naming Types,[object Object],Naming types (classes, structures, etc.),[object Object],Use PascalCase character casing,[object Object],Examples:,[object Object],RecursiveFactorialCalculator, TreeSet, XmlDocument, IEnumerable, Color, TreeNode, InvalidTransactionException, MainForm,[object Object],Incorrect examples: ,[object Object],recursiveFactorialCalculator, recursive_factorial_calculator,  RECURSIVE_FACTORIAL_CALCULATOR,[object Object],15,[object Object]
Naming Classes and Structures,[object Object],Use the following formats:,[object Object],[Noun],[object Object],[Adjective] + [Noun],[object Object],Examples:,[object Object],Student, FileSystem, BinaryTreeNode, Constants, MathUtils, TextBox, Calendar,[object Object],Incorrect examples:,[object Object],Move, FindUsers, Fast, Optimize, Extremly, FastFindInDatabase, Check,[object Object],16,[object Object]
Naming Interfaces,[object Object],Following formats are acceptable:,[object Object],'I' + [Verb] + 'able',[object Object],'I' + [Noun], 'I' + [Adjective] + [Noun],[object Object],Examples:,[object Object],IEnumerable, IFormattable, IDataReader, IList, IHttpModule, ICommandExecutor,[object Object],Incorrect examples:,[object Object],List, FindUsers, IFast, IMemoryOptimize, Optimizer, FastFindInDatabase, CheckBox,[object Object],17,[object Object]
Naming Enumerations,[object Object],Several formats are acceptable:,[object Object],[Noun] or [Verb] or [Adjective],[object Object],Use the same style for all members,[object Object],Examples:,[object Object],enum Days {Monday, Tuesday, Wednesday, …}, enum AppState {Running, Finished, …},[object Object],Incorrect examples:,[object Object],enum Color {red, green, blue, white}, enum PAGE_FORMAT {A4, A5, A3, LEGAL, …},[object Object],18,[object Object]
Naming Special Classes,[object Object],Exceptions,[object Object],Add 'Exception' as suffix,[object Object],Use informative name,[object Object],Example: FileNotFoundException,[object Object],Incorrect example: FileNotFoundError,[object Object],Delegate Classes,[object Object],Add 'Delegate' or 'EventHandler' as suffix,[object Object],Example: DownloadFinishedDelegate,[object Object],Incorrect example: WakeUpNotification,[object Object],19,[object Object]
The Length of Class Names,[object Object],How long could be the name of a class / struct / interface / enum?,[object Object],The name should be as long as required,[object Object],Don't abbreviate the names if this could make them unclear,[object Object],Your IDE has autocomplete, right?,[object Object],Examples: FileNotFoundException, CustomerSupportNotificationService,[object Object],Incorrect examples: FNFException, CustSuppNotifSrvc,[object Object],20,[object Object]
Naming Projects / Folders,[object Object],Project naming guidelines,[object Object],Use PascalCase,[object Object],Following formats are preferable:,[object Object],ProductName,[object Object],Company [., -, _] ProductName,[object Object],Name project folders to match the project name / its component names,[object Object],Examples: Sitefinity, Telerik JustCode,[object Object],Incorrect example: ConsoleApplication17,[object Object],21,[object Object]
Naming Namespaces,[object Object],Namespaces naming guidelines,[object Object],Use PascalCase,[object Object],Following formats are acceptable:,[object Object],Company . Product . Component . …,[object Object],Product . Component . …,[object Object],Example:,[object Object],Telerik.WinControls.GridView,[object Object],Incorrect example:,[object Object],Telerik_WinControlsGridView, Classes,[object Object],22,[object Object]
Naming Assemblies,[object Object],Assembly names should follow the root namespace in its class hierarchy,[object Object],Examples:,[object Object],Telerik.WinControls.GridView.dll,[object Object],Oracle.DataAccess.dll,[object Object],Interop.CAPICOM.dll,[object Object],Incorrect examples:,[object Object],Telerik_WinControlsGridView.dll,[object Object],OracleDataAccess.dll,[object Object],23,[object Object]
Naming Methods,[object Object],Methods naming guidelines,[object Object],Method names should be meaningful,[object Object],Should answer the question:,[object Object],What does this method do?,[object Object],If you cannot find a good name for a method, think about does it have clear intent,[object Object],Examples: FindStudent, LoadReport, Sin,[object Object],Incorrect examples: Method1, DoSomething, HandleStuff, SampleMethod, DirtyHack,[object Object],24,[object Object]
Naming Methods (2),[object Object],Use PascalCase character casing,[object Object],Example: LoadSettings, not loadSettings,[object Object],Prefer the following formats:,[object Object],[Verb],[object Object],[Verb] + [Noun], [Verb] + [Adjective] + [Noun],[object Object],Examples: Show, LoadSettingsFile, FindNodeByPattern,  ToString, PrintList,[object Object],Incorrect examples: Student, Counter, White, Generator, Approximation, MathUtils,[object Object],25,[object Object]
Methods Returning a Value,[object Object],Methods returning values should describe the returned value,[object Object],Examples:,[object Object],ConvertMetersToInches, not MetersInches or Convert or ConvertUnit,[object Object],Meters2Inches is still acceptable,[object Object],CalculateSinis good,[object Object],Sin is still acceptable (like in the Math class),[object Object],Ensure that the unit of measure of obvious,[object Object],Prefer MeasureFontInPixelsto MeasureFont,[object Object],26,[object Object]
Single Purpose of All Methods,[object Object],Methods should have a single purpose!,[object Object],Otherwise they cannot be named well,[object Object],How to name a method that creates annual incomes report, downloads updates from internet and scans the system for viruses?,[object Object],CreateAnnualIncomesReportDownloadUpdatesAndScanForViruses is a nice name, right?,[object Object],Methods that have multiple purposes (weak cohesion) are hard to be named,[object Object],Need to be refactored instead of named,[object Object],27,[object Object]
Consistency in Methods Naming,[object Object],Use consistent naming in the entire project,[object Object],LoadFile, LoadImageFromFile, LoadSettings, LoadFont, LoadLibrary, but not ReadTextFile,[object Object],Use consistently the opposites at the same level of abstraction:,[object Object],LoadLibrary vs. UnloadLibrary, but not  FreeHandle,[object Object],OpenFile vs. CloseFile, but not  DeallocateResource,[object Object],GetName vs. SetName, but not  AssignName,[object Object],28,[object Object]
The Length of Method Names,[object Object],How long could be the name of a method?,[object Object],The name should be as long as required,[object Object],Don't abbreviate,[object Object],Your IDE has autocomplete,[object Object],Examples:,[object Object],LoadCustomerSupportNotificationService, CreateMonthlyAndAnnualIncomesReport,[object Object],Incorrect examples:,[object Object],LoadCustSuppSrvc, CreateMonthIncReport,[object Object],29,[object Object]
Naming Method Parameters,[object Object],Method parameters names,[object Object],Preferred form: [Noun] or [Adjective] + [Noun],[object Object],Should be in camelCase,[object Object],Should be meaningful,[object Object],Unit of measure should be obvious,[object Object],Examples: firstName, report, usersList, fontSizeInPixels, speedKmH, font,[object Object],Incorrect examples: p, p1, p2, populate, LastName, last_name, convertImage,[object Object],30,[object Object]
Naming Variables,[object Object],Variable names,[object Object],Should be in camelCase,[object Object],Preferred form: [Noun] or [Adjective] + [Noun],[object Object],Should explain the purpose of the variable,[object Object],If you can't find good name for a variable check if it has a single purpose,[object Object],Exception: variables with very small scope, e.g. the index variable in a 3-lines long for-loop,[object Object],Names should be consistent in the project,[object Object],31,[object Object]
Naming Variables – Examples,[object Object],Examples:,[object Object],firstName, report, usersList , fontSize, maxSpeed, font, startIndex, endIndex, charsCount, configSettingsXml, config, dbConnection, createUserSqlCommand,[object Object],Incorrect examples:,[object Object],foo, bar, p, p1, p2, populate, LastName, last_name, LAST_NAME, convertImage, moveMargin, MAXSpeed, _firstName, __temp, firstNameMiddleNameAndLastName,[object Object],32,[object Object]
More about Naming Variables,[object Object],The name should be addressed to the problem we solve, not to the means we use to solve it,[object Object],Prefer nouns from the business domain to computer terms,[object Object],Examples:,[object Object],accounts, customers, customerAddress, accountHolder, paymentPlan, vipPlayer,[object Object],Incorrect examples:,[object Object],accountsLinkedList, customersHashtable, paymentsPriorityQueue, playersArray,[object Object],33,[object Object]
Naming Boolean Variables,[object Object],Boolean variables should imply true or false,[object Object],Prefixes like is, has and can are useful,[object Object],Use positive boolean variable names,[object Object],Incorrect example:,[object Object],Examples:,[object Object],hasPendingPayment, customerFound, validAddress, positiveBalance, isPrime,[object Object],Incorrect examples:,[object Object],notFound, run, programStop, player, list, findCustomerById, isUnsuccessfull,[object Object],34,[object Object],if (! notFound) { … },[object Object]
Naming Special Variables,[object Object],Naming Counters,[object Object],Establish a convention, e.g. [Noun] + 'Count',[object Object],Examples: ticketsCount, customersCount,[object Object],State,[object Object],Establish a convention, e.g. [Noun] + 'State',[object Object],Examples: blogParseState, threadState,[object Object],Variables with small scope and span,[object Object],Short names can be used, e.g. index, i, u,[object Object],35,[object Object]
Temporary Variables,[object Object],Do really temporary variables exist?,[object Object],All variables in a program are temporary because they are used temporarily only during the program execution, right?,[object Object],Temporary variables can always be named better than temp or tmp:,[object Object],36,[object Object],// Swap a[i] and a[j],[object Object],int temp = a[i];,[object Object],a[i] = a[j];,[object Object],a[j] = temp;,[object Object],// Swap a[i] and a[j],[object Object],int swapValue = a[i];,[object Object],a[i] = a[j];,[object Object],a[j] = swapValue;,[object Object]
The Length of Variable Names,[object Object],How long could be the name of a variable?,[object Object],Depends on the variable scope and lifetime,[object Object],More "famous" variables should have longer and more self-explaining name,[object Object],Acceptable naming examples:,[object Object],Unacceptable naming examples:,[object Object],37,[object Object],class Student {,[object Object],  public string lastName;,[object Object],},[object Object],for (int i=0; i<users.Length; i++),[object Object],  if (i % 2 == 0),[object Object],    sum += users[i].Weight;,[object Object],class Student {,[object Object],  private int i;,[object Object],},[object Object],class PairOfLists {,[object Object],  public int Count { get; set; },[object Object],},[object Object]
Prefixes / Suffixes and Hungarian Notation,[object Object],In C# prefix / suffix notations are not popular,[object Object],Hungarian notation,[object Object],Using prefixes to denote the variable types, e.g. lpcstrText, lpdwFlags, cbMultiByte, hWnd,[object Object],The Hungarian notation works well in unmanaged languages like C++,[object Object],Do not use Hungarian notation in C# and .NET,[object Object],Don't use prefixes / suffixes to denote the variable data type,[object Object],38,[object Object]
Naming Properties,[object Object],Name properties in C# using a noun, noun phrase, or an adjective,[object Object],Use Pascal Case,[object Object],Examples:,[object Object],Incorrect examples:,[object Object],39,[object Object],public int Length { … },[object Object],public Color BackgroundColor { … },[object Object],public CacheMode CacheMode { … },[object Object],public bool Loaded { … },[object Object],public int Load { … },[object Object],public Color BackgroundColor { … },[object Object],public bool Font { … },[object Object]
Naming Constants,[object Object],Use CAPITAL_LETTERS for const fields and PascalCase for readonly fields,[object Object],Use meaningful names that describe their value,[object Object],Examples:,[object Object],Incorrect examples:,[object Object],40,[object Object],private const int READ_BUFFER_SIZE = 8192;,[object Object],public static readonly PageSize DefaultPageSize = PageSize.A4;,[object Object],private const int FONT_SIZE_IN_POINTS = 16;,[object Object],public const int MAX = 512; // Max what? Apples or Oranges?,[object Object],public const int BUF256 = 256; // What about BUF256 = 1024?,[object Object],public const string GREATER = "&gt;"; // GREATER_HTML_ENTITY,[object Object],public const int FONT_SIZE = 16; // 16pt or 16px?,[object Object],public const PageSize PAGE = PageSize.A4; // Maybe PAGE_SIZE?,[object Object]
Names to Avoid,[object Object],Don't use numbers in the identifiers names,[object Object],Example: ,[object Object],PrintReport and PrintReport2,[object Object],What is the difference?,[object Object],Exceptions:,[object Object],When the number is part of the name itself, e.g. RS232Port, COM3, Win32APIFunctions,[object Object],Don't use Cyrillic or letters from other alphabets,[object Object],E.g. FindСтудентByName, CalcΩ2Protein,[object Object],41,[object Object]
Never Give a Misleading Name!,[object Object],Giving a misleading name is worse than giving a totally unclear name,[object Object],Example:,[object Object],Consider a method that calculates the sum of all elements in an array,[object Object],It should be named Sum or CalculateSum,[object Object],What about naming it CalculateAverageor Max or CheckForNegativeNumber?,[object Object],It's crazy, but be careful with "copy-paste",[object Object],42,[object Object]
Don't Believe Microsoft!,[object Object],Microsoft sometimes use really bad naming in their API libraries (especially in Win32 API),[object Object],Examples:,[object Object],Navigateand Navigate2methods in Internet Explorer ActiveX control (MSHTML.DLL),[object Object],WNetAddConnection3method in Multiple Provider Router Networking API (MPR.DLL),[object Object],LPWKSTA_USER_INFO_1structure in Win32,[object Object],Don't follow them blindly, just think a bit!,[object Object],43,[object Object]
What's Wrong with This Code?,[object Object],44,[object Object],FileStream fs = new FileStream(FILE_NAME, FileMode.CreateNew);,[object Object],// Create the writer for data.,[object Object],BinaryWriter w = new BinaryWriter(fs);,[object Object],// Write data to Test.data.,[object Object],for (int i = 0; i < 11; i++) ,[object Object],{,[object Object],  w.Write( (int) i);,[object Object],},[object Object],w.Close();,[object Object],fs.Close();,[object Object],// Create the reader for data.,[object Object],fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);,[object Object],BinaryReader r = new BinaryReader(fs);,[object Object],// Read data from Test.data.,[object Object],for (int i = 0; i < 11; i++) ,[object Object],{,[object Object],  Console.WriteLine(r.ReadInt32());,[object Object],},[object Object],r.Close();,[object Object],fs.Close();,[object Object],Source: http://msdn.microsoft.com/en-us/library/36b93480.aspx,[object Object]
Naming Should BeClear inside Its Context,[object Object],Naming should be clear inside its context,[object Object],Method names should be clear in their class,[object Object],Methods should not repeat their class name,[object Object],Parameter names should be clear in the context of their method name,[object Object],Example of good class / property naming:,[object Object],45,[object Object],class Font,[object Object],{,[object Object], public string Name { get; } // not FontName,[object Object],},[object Object]
Naming Should BeClear inside Its Context (2),[object Object],Example of good method & parameter naming:,[object Object],Name like CalcDistanceBetweenPoints is excessive – parameters say "between points",[object Object],Parameter names still can be improved:,[object Object],Name like Calc can still be correct:,[object Object],46,[object Object],double CalcDistance(Point p1, Point p2) { … },[object Object],double CalcDistance(Point firstPoint,,[object Object],  Point secondPoint) { … },[object Object],class DistanceCalculator,[object Object],{ static double Calc(Point p1, Point p1) { … } },[object Object]
Naming Should BeClear inside Its Context (3),[object Object],Incorrect example of method naming:,[object Object],It is unclear in this context what kind of calculation is performed by the method,[object Object],Incorrect example of parameter naming:,[object Object],47,[object Object],class Program,[object Object],{,[object Object], int Calculation(int value),[object Object],},[object Object],What "f" means? An URL or FTP server or file path?,[object Object],class FileDownloader,[object Object],{,[object Object],  byte[] Download(string f);,[object Object],},[object Object]
Code Formatting,[object Object]
Why Code Needs Formatting?,[object Object],49,[object Object],public   const    string                    FILE_NAME,[object Object],="example.bin"  ;  static void Main   (             ){,[object Object],FileStream   fs=     new FileStream(FILE_NAME,FileMode,[object Object],.   CreateNew)   // Create the writer      for data  .,[object Object],;BinaryWriter w=new BinaryWriter     (    fs      );// Write data to                               Test.data.,[object Object],for(  int i=0;i<11;i++){w.Write((int)i);}w   .Close();,[object Object],fs   .   Close  (  ) // Create the reader    for data.,[object Object],;fs=new FileStream(FILE_NAME,FileMode.            Open,[object Object],,  FileAccess.Read)     ;BinaryReader                r,[object Object],= new BinaryReader(fs);  // Read data from  Test.data.,[object Object], for (int i = 0; i < 11; i++){ Console      .WriteLine,[object Object],(r.ReadInt32                                       ()),[object Object],;}r       .    Close   (   );  fs .  Close  (  )  ;  },[object Object]
Code Formatting Fundamentals,[object Object],Good formatting goals,[object Object],To improve code readability,[object Object],To improve code maintainability,[object Object],Fundamental principle of code formatting:,[object Object],Any formatting style that follows the above principle is good,[object Object],Any other formatting is not good,[object Object],50,[object Object],The formating of the source code should disclose its logical structure.,[object Object]
Formatting Blocks in C#,[object Object],Put { and } alone on a line under the corresponding parent block,[object Object],Indent the block contents by a single [Tab],[object Object],Don't indent with spaces,[object Object],Example:,[object Object],51,[object Object],if ( some condition ),[object Object],{,[object Object],  // Block contents indented by a single [Tab],[object Object],  // Don't use spaces for indentation,[object Object],},[object Object]
Methods Indentation,[object Object],Methods should be indented with a single [Tab] from the class body,[object Object],Methods body should be indented with a single [Tab] as well,[object Object],52,[object Object],public class IndentationExample,[object Object],{,[object Object],  private int Zero(),[object Object],  {,[object Object],    return 0;,[object Object],  },[object Object],},[object Object],The entire method is indented with a single [Tab],[object Object],Method body is also indented,[object Object]
Brackets in Methods Declaration,[object Object],Brackets in the method declaration should be formatted as follows:,[object Object],Don't  use spaces between the brackets:,[object Object],The same applies for if-conditions and for-loops:,[object Object],53,[object Object],private static ulong CalcFactorial(uint num),[object Object],private static ulong CalcFactorial ( uint num ) ,[object Object],private static ulong CalcFactorial (uint num) ,[object Object],if (condition) …,[object Object]
Separating Parameters,[object Object],Separate method parameters by comma followed by a space,[object Object],Don't put comma before the space,[object Object],Examples:,[object Object],Incorrect examples:,[object Object],54,[object Object],private void RegisterUser(string username, string password),[object Object],RegisterUser("nakov", "s3cr3t!p@ssw0rd");,[object Object],private void RegisterUser(string username,string password),[object Object],private void RegisterUser(string username ,string password),[object Object],private void RegisterUser(string username , string password),[object Object]
Empty Lines between Methods,[object Object],Use empty line for separation between methods:,[object Object],55,[object Object],public class Factorial,[object Object],{,[object Object],  private static ulong CalcFactorial(uint num),[object Object],  {,[object Object],    if (num == 0),[object Object],      return 1;,[object Object],    else,[object Object],      return num * CalcFactorial(num - 1);,[object Object],  },[object Object],  static void Main(),[object Object],  {,[object Object],    ulong factorial = CalcFactorial(5);,[object Object],    Console.WriteLine(factorial);,[object Object],  },[object Object],},[object Object],Always use { and } after if,[object Object],(there is no space to do it here),[object Object],Empty line,[object Object]
Empty Lines in Method Body,[object Object],Use an empty line to separate logically related sequences of lines:,[object Object],56,[object Object],private List<Report> PrepareReports(),[object Object],{,[object Object],    List<Report> reports = new List<Report>();,[object Object],    // Create incomes reports,[object Object],    Report incomesSalesReport = PrepareIncomesSalesReport();,[object Object],    reports.Add(incomesSalesReport);,[object Object],    Report incomesSupportReport = PrepareIncomesSupportReport();,[object Object],    reports.Add(incomesSupportReport);,[object Object],    // Create expenses reports,[object Object],    Report expensesPayrollReport = PrepareExpensesPayrollReport();,[object Object],    reports.Add(expensesPayrollReport);,[object Object],    Report expensesMarketingReport = PrepareExpensesMarketingReport();,[object Object],    reports.Add(expensesMarketingReport);,[object Object],    return reports;,[object Object],},[object Object],Empty line,[object Object],Empty line,[object Object],Empty line,[object Object]
Misplaced Empty Lines – Example,[object Object],57,[object Object],public static void PrintList(List<int> ints) ,[object Object],{,[object Object],  Console.Write("{ ");,[object Object],  foreach (int item in ints),[object Object],  {,[object Object],    Console.Write(item);,[object Object],    Console.Write(" ");,[object Object],  },[object Object],  Console.WriteLine("}");,[object Object],},[object Object],static void Main(),[object Object],{,[object Object],  // ...,[object Object],},[object Object]
Formatting Types,[object Object],Formatting classes / structures / interfaces / enumerations,[object Object],Indent the class body with a single [Tab],[object Object],Use the following order of definitions:,[object Object],Constants, delegates, inner types, fields, constructors, properties, methods,[object Object],Static members, public members, protected members,  internal members, private members,[object Object],The above order of definitions is not the only possible correct one,[object Object],58,[object Object]
Formatting Types – Example,[object Object],59,[object Object],public class Dog,[object Object],{,[object Object],  // Static variables,[object Object],  public const string SPECIES = ,[object Object],    "Canis Lupus Familiaris";,[object Object],  // Instance variables,[object Object],  private int age;,[object Object],  // Constructors,[object Object],  public Dog(string name, int age),[object Object],  {,[object Object],    this.Name = name;,[object Object],    this.age = age;,[object Object],  } ,[object Object],(continues on the next slide),[object Object]
Formatting Types – Example (2),[object Object],60,[object Object],  // Properties,[object Object],  public string Name { get; set; },[object Object],  // Methods,[object Object],  public void Breath(),[object Object],  {,[object Object],    // TODO: breathing process,[object Object],  },[object Object],  public void Bark(),[object Object],  {,[object Object],    Console.WriteLine("wow-wow");,[object Object],  },[object Object],},[object Object]
Formatting Conditional Statements and Loops,[object Object],Formatting conditional statements and loops,[object Object],Always use { } block after if / for / while, even when a single operator follows,[object Object],Indent the block body after if / for / while,[object Object],Never put the block after if / for / while on the same line!,[object Object],Always put the { on the next line,[object Object],Never indent with more than one [Tab],[object Object],61,[object Object]
Conditional Statements and Loops Formatting – Examples,[object Object],Example:,[object Object],Incorrect examples:,[object Object],62,[object Object],for (int i=0; i<10; i++),[object Object],{,[object Object],  Console.WriteLine("i={0}", i);,[object Object],},[object Object],for (int i=0; i<10; i++),[object Object],  Console.WriteLine("i={0}", i);,[object Object],for (int i=0; i<10; i++) Console.WriteLine("i={0}", i);,[object Object],for (int i=0; i<10; i++) {,[object Object],  Console.WriteLine("i={0}", i);,[object Object],},[object Object]
Breaking Long Lines,[object Object],Break long lines after punctuation,[object Object],Indent the second line by single [Tab],[object Object],Do not additionally indent the third line,[object Object],Examples:,[object Object],63,[object Object],if (matrix[x, y] == 0 || matrix[x-1, y] == 0 ||,[object Object],  matrix[x+1, y] == 0 || matrix[x, y-1] == 0 ||,[object Object],  matrix[x, y+1] == 0),[object Object],{ …,[object Object],DictionaryEntry<K, V> newEntry = ,[object Object],  new DictionaryEntry<K, V>(,[object Object],  oldEntry.Key, oldEntry.Value);,[object Object]
Incorrect Ways ToBreak Long Lines,[object Object],64,[object Object],if (matrix[x, y] == 0 || matrix[x-1, y] ==,[object Object],  0 || matrix[x+1, y] == 0 || matrix[x, ,[object Object],  y-1] == 0 || matrix[x, y+1] == 0),[object Object],{ …,[object Object],if (matrix[x, y] == 0 || matrix[x-1, y] == 0 || ,[object Object],      matrix[x+1, y] == 0 || matrix[x, y-1] == 0 || ,[object Object],      matrix[x, y+1] == 0),[object Object],{ …,[object Object],DictionaryEntry<K, V> newEntry ,[object Object],  = new DictionaryEntry<K, V>(oldEntry,[object Object],  .Key, oldEntry.Value);,[object Object]
Alignments,[object Object],All types of alignments are considered harmful,[object Object],Alignments are hard-to-maintain!,[object Object],Incorrect examples:,[object Object],65,[object Object],DateTime      date     = DateTime.Now.Date;,[object Object],int           count    = 0;,[object Object],Student       student  = new Strudent();,[object Object],List<Student> students = new List<Student>();,[object Object],matrix[x, y]                 == 0;,[object Object],matrix[x + 1, y + 1]         == 0;,[object Object],matrix[2 * x + y, 2 * y + x] == 0;,[object Object],matrix[x * y, x * y]         == 0;,[object Object]
High-Quality Classes,[object Object],How to Design High-Quality Classes? Abstraction, Cohesion and Coupling,[object Object]
High-Quality Classes: Abstraction,[object Object],Present a consistent level of abstraction in the class contract (publicly visible members),[object Object],What abstraction the class is implementing?,[object Object],Does it represent only one thing?,[object Object],Does the class name well describe its purpose?,[object Object],Does the class define clear and easy to understand public interface?,[object Object],Does the class hide all its implementation details?,[object Object],67,[object Object]
Good Abstraction – Example,[object Object],68,[object Object],public class Font,[object Object],{,[object Object],  public string Name { get; set; },[object Object],  public float SizeInPoints { get; set; },[object Object],  public FontStyle Style { get; set; },[object Object],  public Font(string name, float sizeInPoints, ,[object Object],FontStyle style),[object Object],  {,[object Object],    this.Name = name;,[object Object],    this.SizeInPoints = sizeInPoints;,[object Object],    this.Style = style;,[object Object],  },[object Object],  public void DrawString(DrawingSurface surface, ,[object Object],    string str, int x, int y),[object Object],{ ... },[object Object],  public Size MeasureString(string str),[object Object], { ... },[object Object],},[object Object]
Bad Abstraction – Example,[object Object],69,[object Object],public class Program,[object Object],{,[object Object],  public string title;,[object Object],  public int size;,[object Object],  public Color color;,[object Object],  public void InitializeCommandStack();,[object Object],  public void PushCommand(Command command);,[object Object],  public Command PopCommand();,[object Object],  public void ShutdownCommandStack();,[object Object],  public void InitializeReportFormatting();,[object Object],  public void FormatReport(Report report);,[object Object],  public void PrintReport(Report report);,[object Object],  public void InitializeGlobalData();,[object Object],  public void ShutdownGlobalData();,[object Object],},[object Object],Does this class really represent a "program"? Is this name good?,[object Object],Does this class really have a single purpose?,[object Object]
Establishing Good Abstraction,[object Object],Define operations along with their opposites,[object Object],Example:,[object Object],Open() and Close(),[object Object],Move unrelated methods in another class,[object Object],Example:,[object Object],In class Employee if you need to calculate Age by given DateOfBirth,[object Object],[object Object],70,[object Object]
Establishing Good Abstraction (2),[object Object],Beware of breaking the interface abstraction due to evolution,[object Object],Don't add public members inconsistent with class abstraction,[object Object],Example: in class called Employee at some time we add method for accessing the DB with SQL,[object Object],71,[object Object],class Employee,[object Object],{,[object Object],  public string firstName;,[object Object],  public string lastName;,[object Object],  …,[object Object],  public SqlCommand FindByPrimaryKeySqlCommand(int id);,[object Object],},[object Object]
Encapsulation,[object Object],Minimize the visibility of classes and members,[object Object],Start from private and move to internal, protected and public if required,[object Object],Classes should hide their implementation details,[object Object],Anything which is not part of the class interface should be declared private,[object Object],Classes with good encapsulated classes are: less complex, easier to maintain, more loosely coupled,[object Object],Never declare fields public (except constants),[object Object],Use methods or properties to access fields,[object Object],72,[object Object]
Encapsulation (2),[object Object],Don't violate encapsulation semantically!,[object Object],Don't rely on non-documented internal behavior or side effects,[object Object],Wrong example: ,[object Object],Skip calling ConnectToDB() because you just called FindEmployeeById() which should open connection,[object Object],Another wrong example:,[object Object],Use String.Empty instead of Titles.NoTitle because you know both values are the same,[object Object],73,[object Object]
Inheritance,[object Object],Don't hide methods in a subclass,[object Object],Example: if the class Timer has private method Start(), don't define Start() in AtomTimer,[object Object],Move common interfaces, data, and behavior as high as possible in the inheritance tree,[object Object],This maximizes the code reuse,[object Object],Be suspicious of base classes of which there is only one derived class,[object Object],Do you really need this additional level of inheritance?,[object Object],74,[object Object]
Inheritance (2),[object Object],Be suspicious of classes that override a routine and do nothing inside,[object Object],Is the overridden routine used correctly?,[object Object],Avoid deep inheritance trees,[object Object],Don't create more than 6 levels of inheritance,[object Object],Avoid using a base class’s protected data fields in a derived class,[object Object],Provide protected accessor methods or properties instead,[object Object],75,[object Object]
Inheritance (3),[object Object],Prefer inheritance to extensive type checking:,[object Object],Consider inheriting Circle and Square from Shape and override the abstract action Draw(),[object Object],76,[object Object],switch (shape.Type),[object Object],{,[object Object],  case Shape.Circle:,[object Object],    shape.DrawCircle();,[object Object],    break;,[object Object],  case Shape.Square:,[object Object],    shape.DrawSquare();,[object Object],    break;,[object Object],  ...,[object Object],},[object Object]
Class Methods and Data,[object Object],Keep the number of methods in a class as small as possible  reduce complexity,[object Object],Minimize direct method calls to other classes,[object Object],Minimize indirect method calls to other classes,[object Object],Less external method calls == less coupling,[object Object],Minimize the extent to which a class collaborates with other classes,[object Object],Reduce coupling between classes,[object Object],77,[object Object]
Class Constructors,[object Object],Initialize all member data in all constructors, if possible,[object Object],Uninitialized data is error prone,[object Object],Partially initialized data is even more evil,[object Object],Incorrect example: assign FirstName in class Person but leave LastName empty,[object Object],Initialize data members in the same order in which they are declared,[object Object],Prefer deep copies to shallow copies (ICloneable should make deep copy),[object Object],78,[object Object]
Use Design Patterns,[object Object],Use private constructor to prohibit direct class instantiation,[object Object],Use deign patterns for common design situations,[object Object],Creational patterns like singleton, factory method, abstract factory,[object Object],Structural patterns like adapter, bridge, composite, decorator, façade,[object Object],Behavioral patterns like command, iterator, observer, strategy, template method,[object Object],79,[object Object]
Top Reasons to Create Class,[object Object],Model real-world objects with OOP classes,[object Object],Model abstract objects, processes, etc.,[object Object],Reduce complexity,[object Object],Work at higher level,[object Object],Isolate complexity,[object Object],Hide it in a class,[object Object],Hide implementation details  encapsulation,[object Object],Limit effects of changes,[object Object],Changes affect only their class,[object Object],80,[object Object]
Top Reasons to Create Class (2),[object Object],Hide global data,[object Object],Work through methods,[object Object],Group variables that are used together,[object Object],Make central points of control,[object Object],Single task should be done at single place,[object Object],Avoid duplicating code,[object Object],Facilitate code reuse,[object Object],Use class hierarchies and virtual methods,[object Object],Package related operations together,[object Object],81,[object Object]
Namespaces,[object Object],Group related classes together in namespaces,[object Object],Follow consistent naming convention,[object Object],82,[object Object],namespace Utils,[object Object],{,[object Object], class MathUtils { … },[object Object], class StringUtils { … },[object Object],},[object Object],namespace DataAccessLayer,[object Object],{,[object Object], class GenericDAO<Key, Entity> { … },[object Object], class EmployeeDAO<int, Employee> { … },[object Object], class AddressDAO<int, Address> { … },[object Object],},[object Object]
High-Quality Methods,[object Object],How to Design and Implement High-Quality Methods? Understanding Cohesion and Coupling,[object Object]
Why We Need Methods?,[object Object],Methods are important in			 software development,[object Object],Reduce complexity,[object Object],Divide and conquer: complex problems can be split into composition of several simple ones,[object Object],Improve code readability,[object Object],Small methods with good method names make the code self-documenting,[object Object],Avoid duplicating code,[object Object],Duplicating code is hard to maintain,[object Object],84,[object Object]
Why We Need Methods? (2),[object Object],Methods simplify software development,[object Object],Hide implementation details,[object Object],Complex logic is encapsulated and hidden behind a simple interface,[object Object],Algorithms and data structures are hidden and can be transparently replaced later,[object Object],Increase the level of abstraction,[object Object],Methods address the business problem, not the technical implementation:,[object Object],85,[object Object],Bank.accounts[customer].deposit(500);,[object Object]
Using Methods: Fundamentals,[object Object],Fundamental principle of correct method usage:,[object Object],Methods should do exactly what their names say,[object Object],Nothing less,[object Object],Nothing more,[object Object],In case of incorrect input or incorrect preconditions, an error should be indicated,[object Object],86,[object Object],A method should do what its name says or should indicate an error. Any other behaviour is incorrect! ,[object Object]
Good Methods – Examples,[object Object],87,[object Object],long Sum(int[] elements),[object Object],{,[object Object],  long sum = 0;,[object Object],  foreach (int element in elements),[object Object],  {,[object Object],      sum = sum + element;,[object Object],  },[object Object],  return sum;,[object Object],},[object Object],double CalcTriangleArea(double a, double b, double c),[object Object],{,[object Object],  if (a <= 0 || b <= 0 || c <= 0),[object Object],  {,[object Object],    throw new ArgumentException(,[object Object],    "Sides should be positive.");,[object Object],  },[object Object],  double s = (a + b + c) / 2;,[object Object],  double area = Math.Sqrt(s * (s - a) * (s - b) * (s - c));,[object Object],  return area;,[object Object],},[object Object]
Symptoms of Wrong Methods,[object Object],Method that does something different than its name says, is wrong for one of these reasons:,[object Object],The returned result is incorrect  bug,[object Object],The returned output is incorrect when its input is incorrect or unusual  low quality,[object Object],Acceptable for private methods only,[object Object],The method does too many things                    bad cohesion,[object Object],The method has side effects  spaghetti code,[object Object],Method returns strange value when an error condition happens  it should indicate the error,[object Object],88,[object Object]
Wrong Methods – Examples,[object Object],89,[object Object],long Sum(int[] elements),[object Object],{,[object Object],  long sum = 0;,[object Object],  for (int i = 0; i < elements.Length; i++),[object Object],  {,[object Object],    sum = sum + elements[i];,[object Object],    elements[i] = 0;,[object Object],  },[object Object],  return sum;,[object Object],},[object Object],Hidden side effect,[object Object],double CalcTriangleArea(double a, double b, double c),[object Object],{,[object Object],  if (a <= 0 || b <= 0 || c <= 0),[object Object],  {,[object Object],    return 0;,[object Object],  },[object Object],  double s = (a + b + c) / 2;,[object Object],  double area = Math.Sqrt(s * (s - a) * (s - b) * (s - c));,[object Object],  return area;,[object Object],},[object Object],Incorrect result. Throw an exception instead.,[object Object]
Strong Cohesion,[object Object],Methods should have strong cohesion,[object Object],Should address single task and address it well,[object Object],Should have clear intent,[object Object],Methods that  address several tasks in the same time are hard to be named,[object Object],String cohesion is used in engineering,[object Object],In computer hardware any PC component solves a single task,[object Object],E.g. hard disk performs a single task – storage,[object Object],90,[object Object]
Acceptable Types of Cohesion,[object Object],Functional cohesion(independent function),[object Object],Method performs certain well-defined calculation and returns a single result,[object Object],The entire input is passed through parameters and the entire output is returned as result,[object Object],No external dependencies or side effects,[object Object],Examples:,[object Object],91,[object Object],Math.Sqrt(value)  square root,[object Object],Char.IsLetterOrDigit(ch),[object Object],String.Substring(str, startIndex, length),[object Object]
Acceptable Types of Cohesion (2),[object Object],Sequential cohesion(algorithm),[object Object],Method performs certain sequence of operations to perform a single task and achieve certain result,[object Object],It encapsulates an algorithm,[object Object],Example:,[object Object],Connect to mail server,[object Object],Send message headers,[object Object],Send message body,[object Object],Disconnect from the server,[object Object],92,[object Object],SendEmail(recipient, subject, body),[object Object]
Acceptable Types of Cohesion (3),[object Object],Communicational cohesion(common data),[object Object],A set of operations used to process certain data and produce a result,[object Object],Example:,[object Object],Retrieve input data from database,[object Object],Perform internal calculations over retrieved data,[object Object],Build the report,[object Object],Format the report as Excel worksheet,[object Object],Display the Excel worksheet on the screen,[object Object],93,[object Object],DisplayAnnualExpensesReport(int employeeId),[object Object]
Acceptable Types of Cohesion (4),[object Object],Temporal cohesion (time related activities),[object Object],Operations that are generally not related but need to happen in a certain moment,[object Object],Examples:,[object Object],Load user settings,[object Object],Check for updates,[object Object],Load all invoices from the database,[object Object],Sequence of actions to handle the event,[object Object],94,[object Object],InitializeApplication(),[object Object],ButtonConfirmClick(),[object Object]
Unacceptable Cohesion,[object Object],Logical cohesion,[object Object],Performs a different operation depending on an input parameter,[object Object],Incorrect example:,[object Object],Can be acceptable in event handlers (e.g. the KeyDown event in Windows Forms),[object Object],95,[object Object],object ReadAll(int operationCode),[object Object],{,[object Object],  if (operationCode == 1) … // Read person name,[object Object],  else if (operationCode == 2) … // Read address,[object Object],  else if (operationCode == 3) … // Read date,[object Object],  …,[object Object],},[object Object]
Unacceptable Cohesion,[object Object],Coincidental cohesion (spaghetti),[object Object],Not related (random) operations are grouped in a method for unclear reason,[object Object],Incorrect example:,[object Object],Prepares annual incomes report for given customer,[object Object],Sorts an array of integers in increasing order,[object Object],Calculates the square root of given number,[object Object],Converts given MP3 file into WMA format,[object Object],Sends email to given customer,[object Object],96,[object Object],HandleStuff(customerId, int[], ref sqrtValue,,[object Object],  mp3FileName, emailAddress),[object Object]
Loose Coupling,[object Object],What is loose coupling?,[object Object],Minimal dependences of the method on the other parts of the source code,[object Object],Minimal dependences on the class members or external classes and their members,[object Object],No side effects,[object Object],If the coupling is loose, we can easily reuse a method or group of methods in a new project,[object Object],Tight coupling  spaghetti code,[object Object],97,[object Object]
Loose Coupling (2),[object Object],The ideal coupling,[object Object],A methods depends only on its parameters,[object Object],Does not have any other input or output,[object Object],Example: Math.Sqrt,[object Object],Real world,[object Object],Complex software cannot avoid coupling but could make it as loose as possible,[object Object],Example: complex encryption algorithm performs initialization, encryption, finalization,[object Object],98,[object Object]
Coupling – Example,[object Object],Intentionally increased coupling for more flexibility (.NET cryptography API):,[object Object],99,[object Object],byte[] EncryptAES(byte[] inputData, byte[] secretKey),[object Object],{,[object Object],  Rijndael cryptoAlg = new RijndaelManaged();,[object Object],  cryptoAlg.Key = secretKey;,[object Object],  cryptoAlg.GenerateIV();,[object Object],  MemoryStream destStream = new MemoryStream();,[object Object],  CryptoStream csEncryptor = new CryptoStream(,[object Object],    destStream, cryptoAlg.CreateEncryptor(),,[object Object],    CryptoStreamMode.Write);,[object Object],  csEncryptor.Write(inputData, 0, inputData.Length);,[object Object],  csEncryptor.FlushFinalBlock();,[object Object],  byte[] encryptedData = destStream.ToArray();,[object Object],  return encryptedData;,[object Object],},[object Object]
Loose Coupling – Example,[object Object],To reduce coupling we can make utility classes that hide the complex logic and provide simple straightforward interface (a.k.a. façade):,[object Object],100,[object Object],byte[] EncryptAES(byte[] inputData, byte[] secretKey),[object Object],{,[object Object],  MemoryStream inputStream =,[object Object],    new MemoryStream(inputData);,[object Object],  MemoryStream outputStream = new MemoryStream();,[object Object],  EncryptionUtils.EncryptAES(,[object Object],    inputStream, outputStream, secretKey);,[object Object],  byte[] encryptedData = outputStream.ToArray();,[object Object],  return encryptedData;,[object Object],},[object Object]
Tight Coupling – Example,[object Object],Passing parameters through class fields,[object Object],Typical example of tight coupling,[object Object],Don't do this unless you have a good reason!,[object Object],101,[object Object],class Sumator,[object Object],{,[object Object],  public int a, b;,[object Object],  int Sum(),[object Object],  {,[object Object],    return a + b;,[object Object],  },[object Object],  static void Main(),[object Object],  {,[object Object],    Sumator sumator = new Sumator() { a = 3, b = 5 };,[object Object],    Console.WriteLine(sumator.Sum());,[object Object],  },[object Object],},[object Object],Why don't pass the numbers as parameters?,[object Object]
Loose Coupling and OOP,[object Object],Reducing coupling with OOP techniques,[object Object],Abstraction,[object Object],Define a public interface and hide the implementation details,[object Object],Encapsulation,[object Object],Make methods and fields private unless they are definitely needed,[object Object],Define new members as private,[object Object],Increase visibility as soon as this is needed,[object Object],102,[object Object]
Acceptable Coupling,[object Object],Method is coupled to its parameters,[object Object],This is the best type of coupling,[object Object],Method in a class is coupled to some class fields,[object Object],This coupling is usual, do not worry too much,[object Object],Method in a class is coupled to static methods, properties or constants in external class,[object Object],This is normal, usually is not a problem,[object Object],Method is coupled to external static fields,[object Object],Avoid this, classes should keep their fields private,[object Object],103,[object Object]
Non-Acceptable Coupling,[object Object],Method in a class is coupled to static fields in external class,[object Object],Avoid it  consider refactoring,[object Object],Methods take as input data some fields that could be passed as parameters,[object Object],Check the intent of the method,[object Object],Is it designed to process internal class data or is utility method,[object Object],Method is defined public without being part of the public class's interface  possible coupling,[object Object],104,[object Object]
Methods Parameters,[object Object],Put most important parameters first,[object Object],First put the main input parameters,[object Object],Put non-important optional parameters last,[object Object],Example:,[object Object],Incorrect examples:,[object Object],105,[object Object],void RegisterUser(string username, string password,,[object Object],  Date accountExpirationDate, Role[] roles),[object Object],void RegisterUser(Role[] roles, string password,,[object Object],  string username, Date accountExpirationDate),[object Object],void RegisterUser(string password, Date,[object Object],  accountExpirationDate, Role[] roles, string username),[object Object]
Methods Parameters (2),[object Object],Do not modify the input parameters,[object Object],Use new variable instead,[object Object],Incorrect example:,[object Object],Correct example:,[object Object],106,[object Object],bool CheckLogin(string username, string password),[object Object],{,[object Object],  username = username.ToLower();,[object Object],  … // Check the username / password here,[object Object],},[object Object],bool CheckLogin(string username, string password),[object Object],{,[object Object],  string usernameLowercase = username.ToLower();,[object Object],  … // Check the username / password here,[object Object],},[object Object]
Methods Parameters (3),[object Object],Use parameters consistently,[object Object],Use the same names and the same order in all methods,[object Object],Incorrect example:,[object Object],Output parameters should be put last,[object Object],107,[object Object],void EncryptFile(Stream input, Stream output, string key);,[object Object],void DecryptFile(string key, Stream output, Stream input);,[object Object],FindCustomersAndIncomes(Region region,,[object Object],  out Customer[] customers, out decimal[] incomes),[object Object]
Pass Entire Object or Its Fields?,[object Object],When should we pass an object containing few values and when these values separately?,[object Object],Sometime we pass an object and use only a single field of it – it is a good practice?,[object Object],Examples:,[object Object],Look at the method's level of abstraction,[object Object],Is it intended to operate with employees of with rates and months?  the first is incorrect,[object Object],108,[object Object],CalculateSalary(Employee employee, int months);,[object Object],CalculateSalary(double rate, int months);,[object Object]
How Much Parameters Methods Should Have?,[object Object],Limit the number of method parameters to 7 (+/-2),[object Object],7 is a magic number in psychology,[object Object],Human brain cannot process more than 7 (+/-2) things in the same time,[object Object],If the parameters need to be too much reconsider the method intent  does it have clear intent?,[object Object],Consider putting few parameters in a new class,[object Object],109,[object Object]
Methods Length,[object Object],How long should a method be?,[object Object],There is no specific restriction,[object Object],Avoid methods longer than one screen (30 lines),[object Object],Long methods are not always bad,[object Object],Be sure you have a good reason for their length,[object Object],Cohesion and coupling are more important than the method length!,[object Object],Long methods often contain portions that could be extracted as separate methods with good name and clear intent  check this!,[object Object],110,[object Object]
Using Variables,[object Object],Best Practices,[object Object]
Retuning Result from a Method,[object Object],Always assign the result of a method in some variable before returning it. Benefits:,[object Object],Improved code readability,[object Object],The returned value has self-documenting name,[object Object],Simplified debugging,[object Object],Example:,[object Object],Incorrect example:,[object Object],112,[object Object],The intent of the formula is obvious,[object Object],int salary = days * hoursPerDay * ratePerHour;,[object Object],return salary;,[object Object],We can put a breakpoint at this line and check if the result is correct,[object Object],return days * hoursPerDay * ratePerHour;,[object Object]
Variable Initialization,[object Object],Initialize all variables before their first usage,[object Object],Class variables (fields) are automatically initialized with 0 / null by the C# compiler,[object Object],You still get a warning message,[object Object],Local variables should be manually initialized,[object Object],This C# code will result in compilation error:,[object Object],We can initialize variables at their declaration:,[object Object],113,[object Object],int value;,[object Object],Console.WriteLine(value);,[object Object],int value = 0;,[object Object],Console.WriteLine(value);,[object Object]
Partially Initialized Objects,[object Object],Ensure objects cannot get into partially initialized state,[object Object],Make all fields private and require valid values for all mandatory fields in all constructors,[object Object],Example: Student object is invalid unless it has Name and FacultyNumber,[object Object],114,[object Object],class Student,[object Object],{,[object Object],  private string name, facultyNumber;,[object Object],  public Student(string name, string facultyNumber),[object Object],  { … },[object Object],},[object Object]
Variable Scope,[object Object],Variable scope defines how "famous" is a variable in the program,[object Object],Static variables are more "famous" than instance variables, and they are more "famous" than local,[object Object],Variables' visibility is directly related to their scope,[object Object],public, protected, internal, private,[object Object],Always try to reduce the variable's scope,[object Object],This reduces potential coupling,[object Object],Avoid public fields (exception: readonly / const),[object Object],Access all fields through properties / methods,[object Object],115,[object Object]
Exceeded Scope – Example,[object Object],116,[object Object],public class Globals,[object Object],{,[object Object],  public static int state = 0;,[object Object],},[object Object],public class Genious ,[object Object],{,[object Object],  public static void PrintSomething(),[object Object],  {,[object Object],    if (Globals.state == 0),[object Object],    {,[object Object],      Console.WriteLine("Hello.");,[object Object],    },[object Object],    else,[object Object],    {,[object Object],      Console.WriteLine("Good bye.");,[object Object],    },[object Object],  },[object Object],},[object Object]
Variable Span and Lifetime,[object Object],Variable span,[object Object],The average number of lines of code (LOC) between variable usages,[object Object],Variable lifetime,[object Object],The number of lines of code (LOC) between the first and the last variable usage in a block,[object Object],Keep variable span and lifetime as low as possible,[object Object],117,[object Object],Always define and initialize variables just before their first use and never before it!,[object Object]
Unneeded Large Variable Span and Lifetime,[object Object],int count;,[object Object],int[] numbers = new int[100];,[object Object],for (int i = 0; i < numbers.Length; i++),[object Object],{,[object Object],  numbers[i] = i;,[object Object],},[object Object],count = 0;,[object Object],for (int i = 0; i < numbers.Length / 2; i++),[object Object],{,[object Object],  numbers[i] = numbers[i] * numbers[i];,[object Object],},[object Object],for (int i = 0; i < numbers.Length; i++),[object Object],{,[object Object],  if (numbers[i] % 3 == 0),[object Object],  {,[object Object],    count++;,[object Object],  },[object Object],},[object Object],Console.WriteLine(count);,[object Object],118,[object Object],lifetime ("count") = 19,[object Object],span =,[object Object],19 / 4 = ,[object Object],4.75,[object Object]
Reduced Variable Span and Lifetime,[object Object],119,[object Object],int[] numbers = new int[100];,[object Object],for (int i = 0; i < numbers.Length; i++),[object Object],{,[object Object],  numbers[i] = i;,[object Object],},[object Object],for (int i = 0; i < numbers.Length / 2; i++),[object Object],{,[object Object],  numbers[i] = numbers[i] * numbers[i];,[object Object],},[object Object],int count = 0;,[object Object],for (int i = 0; i < numbers.Length; i++),[object Object],{,[object Object],  if (numbers[i] % 3 == 0),[object Object],  {,[object Object],    count++;,[object Object],  },[object Object],},[object Object],Console.WriteLine(count);,[object Object],lifetime = 9,[object Object],span=,[object Object],9 / 3 = 3,[object Object]
Single Purpose,[object Object],Variables should have single purpose,[object Object],Never use a single variable for multiple purposes!,[object Object],Economizing memory is not an excuse,[object Object],Can you choose a good name for variable that is used for several purposes?,[object Object],Example: variable used to count students of to keep the average of their grades,[object Object],Proposed name: studentsCountOrAvgGrade,[object Object],120,[object Object]
Variables – Other Suggestions,[object Object],Don't define variables that are not used,[object Object],Compilers usually issues warnings,[object Object],Don't use variables with hidden purpose,[object Object],Incorrect example:,[object Object],Instead use enumeration:,[object Object],121,[object Object],int mode = 1;,[object Object],…,[object Object],if (mode == 1) …; // Read,[object Object],if (mode == 2) …; // Write,[object Object],if (mode == 3) …; // Read and write,[object Object],enum ResourceAccessMode { Read, Write, ReadWrite },[object Object]
Using Expressions,[object Object],Best Practices,[object Object]
Avoid Complex Expressions,[object Object],Never use complex expressions in the code!,[object Object],Incorrect example:,[object Object],Complex expressions are evil because:,[object Object],Make code hard to read and understand, hard to debug, hard to modify and hard to maintain,[object Object],123,[object Object],What shall we do if we get at this line IndexOutOfRangeException?,[object Object],for (int i=0; i<xCoords.length; i++) {,[object Object],  for (int j=0; j<yCoords.length; j++) {,[object Object],    matrix[i][j] = ,[object Object],      matrix[xCoords[findMax(i)+1]][yCoords[findMin(j)-1]] *,[object Object],      matrix[yCoords[findMax(j)+1]][xCoords[findMin(i)-1]];,[object Object],  },[object Object],},[object Object],There are 10 potential sources of IndexOutOfRangeException in this expression!,[object Object]
Simplifying Complex Expressions,[object Object],124,[object Object],for (int i = 0; i < xCoords.length; i++),[object Object],{,[object Object],  for (int j = 0; j < yCoords.length; j++),[object Object],  {,[object Object],    int maxStartIndex = findMax(i) + 1;,[object Object],    int minStartIndex = findMin(i) - 1;,[object Object],    int minXcoord = xCoords[minStartIndex];,[object Object],    int maxXcoord = xCoords[maxStartIndex];,[object Object],    int minYcoord = yCoords[minStartIndex];,[object Object],    int maxYcoord = yCoords[maxStartIndex];,[object Object],    int newValue = ,[object Object],      matrix[maxXcoord][minYcoord] *,[object Object],      matrix[maxYcoord][minXcoord];,[object Object],    matrix[i][j] = newValue;,[object Object],  },[object Object],},[object Object]
Using Constants,[object Object],When and How to Use Constants?,[object Object]
Avoid Magic Numbers and Strings,[object Object],What is magic number or value?,[object Object],Magic numbers / values are all literals different than 0, 1, -1, null and "" (empty string),[object Object],Avoid using magic numbers / values,[object Object],They are hard to maintain,[object Object],When change occurs, you need to modify all occurrences of the magic number / constant,[object Object],Their meaning is not obvious,[object Object],Example: what does the number 1024 mean?,[object Object],126,[object Object]
The Evil Magic Numbers,[object Object],127,[object Object],public class GeometryUtils,[object Object],{,[object Object],  public static double CalcCircleArea(double radius),[object Object],  {,[object Object],    double area = 3.14159206 * radius * radius;,[object Object],    return area;,[object Object],  },[object Object],  public static double CalcCirclePerimeter(double radius),[object Object],  {,[object Object],    double perimeter = 6.28318412 * radius;,[object Object],    return perimeter;,[object Object],  },[object Object],  public static double CalcElipseArea(double axis1, double axis2),[object Object],  {,[object Object],    double area = 3.14159206 * axis1 * axis2;,[object Object],    return area;,[object Object],  },[object Object],},[object Object]
Turning MagicNumbers into Constants,[object Object],128,[object Object],public class GeometryUtils,[object Object],{,[object Object],  public const double PI = 3.14159206;,[object Object],  public static double CalcCircleArea(double radius),[object Object],  {,[object Object],    double area = PI * radius * radius;,[object Object],    return area;,[object Object],  },[object Object],  public static double CalcCirclePerimeter(double radius),[object Object],  {,[object Object],    double perimeter = 2 * PI * radius;,[object Object],    return perimeter;,[object Object],  },[object Object],  public static double CalcElipseArea(,[object Object],   double axis1, double axis2),[object Object],  {,[object Object],    double area = PI * axis1 * axis2;,[object Object],    return area;,[object Object],  },[object Object],},[object Object]
When to Use Constants?,[object Object],Constants should be used in the following cases:,[object Object],When we need to use numbers or other values and their logical meaning and value are not obvious,[object Object],File names,[object Object],Mathematical constants,[object Object],Bounds and ranges,[object Object],129,[object Object],public const string SettingsFileName =,[object Object],  "ApplicationSettings.xml";,[object Object],public const double E = 2.7182818284;,[object Object],public const int READ_BUFFER_SIZE = 5 * 1024 *1024;,[object Object]
When to Avoid Constants?,[object Object],Sometime it is better to keep the magic values instead of using a constant,[object Object],Error messages and exception descriptions,[object Object],SQL commands for database operations,[object Object],Titles of GUI elements (labels, buttons, menus, dialogs, etc.),[object Object],For internationalization purposes use resources, not constants,[object Object],130,[object Object]
Using Control Constructs,[object Object],Using Conditional Statements and Loops Correctly,[object Object]
Using Conditional Statements,[object Object],Always use { and } for the conditional statements body, even when it is a single line:,[object Object],Why omitting the brackets could be harmful?,[object Object],This is misleading code + misleading formatting,[object Object],132,[object Object],if (condition),[object Object],{,[object Object],  DoSometing();,[object Object],},[object Object],if (condition),[object Object],  DoSomething();,[object Object],  DoAnotherThing();,[object Object],DoDifferentThing();,[object Object]
Use Simple Conditions,[object Object],Do not use complex if conditions,[object Object],You can always simplify them by introducing boolean variables or boolean methods,[object Object],Incorrect example:,[object Object],Complex boolean expressions are harmful,[object Object],How you will find the problem if you get IndexOutOfRangeException?,[object Object],133,[object Object],if (x > 0 && y > 0 && x < Width-1 && y < Height-1 &&,[object Object],  matrix[x, y] == 0 && matrix[x-1, y] == 0 &&,[object Object],  matrix[x+1, y] == 0 && matrix[x, y-1] == 0 &&,[object Object],  matrix[x, y+1] == 0 && !visited[x, y]),[object Object]
Simplifying Boolean Conditions,[object Object],The last example can be easily refactored into self-documenting code:,[object Object],Now the code is:,[object Object],Easy to read – the logic of the condition is clear,[object Object],Easy to debug – breakpoint can be put at the if,[object Object],134,[object Object],bool inRange = ,[object Object],  x > 0 && y > 0 && x < Width-1 && y < Height-1;,[object Object],bool emptyCellAndNeighbours =,[object Object],  matrix[x, y] == 0 && matrix[x-1, y] == 0 &&,[object Object],  matrix[x+1, y] == 0 && matrix[x, y-1] == 0 &&,[object Object],  matrix[x, y+1] == 0;,[object Object],if (inRange && emptyCellAndNeighbours && !visited[x, y]),[object Object]
Avoid Deep Nesting of Blocks,[object Object],Deep nesting of conditional statements and loops makes the code unclear,[object Object],Deeply nested code is complex and hard to read and understand,[object Object],Usually you can extract portions of the code in separate methods,[object Object],This simplifies the logic of the code,[object Object],Using good method name makes the code self-documenting,[object Object],135,[object Object]
Deep Nesting – Example,[object Object],136,[object Object],if (maxElem != Int32.MaxValue),[object Object],{,[object Object],  if (arr[i] < arr[i + 1]),[object Object],  {,[object Object],    if (arr[i + 1] < arr[i + 2]),[object Object],    {,[object Object],      if (arr[i + 2] < arr[i + 3]),[object Object],      {,[object Object],        maxElem = arr[i + 3];,[object Object],      },[object Object],      else,[object Object],      {,[object Object],        maxElem = arr[i + 2];,[object Object],      },[object Object],    },[object Object],    else,[object Object],    {,[object Object],      if (arr[i + 1] < arr[i + 3]),[object Object],      {,[object Object],        maxElem = arr[i + 3];,[object Object],      },[object Object],      else,[object Object],      {,[object Object],        maxElem = arr[i + 1];,[object Object],      },[object Object],    },[object Object],  },[object Object],(continues on the next slide),[object Object]
Deep Nesting – Example (2),[object Object],137,[object Object],  else,[object Object],  {,[object Object],    if (arr[i] < arr[i + 2]),[object Object],    {,[object Object],      if (arr[i + 2] < arr[i + 3]),[object Object],      {,[object Object],        maxElem = arr[i + 3];,[object Object],      },[object Object],      else,[object Object],      {,[object Object],        maxElem = arr[i + 2];,[object Object],      },[object Object],    },[object Object],    else,[object Object],    {,[object Object],      if (arr[i] < arr[i + 3]),[object Object],      {,[object Object],        maxElem = arr[i + 3];,[object Object],      },[object Object],      else,[object Object],      {,[object Object],        maxElem = arr[i];,[object Object],      },[object Object],    },[object Object],  },[object Object],},[object Object]
Avoiding Deep Nesting – Example,[object Object],138,[object Object],private static int Max(int i, int j),[object Object],{,[object Object],  if (i < j),[object Object],  {,[object Object],    return j;,[object Object],  },[object Object],  else,[object Object],  {,[object Object],    return i;,[object Object],  },[object Object],},[object Object],private static int Max(int i, int j, int k),[object Object],{,[object Object],  if (i < j),[object Object],  {,[object Object],    int maxElem = Max(j, k);,[object Object],    return maxElem;,[object Object],  },[object Object],  else,[object Object],  {,[object Object],    int maxElem = Max(i, k);,[object Object],    return maxElem;,[object Object],  },[object Object],},[object Object],(continues on the next slide),[object Object]
Avoiding Deep Nesting – Example,[object Object],139,[object Object],private static int FindMax(int[] arr, int i),[object Object],{,[object Object],  if (arr[i] < arr[i + 1]),[object Object],  {,[object Object],    int maxElem = Max(arr[i + 1], arr[i + 2], arr[i + 3]);,[object Object],    return maxElem;,[object Object],  },[object Object],  else,[object Object],  {,[object Object],    int maxElem = Max(arr[i], arr[i + 2], arr[i + 3]);,[object Object],    return maxElem;,[object Object],  },[object Object],},[object Object],if (maxElem != Int32.MaxValue) {,[object Object],  maxElem = FindMax(arr, i);,[object Object],},[object Object]
Using Case Statement,[object Object],Choose the most effective ordering of cases,[object Object],Put the normal (usual) case first,[object Object],Order cases by frequency,[object Object],Put the most unusual (exceptional) case last,[object Object],Order cases alphabetically or numerically,[object Object],Keep the actions of each case simple,[object Object],Extract complex logic in separate methods,[object Object],Use the default clause in a casestatement or the last elsein a chain of if-else to trap errors,[object Object],140,[object Object]
Bad Case Statement,[object Object],141,[object Object],void ProcessNextChar(char ch),[object Object],{,[object Object],  switch (parseState),[object Object],  {,[object Object],    InTag:,[object Object],      if (ch == ">"),[object Object],      {,[object Object],        Console.WriteLine("Found tag: {0}", tag);,[object Object],        text = "";,[object Object],        parseState = ParseState.OutOfTag;,[object Object],      },[object Object],      else,[object Object],      {,[object Object],        tag = tag + ch;,[object Object],      },[object Object],      break;,[object Object],    OutOfTag:,[object Object],      …,[object Object],  },[object Object],},[object Object]
Improved Case Statement,[object Object],142,[object Object],void ProcessNextChar(char ch),[object Object],{,[object Object],  switch (parseState),[object Object],  {,[object Object],    InTag:,[object Object],      ProcessCharacterInTag(ch);,[object Object],      break;,[object Object],    OutOfTag:,[object Object],      ProcessCharacterOutOfTag(ch);,[object Object],      break;,[object Object],    default:,[object Object],      throw new Exception("Invalid parse state: " +,[object Object],        parseState);,[object Object],  },[object Object],},[object Object]
Using Loops,[object Object],Choosing the correct type of loop:,[object Object],Use for loop to repeat some block of code a certain number of times,[object Object],Use foreach loop to process each element of array or collection,[object Object],Use while / do-while loop when you don't know how many times a block should be repeated,[object Object],Avoid deep nesting of loops,[object Object],You can extract the loop body in a new method,[object Object],143,[object Object]
Loops: Best Practices,[object Object],Keep loops simple,[object Object],This helps readers of your code,[object Object],Treat the inside of the loop as it were a routine,[object Object],Don’t make the reader look inside the loop to understand the loop control,[object Object],Think of a loop as a black box:,[object Object],144,[object Object],while (!inputFile.EndOfFile() && !hasErrors),[object Object],{,[object Object],},[object Object],(black box code),[object Object]
Defensive Programming,[object Object],Using Assertions and Exceptions Correctly,[object Object]
Principles of Defensive Programming,[object Object],Fundamental principle of defensive programming,[object Object],Defensive programming means:,[object Object],To expect incorrect input and to handle it correctly,[object Object],To think not only about the usual execution flow, but to consider also unusual situations,[object Object],To ensure that incorrect input results to exception, not to incorrect output,[object Object],146,[object Object],Any public method should check its input data, preconditions and postconditions,[object Object]
Defensive Programming – Example,[object Object],147,[object Object],string Substring(string str, int startIndex, int length),[object Object],{,[object Object],  if (str == null),[object Object],  {,[object Object],    throw new NullReferenceException("Str is null.");,[object Object],  },[object Object],  if (startIndex >= str.Length),[object Object],  {,[object Object],    throw new ArgumentException(,[object Object],      "Invalid startIndex:" + startIndex);,[object Object],  },[object Object],  if (startIndex + count > str.Length),[object Object],  {,[object Object],    throw new ArgumentException("Invalid length:" + length);,[object Object],  },[object Object],  …,[object Object],  Debug.Assert(result.Length == length);,[object Object],},[object Object],Check the input and preconditions.,[object Object],Perform the method main logic.,[object Object],Check the postconditions.,[object Object]
Exceptions – Best Practices,[object Object],Choose a good name for your exception class,[object Object],Incorrect example:,[object Object],Example:,[object Object],Use descriptive error messages,[object Object],Incorrect example:,[object Object],Example:,[object Object],148,[object Object],throw new Exception("File error!");,[object Object],throw new FileNotFoundException("Cannot find file " + fileName);,[object Object],throw new Exception("Error!");,[object Object],throw new ArgumentException("The speed should be a number " +,[object Object],  "between " + MIN_SPEED + " and " + MAX_SPEED + ".");,[object Object]
Exceptions Handling Best Practices (2),[object Object],Catch only exceptions that you are capable to process correctly,[object Object],Do not catch all exceptions!,[object Object],Incorrect example:,[object Object],What about OutOfMemoryException?,[object Object],149,[object Object],try,[object Object],{,[object Object],  ReadSomeFile();,[object Object],},[object Object],catch,[object Object],{,[object Object],  Console.WriteLine("File not found!");,[object Object],},[object Object]
Exceptions Handling Best Practices (3),[object Object],Always include the exception cause when throwing a new exception,[object Object],150,[object Object],try,[object Object],{,[object Object],  WithdrawMoney(account, amount);,[object Object],},[object Object],catch (DatabaseException dbex),[object Object],{,[object Object],  throw new WithdrawException(String.Format(,[object Object],    "Can not withdraw the amount {0} from acoount {1}",,[object Object],    amount, account), dbex);,[object Object],},[object Object],We include in the exceptions chain the original source of the problem.,[object Object]
Exceptions Handling Best Practices (4),[object Object],Throw exceptions at the corresponding level of abstraction,[object Object],Example: Bank account withdrawal operation could throw InsufficientFundsException but cannot throw FileAccessDeniedException,[object Object],Display to the end users only messages that they could understand,[object Object],151,[object Object],or,[object Object]
Disposable Resources,[object Object],Handle disposable resources with care,[object Object],All classes implementing IDisposable should follow the try-finally / using pattern:,[object Object],152,[object Object],StreamReader reader = ,[object Object],  new StreamReader("file.txt");,[object Object],try,[object Object],{ ,[object Object],  String line = reader.ReadLine(); ,[object Object],},[object Object],finally,[object Object],{,[object Object],  reader.Close();,[object Object],},[object Object],StreamReader reader = ,[object Object],  new StreamReader(,[object Object],    "file.txt");,[object Object],using (reader),[object Object],{ ,[object Object],  String line =,[object Object],    reader.ReadLine(); ,[object Object],},[object Object],==,[object Object]
Comments and Code Documentation,[object Object],The Concept of Self-Documenting Code,[object Object]
Effective Comments,[object Object],Effective comments do not repeat the code,[object Object],They explain it at higher level and reveal non-obvious details,[object Object],The best software documentation is the source code itself – keep it clean and readable,[object Object],Self-documenting code is code that is self-explainable and does not need comments,[object Object],Simple design, small well named methods, strong cohesion and loose coupling, simple logic, good variable names, good formatting, … ,[object Object],154,[object Object]
Self-Documenting Code,[object Object],Self-documenting code fundamental principles,[object Object],155,[object Object],The best documentation is the code itself. ,[object Object],Make the code self-explainable and self-documenting, easy to read and understand.,[object Object],Do not document bad code, rewrite it!,[object Object]
Bad Comments – Example,[object Object],156,[object Object],public static List<int> FindPrimes(int start, int end),[object Object],{,[object Object],    // Create new list of integers,[object Object],    List<int> primesList = new List<int>();,[object Object],    // Perform a loop from start to end,[object Object],    for (int num = start; num <= end; num++),[object Object],    {,[object Object],        // Declare boolean variable, initially true,[object Object],        bool prime = true;,[object Object],        // Perform loop from 2 to sqrt(num),[object Object],        for (int div = 2; div <= Math.Sqrt(num); div++),[object Object],        {,[object Object],            // Check if div divides num with no remainder ,[object Object],            if (num % div == 0),[object Object],            {,[object Object],                // We found a divider -> the number is not prime,[object Object],                prime = false;,[object Object],                // Exit from the loop,[object Object],                break;,[object Object],            },[object Object],(continues on the next slide),[object Object]
Bad Comments – Example (2),[object Object],157,[object Object],          // Continue with the next loop value,[object Object],        },[object Object],        // Check if the number is prime,[object Object],        if (prime),[object Object],        {,[object Object],            // Add the number to the list of primes,[object Object],            primesList.Add(num);,[object Object],        },[object Object],    },[object Object],    // Return the list of primes,[object Object],    return primesList;,[object Object],},[object Object]
Self-Documenting Code – Example,[object Object],158,[object Object],public static List<int> FindPrimes(int start, int end),[object Object],{,[object Object],  List<int> primesList = new List<int>();,[object Object],  for (int num = start; num <= end; num++),[object Object],  {,[object Object],    bool isPrime = IsPrime(num);,[object Object],    if (isPrime),[object Object],    {,[object Object],      primesList.Add(num);,[object Object],    },[object Object],  },[object Object],  return primesList;,[object Object],},[object Object],Good code does not need comments. It is self-explaining.,[object Object],(continues on the next slide),[object Object]
Self-Documenting Code –Example (2),[object Object],159,[object Object],private static bool IsPrime(int num),[object Object],{,[object Object],  bool isPrime = true;,[object Object],  int maxDivider = Math.Sqrt(num);,[object Object],  for (int div = 2; div <= maxDivider; div++),[object Object],  {,[object Object],    if (num % div == 0),[object Object],    {,[object Object],      // We found a divider -> the number is not prime,[object Object],      isPrime = false;,[object Object],      break;,[object Object],    },[object Object],  },[object Object],  return isPrime;,[object Object],},[object Object],Good methods have good name and are easy to read and understand.,[object Object],This comment explain non-obvious details. It does not repeat the code.,[object Object]
Code Refactoring,[object Object],Improving the Quality of the Existing Code,[object Object]
Code Refactoring,[object Object],What is refactoring of the source code?,[object Object],Improving the design and quality of existing source code without changing its behavior,[object Object],Step by step process that turns the bad code into good code (if possible),[object Object],Why we need refactoring?,[object Object],Code constantly changes and its quality constantly degrades (unless refactored),[object Object],Requirements often change and code needs to be changed to follow them,[object Object],161,[object Object]
Rafactoring Patterns,[object Object],When should we perform refactoring of the code?,[object Object],Bad smells in the code indicate need of refactoring,[object Object],Unit tests guarantee that refactoring does not change the behavior,[object Object],Rafactoring patterns,[object Object],Large repeating code fragments  extract repeating code in separate method,[object Object],Large methods  split them logically,[object Object],Large loop body or deep nesting  extract method,[object Object],162,[object Object]
Rafactoring Patterns (2),[object Object],Refactoring patterns,[object Object],Class or method has weak cohesion  split into several classes / methods,[object Object],Single change carry out changes in several classes  classes have tight coupling  consider redesign,[object Object],Related data are always used together but are not part of a single class  group them in a class,[object Object],A method has too many parameters  create a class to groups parameters together,[object Object],A method calls more methods from another class than from its own class  move it,[object Object],163,[object Object]
Rafactoring Patterns (3),[object Object],Refactoring patterns,[object Object],Two classes are tightly coupled  merge them or redesign them to separate their responsibilities,[object Object],Public non-constant fields  make them private and define accessing properties,[object Object],Magic numbers in the code  consider extracting constants,[object Object],Bad named class / method / variable  rename it,[object Object],Complex boolean condition  split it to several expressions or method calls,[object Object],164,[object Object]
Rafactoring Patterns (4),[object Object],Refactoring patterns,[object Object],Complex expression  split it into few simple parts,[object Object],A set of constants is used as enumeration  convert it to enumeration,[object Object],Method logic is too complex and is hard to understand  extract several more simple methods or even create a new class,[object Object],Unused classes, methods, parameters, variables  remove them,[object Object],Large data is passed by value without a good reason  pass it by reference,[object Object],165,[object Object]
Rafactoring Patterns (5),[object Object],Refactoring patterns,[object Object],Few classes share repeating functionality  extract base class and reuse the common code,[object Object],Different classes need to be instantiated depending on configuration setting  use factory,[object Object],Code is not well formatted  reformat it,[object Object],Too many classes in a single namespace  split classes logically into more namespaces,[object Object],Unused using definitions  remove them,[object Object],Non-descriptive error messages  improve them,[object Object],Absence of defensive programming  add it,[object Object],166,[object Object]
Refactoring of Bad Code,[object Object],Live Demo,[object Object]
Resources,[object Object],The bible of high-quality software construction:,[object Object],168,[object Object],[object Object]
http://codecourse.telerik.comCode Complete, 2nd edition, Steve McConnell, Microsoft Press, 2004, ISBN 0735619670, http://www.cc2e.com,[object Object]

More Related Content

What's hot (20)

Introduction to JSON
Introduction to JSONIntroduction to JSON
Introduction to JSON
 
String in java
String in javaString in java
String in java
 
Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
 
Packages - PL/SQL
Packages - PL/SQLPackages - PL/SQL
Packages - PL/SQL
 
C# - Part 1
C# - Part 1C# - Part 1
C# - Part 1
 
04 Handling Exceptions
04 Handling Exceptions04 Handling Exceptions
04 Handling Exceptions
 
PHP FUNCTIONS
PHP FUNCTIONSPHP FUNCTIONS
PHP FUNCTIONS
 
C# basics
 C# basics C# basics
C# basics
 
Database development coding standards
Database development coding standardsDatabase development coding standards
Database development coding standards
 
Introduction to java
Introduction to javaIntroduction to java
Introduction to java
 
Constructors in java
Constructors in javaConstructors in java
Constructors in java
 
Unit 9. Structure and Unions
Unit 9. Structure and UnionsUnit 9. Structure and Unions
Unit 9. Structure and Unions
 
Lesson 4 constant
Lesson 4  constantLesson 4  constant
Lesson 4 constant
 
String Builder & String Buffer (Java Programming)
String Builder & String Buffer (Java Programming)String Builder & String Buffer (Java Programming)
String Builder & String Buffer (Java Programming)
 
JAVA OOP
JAVA OOPJAVA OOP
JAVA OOP
 
Java I/o streams
Java I/o streamsJava I/o streams
Java I/o streams
 
OOPS Basics With Example
OOPS Basics With ExampleOOPS Basics With Example
OOPS Basics With Example
 
PHP - Introduction to Object Oriented Programming with PHP
PHP -  Introduction to  Object Oriented Programming with PHPPHP -  Introduction to  Object Oriented Programming with PHP
PHP - Introduction to Object Oriented Programming with PHP
 
L13 string handling(string class)
L13 string handling(string class)L13 string handling(string class)
L13 string handling(string class)
 
Java Data Types
Java Data TypesJava Data Types
Java Data Types
 

Similar to Writing High Quality Code in C#

Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddSrinivasa GV
 
21. High-Quality Programming Code
21. High-Quality Programming Code21. High-Quality Programming Code
21. High-Quality Programming CodeIntro C# Book
 
C# coding standards, good programming principles & refactoring
C# coding standards, good programming principles & refactoringC# coding standards, good programming principles & refactoring
C# coding standards, good programming principles & refactoringEyob Lube
 
Advanced PowerShell Automation
Advanced PowerShell AutomationAdvanced PowerShell Automation
Advanced PowerShell Automationkieranjacobsen
 
Back-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real WorldBack-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real WorldDavid McCarter
 
Back-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real WorldBack-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real WorldDavid McCarter
 
Combating software entropy 2-roc1-
Combating software entropy 2-roc1-Combating software entropy 2-roc1-
Combating software entropy 2-roc1-Hammad Rajjoub
 
Dot Net Fundamentals
Dot Net FundamentalsDot Net Fundamentals
Dot Net FundamentalsLiquidHub
 
Top 50 .NET Interview Questions and Answers 2019 | Edureka
Top 50 .NET Interview Questions and Answers 2019 | EdurekaTop 50 .NET Interview Questions and Answers 2019 | Edureka
Top 50 .NET Interview Questions and Answers 2019 | EdurekaEdureka!
 
Thesis+of+laleh+eshkevari.ppt
Thesis+of+laleh+eshkevari.pptThesis+of+laleh+eshkevari.ppt
Thesis+of+laleh+eshkevari.pptPtidej Team
 
Best practices in enterprise applications
Best practices in enterprise applicationsBest practices in enterprise applications
Best practices in enterprise applicationsChandra Sekhar Saripaka
 

Similar to Writing High Quality Code in C# (20)

Code review
Code reviewCode review
Code review
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
 
21. High-Quality Programming Code
21. High-Quality Programming Code21. High-Quality Programming Code
21. High-Quality Programming Code
 
Codings Standards
Codings StandardsCodings Standards
Codings Standards
 
C# coding standards, good programming principles & refactoring
C# coding standards, good programming principles & refactoringC# coding standards, good programming principles & refactoring
C# coding standards, good programming principles & refactoring
 
Advanced PowerShell Automation
Advanced PowerShell AutomationAdvanced PowerShell Automation
Advanced PowerShell Automation
 
Back-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real WorldBack-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real World
 
Back-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real WorldBack-2-Basics: .NET Coding Standards For The Real World
Back-2-Basics: .NET Coding Standards For The Real World
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Coding conventions
Coding conventionsCoding conventions
Coding conventions
 
Combating software entropy 2-roc1-
Combating software entropy 2-roc1-Combating software entropy 2-roc1-
Combating software entropy 2-roc1-
 
Dot Net Fundamentals
Dot Net FundamentalsDot Net Fundamentals
Dot Net Fundamentals
 
Abcxyz
AbcxyzAbcxyz
Abcxyz
 
Coding standard
Coding standardCoding standard
Coding standard
 
Top 50 .NET Interview Questions and Answers 2019 | Edureka
Top 50 .NET Interview Questions and Answers 2019 | EdurekaTop 50 .NET Interview Questions and Answers 2019 | Edureka
Top 50 .NET Interview Questions and Answers 2019 | Edureka
 
csharp.docx
csharp.docxcsharp.docx
csharp.docx
 
Thesis+of+laleh+eshkevari.ppt
Thesis+of+laleh+eshkevari.pptThesis+of+laleh+eshkevari.ppt
Thesis+of+laleh+eshkevari.ppt
 
Best practices in enterprise applications
Best practices in enterprise applicationsBest practices in enterprise applications
Best practices in enterprise applications
 
Objc
ObjcObjc
Objc
 
Lecture No 13.ppt
Lecture No 13.pptLecture No 13.ppt
Lecture No 13.ppt
 

More from Svetlin Nakov

Programming World in 2024
Programming World in 2024Programming World in 2024
Programming World in 2024Svetlin Nakov
 
AI Tools for Business and Startups
AI Tools for Business and StartupsAI Tools for Business and Startups
AI Tools for Business and StartupsSvetlin Nakov
 
AI Tools for Scientists - Nakov (Oct 2023)
AI Tools for Scientists - Nakov (Oct 2023)AI Tools for Scientists - Nakov (Oct 2023)
AI Tools for Scientists - Nakov (Oct 2023)Svetlin Nakov
 
AI Tools for Entrepreneurs
AI Tools for EntrepreneursAI Tools for Entrepreneurs
AI Tools for EntrepreneursSvetlin Nakov
 
Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023
Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023
Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023Svetlin Nakov
 
AI Tools for Business and Personal Life
AI Tools for Business and Personal LifeAI Tools for Business and Personal Life
AI Tools for Business and Personal LifeSvetlin Nakov
 
Свободно ИТ учебно съдържание за учители по програмиране и ИТ
Свободно ИТ учебно съдържание за учители по програмиране и ИТСвободно ИТ учебно съдържание за учители по програмиране и ИТ
Свободно ИТ учебно съдържание за учители по програмиране и ИТSvetlin Nakov
 
AI and the Professions of the Future
AI and the Professions of the FutureAI and the Professions of the Future
AI and the Professions of the FutureSvetlin Nakov
 
Programming Languages Trends for 2023
Programming Languages Trends for 2023Programming Languages Trends for 2023
Programming Languages Trends for 2023Svetlin Nakov
 
IT Professions and How to Become a Developer
IT Professions and How to Become a DeveloperIT Professions and How to Become a Developer
IT Professions and How to Become a DeveloperSvetlin Nakov
 
GitHub Actions (Nakov at RuseConf, Sept 2022)
GitHub Actions (Nakov at RuseConf, Sept 2022)GitHub Actions (Nakov at RuseConf, Sept 2022)
GitHub Actions (Nakov at RuseConf, Sept 2022)Svetlin Nakov
 
IT Professions and Their Future
IT Professions and Their FutureIT Professions and Their Future
IT Professions and Their FutureSvetlin Nakov
 
How to Become a QA Engineer and Start a Job
How to Become a QA Engineer and Start a JobHow to Become a QA Engineer and Start a Job
How to Become a QA Engineer and Start a JobSvetlin Nakov
 
Призвание и цели: моята рецепта
Призвание и цели: моята рецептаПризвание и цели: моята рецепта
Призвание и цели: моята рецептаSvetlin Nakov
 
What Mongolian IT Industry Can Learn from Bulgaria?
What Mongolian IT Industry Can Learn from Bulgaria?What Mongolian IT Industry Can Learn from Bulgaria?
What Mongolian IT Industry Can Learn from Bulgaria?Svetlin Nakov
 
How to Become a Software Developer - Nakov in Mongolia (Oct 2022)
How to Become a Software Developer - Nakov in Mongolia (Oct 2022)How to Become a Software Developer - Nakov in Mongolia (Oct 2022)
How to Become a Software Developer - Nakov in Mongolia (Oct 2022)Svetlin Nakov
 
Blockchain and DeFi Overview (Nakov, Sept 2021)
Blockchain and DeFi Overview (Nakov, Sept 2021)Blockchain and DeFi Overview (Nakov, Sept 2021)
Blockchain and DeFi Overview (Nakov, Sept 2021)Svetlin Nakov
 
Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)
Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)
Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)Svetlin Nakov
 
10 Minutes Coding Lesson by Svetlin Nakov (April 2021)
10 Minutes Coding Lesson by Svetlin Nakov (April 2021)10 Minutes Coding Lesson by Svetlin Nakov (April 2021)
10 Minutes Coding Lesson by Svetlin Nakov (April 2021)Svetlin Nakov
 
Starting Your First Job in the Software Industry: Tips and Tricks from Nakov
Starting Your First Job in the Software Industry: Tips and Tricks from NakovStarting Your First Job in the Software Industry: Tips and Tricks from Nakov
Starting Your First Job in the Software Industry: Tips and Tricks from NakovSvetlin Nakov
 

More from Svetlin Nakov (20)

Programming World in 2024
Programming World in 2024Programming World in 2024
Programming World in 2024
 
AI Tools for Business and Startups
AI Tools for Business and StartupsAI Tools for Business and Startups
AI Tools for Business and Startups
 
AI Tools for Scientists - Nakov (Oct 2023)
AI Tools for Scientists - Nakov (Oct 2023)AI Tools for Scientists - Nakov (Oct 2023)
AI Tools for Scientists - Nakov (Oct 2023)
 
AI Tools for Entrepreneurs
AI Tools for EntrepreneursAI Tools for Entrepreneurs
AI Tools for Entrepreneurs
 
Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023
Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023
Bulgarian Tech Industry - Nakov at Dev.BG All in One Conference 2023
 
AI Tools for Business and Personal Life
AI Tools for Business and Personal LifeAI Tools for Business and Personal Life
AI Tools for Business and Personal Life
 
Свободно ИТ учебно съдържание за учители по програмиране и ИТ
Свободно ИТ учебно съдържание за учители по програмиране и ИТСвободно ИТ учебно съдържание за учители по програмиране и ИТ
Свободно ИТ учебно съдържание за учители по програмиране и ИТ
 
AI and the Professions of the Future
AI and the Professions of the FutureAI and the Professions of the Future
AI and the Professions of the Future
 
Programming Languages Trends for 2023
Programming Languages Trends for 2023Programming Languages Trends for 2023
Programming Languages Trends for 2023
 
IT Professions and How to Become a Developer
IT Professions and How to Become a DeveloperIT Professions and How to Become a Developer
IT Professions and How to Become a Developer
 
GitHub Actions (Nakov at RuseConf, Sept 2022)
GitHub Actions (Nakov at RuseConf, Sept 2022)GitHub Actions (Nakov at RuseConf, Sept 2022)
GitHub Actions (Nakov at RuseConf, Sept 2022)
 
IT Professions and Their Future
IT Professions and Their FutureIT Professions and Their Future
IT Professions and Their Future
 
How to Become a QA Engineer and Start a Job
How to Become a QA Engineer and Start a JobHow to Become a QA Engineer and Start a Job
How to Become a QA Engineer and Start a Job
 
Призвание и цели: моята рецепта
Призвание и цели: моята рецептаПризвание и цели: моята рецепта
Призвание и цели: моята рецепта
 
What Mongolian IT Industry Can Learn from Bulgaria?
What Mongolian IT Industry Can Learn from Bulgaria?What Mongolian IT Industry Can Learn from Bulgaria?
What Mongolian IT Industry Can Learn from Bulgaria?
 
How to Become a Software Developer - Nakov in Mongolia (Oct 2022)
How to Become a Software Developer - Nakov in Mongolia (Oct 2022)How to Become a Software Developer - Nakov in Mongolia (Oct 2022)
How to Become a Software Developer - Nakov in Mongolia (Oct 2022)
 
Blockchain and DeFi Overview (Nakov, Sept 2021)
Blockchain and DeFi Overview (Nakov, Sept 2021)Blockchain and DeFi Overview (Nakov, Sept 2021)
Blockchain and DeFi Overview (Nakov, Sept 2021)
 
Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)
Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)
Дигитални професии на бъдещето: не бъдете роботи! (юни 2021)
 
10 Minutes Coding Lesson by Svetlin Nakov (April 2021)
10 Minutes Coding Lesson by Svetlin Nakov (April 2021)10 Minutes Coding Lesson by Svetlin Nakov (April 2021)
10 Minutes Coding Lesson by Svetlin Nakov (April 2021)
 
Starting Your First Job in the Software Industry: Tips and Tricks from Nakov
Starting Your First Job in the Software Industry: Tips and Tricks from NakovStarting Your First Job in the Software Industry: Tips and Tricks from Nakov
Starting Your First Job in the Software Industry: Tips and Tricks from Nakov
 

Recently uploaded

UiPath Studio Web workshop series - Day 4
UiPath Studio Web workshop series - Day 4UiPath Studio Web workshop series - Day 4
UiPath Studio Web workshop series - Day 4DianaGray10
 
Automation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsAutomation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsDianaGray10
 
Patch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 updatePatch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 updateadam112203
 
Novo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNovo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNeo4j
 
Extra-120324-Visite-Entreprise-icare.pdf
Extra-120324-Visite-Entreprise-icare.pdfExtra-120324-Visite-Entreprise-icare.pdf
Extra-120324-Visite-Entreprise-icare.pdfInfopole1
 
AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024Brian Pichman
 
Technical SEO for Improved Accessibility WTS FEST
Technical SEO for Improved Accessibility  WTS FESTTechnical SEO for Improved Accessibility  WTS FEST
Technical SEO for Improved Accessibility WTS FESTBillieHyde
 
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox
 
20140402 - Smart house demo kit
20140402 - Smart house demo kit20140402 - Smart house demo kit
20140402 - Smart house demo kitJamie (Taka) Wang
 
From the origin to the future of Open Source model and business
From the origin to the future of  Open Source model and businessFrom the origin to the future of  Open Source model and business
From the origin to the future of Open Source model and businessFrancesco Corti
 
My key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIMy key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIVijayananda Mohire
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTopCSSGallery
 
UiPath Studio Web workshop series - Day 1
UiPath Studio Web workshop series  - Day 1UiPath Studio Web workshop series  - Day 1
UiPath Studio Web workshop series - Day 1DianaGray10
 
March Patch Tuesday
March Patch TuesdayMarch Patch Tuesday
March Patch TuesdayIvanti
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
 
GraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptx
GraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptxGraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptx
GraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptxNeo4j
 
IT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced ComputingIT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced ComputingMAGNIntelligence
 
Planetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl
 
UiPath Studio Web workshop Series - Day 3
UiPath Studio Web workshop Series - Day 3UiPath Studio Web workshop Series - Day 3
UiPath Studio Web workshop Series - Day 3DianaGray10
 

Recently uploaded (20)

UiPath Studio Web workshop series - Day 4
UiPath Studio Web workshop series - Day 4UiPath Studio Web workshop series - Day 4
UiPath Studio Web workshop series - Day 4
 
Automation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsAutomation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projects
 
Patch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 updatePatch notes explaining DISARM Version 1.4 update
Patch notes explaining DISARM Version 1.4 update
 
Novo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4jNovo Nordisk's journey in developing an open-source application on Neo4j
Novo Nordisk's journey in developing an open-source application on Neo4j
 
Extra-120324-Visite-Entreprise-icare.pdf
Extra-120324-Visite-Entreprise-icare.pdfExtra-120324-Visite-Entreprise-icare.pdf
Extra-120324-Visite-Entreprise-icare.pdf
 
SheDev 2024
SheDev 2024SheDev 2024
SheDev 2024
 
AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024
 
Technical SEO for Improved Accessibility WTS FEST
Technical SEO for Improved Accessibility  WTS FESTTechnical SEO for Improved Accessibility  WTS FEST
Technical SEO for Improved Accessibility WTS FEST
 
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through TokenizationStobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
Stobox 4: Revolutionizing Investment in Real-World Assets Through Tokenization
 
20140402 - Smart house demo kit
20140402 - Smart house demo kit20140402 - Smart house demo kit
20140402 - Smart house demo kit
 
From the origin to the future of Open Source model and business
From the origin to the future of  Open Source model and businessFrom the origin to the future of  Open Source model and business
From the origin to the future of Open Source model and business
 
My key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIMy key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAI
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development Companies
 
UiPath Studio Web workshop series - Day 1
UiPath Studio Web workshop series  - Day 1UiPath Studio Web workshop series  - Day 1
UiPath Studio Web workshop series - Day 1
 
March Patch Tuesday
March Patch TuesdayMarch Patch Tuesday
March Patch Tuesday
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
GraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptx
GraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptxGraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptx
GraphSummit Copenhagen 2024 - Neo4j Vision and Roadmap.pptx
 
IT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced ComputingIT Service Management (ITSM) Best Practices for Advanced Computing
IT Service Management (ITSM) Best Practices for Advanced Computing
 
Planetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile Brochure
 
UiPath Studio Web workshop Series - Day 3
UiPath Studio Web workshop Series - Day 3UiPath Studio Web workshop Series - Day 3
UiPath Studio Web workshop Series - Day 3
 

Writing High Quality Code in C#

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.