Software CraftsmanshipMeeting #2http://www.flickr.com/photos/renfield/17375998/in/set-388814/
AgendaBad Code / Good CodeCode SmellsToolsHands OnCode DojoIdentifying Smells *
WTF    publicstaticbooleanisValidNumber(Integer number) {methodName = "isValidNumber";        Logger logger = LoggingHelper.getLogger(LOGGER);logger.entering (CLASS, methodName);        // parse this number. If you get an NFE, then its         // not valid, return falsetry {Integer.parseInt(number.toString());        } catch(Exception ex) {logger.fine(methodName + " returns false");logger.fine("Number Format Exception when parsing");            return false;         }logger.fine(methodName + " returns true");logger.exiting(CLASS, methodName);         return true;          }Logging EntryWTF?Logging Exit
WTFwhile(true){if(mainType == 7)    {subType = 4;break;    }if(mainType == 9)    {subType = 6;break;    }if(mainType == 11)    {subType = 9;break;    }break;}/*=============checkSizeMake sure the image is a power of 2.=============*/intcheckSize(int x) {if (x == 2 || x == 4 || x == 8 || x == 16 || x == 32 || x == 64 || x == 128 || x == 256 || x == 512)return 1;elsereturn 0;}WTF?WTF?
WTFDirectoryInfo dir = new DirectoryInfo(pathToDelete);// subDirsDirectoryInfo[] subDirs = dir.GetDirectories();foreach(DirectoryInfosubDirinsubDirs){  // subSubDirsDirectoryInfo[] subSubDirs = subDir.GetDirectories();foreach(DirectoryInfosubSubDir in subSubDirs)  {    // subSubSubDirsDirectoryInfo[] subSubSubDirs = subSubDir.GetDirectories();foreach(DirectoryInfosubSubSubDirinsubSubSubDirs)    {      // subSubSubSubDirsDirectoryInfo[] subSubSubSubDirs = subSubSubDir.GetDirectories();foreach(DirectoryInfosubSubSubSubDirinsubSubSubSubDirs)      {        // ********************************************        // should be enough; if not, I can add more here        // ********************************************WTF?WTF?
Code Smellhttp://www.flickr.com/photos/brian-fitzgerald/3334353375/http://www.flickr.com/photos/yomi955/1192827822/Code Smell - In computer programming, code smell is any symptom in the source code of a program that possibly indicates a deeper problemhttp://en.wikipedia.org/wiki/Code_smell
Code SmellsDuplicated CodeSame code structure in more than one place:Same expression in two methods of the same classSame expression in two sibling subclassesSame expression in two unrelated classes
Code Smells
DemoClone Detector
Code SmellsLong MethodA good technique is to look for comments. They often signal a semantic distance between the intension of the code and the implementation of the codeThe net effect is that you should be much more aggressive about decomposing methodsThe desired length should be 5-8 lines
Code Smells
DemoComments, please!
Code SmellsLarge ClassMany instance variables indicates that a class tries to do too muchMany instance variables can indicate a duplicate codeToo much code is prime breeding ground for duplicated code, chaos, and death
Code Smells
DemoHow Many Lines?
Code SmellsLong Parameter ListIn the past we passed in as parameters everything needed by a routine. With objects it’s not required; instead enough parameters passed in to the method in order to allow it to get everything rest it needsLong parameter lists are hard to understandLong parameter lists inconsistent and difficult to useLong parameter lists are forever changed as more data is required
Code Smells
Code SmellsLong Parameter ListAvoid output parameters (ref, out)Avoid boolean argumentsAvoid more than 3 arguments2 is preferable1 is better0 is the bestIntroduce Parameter ObjectRefactoring StepSeparate Query From ModifierRefactoring StepOne return value.
DemoTo Query or To Modify?
Code SmellsSwitch StatementsThe problem with switch statements is essentially that of duplication i.e. the same switch statement scattered about a program in different placesMost times you see a switch statement you should consider polymorphism
Code Smells
DemoHow to Process Request
Code SmellsSpeculative GeneralityA class that exists to support some future and imaginary feature.“We might need this one day …”If you really do need it later, you can add it easily using Refactoring.It doesn’t mean you don’t need to anticipate requirements and features.
Code SmellsCommentsWhen you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous
Code SmellsFeature EnvoyA method that seems more interested in a class other than the one it actually is inData and the behavior that references that data usually change together, but there are exceptions:VisitorStrategy
Code Smells
Code SmellsMessage ChainsA client asks one object for another object, which the client then asks for yet another object, which the client then asks for yet another another object, and so onCan be seen as a long line of GetThis() methods, or as a sequence of tempsAny change to the intermediate relationships causes the client to have to changeAccount.Owner.OwnerDetails.Address.Zip
Hands OnDojoCode Smellshttp://www.flickr.com/photos/renfield/351556388/in/photostream/
Roman Numbers: ToString()0NullaNumerals
Roman Numbers: ToString()IThe values of each roman letter can be additiveIIThe larger numerals must be placed to the left of the smaller numeralsIIIAt the fourth iteration, a subtractive principle may beemployed, with the base placed before the higher base:IIII or IV The subtracted digit must be at least one tenth of thevalue of the larger numeral. Therefore: 99 isn’t IC butrather XCIX
2nd Meeting of the Software Craftsmanship Grouphttp://www.flickr.com/photos/psd/2086641/

Software Craftsmanship - 2

  • 1.
  • 2.
    AgendaBad Code /Good CodeCode SmellsToolsHands OnCode DojoIdentifying Smells *
  • 3.
    WTF publicstaticbooleanisValidNumber(Integer number) {methodName = "isValidNumber"; Logger logger = LoggingHelper.getLogger(LOGGER);logger.entering (CLASS, methodName); // parse this number. If you get an NFE, then its // not valid, return falsetry {Integer.parseInt(number.toString()); } catch(Exception ex) {logger.fine(methodName + " returns false");logger.fine("Number Format Exception when parsing"); return false; }logger.fine(methodName + " returns true");logger.exiting(CLASS, methodName); return true; }Logging EntryWTF?Logging Exit
  • 4.
    WTFwhile(true){if(mainType == 7) {subType = 4;break; }if(mainType == 9) {subType = 6;break; }if(mainType == 11) {subType = 9;break; }break;}/*=============checkSizeMake sure the image is a power of 2.=============*/intcheckSize(int x) {if (x == 2 || x == 4 || x == 8 || x == 16 || x == 32 || x == 64 || x == 128 || x == 256 || x == 512)return 1;elsereturn 0;}WTF?WTF?
  • 5.
    WTFDirectoryInfo dir =new DirectoryInfo(pathToDelete);// subDirsDirectoryInfo[] subDirs = dir.GetDirectories();foreach(DirectoryInfosubDirinsubDirs){ // subSubDirsDirectoryInfo[] subSubDirs = subDir.GetDirectories();foreach(DirectoryInfosubSubDir in subSubDirs) { // subSubSubDirsDirectoryInfo[] subSubSubDirs = subSubDir.GetDirectories();foreach(DirectoryInfosubSubSubDirinsubSubSubDirs) { // subSubSubSubDirsDirectoryInfo[] subSubSubSubDirs = subSubSubDir.GetDirectories();foreach(DirectoryInfosubSubSubSubDirinsubSubSubSubDirs) { // ******************************************** // should be enough; if not, I can add more here // ********************************************WTF?WTF?
  • 6.
    Code Smellhttp://www.flickr.com/photos/brian-fitzgerald/3334353375/http://www.flickr.com/photos/yomi955/1192827822/Code Smell- In computer programming, code smell is any symptom in the source code of a program that possibly indicates a deeper problemhttp://en.wikipedia.org/wiki/Code_smell
  • 7.
    Code SmellsDuplicated CodeSamecode structure in more than one place:Same expression in two methods of the same classSame expression in two sibling subclassesSame expression in two unrelated classes
  • 8.
  • 9.
  • 10.
    Code SmellsLong MethodAgood technique is to look for comments. They often signal a semantic distance between the intension of the code and the implementation of the codeThe net effect is that you should be much more aggressive about decomposing methodsThe desired length should be 5-8 lines
  • 11.
  • 12.
  • 13.
    Code SmellsLarge ClassManyinstance variables indicates that a class tries to do too muchMany instance variables can indicate a duplicate codeToo much code is prime breeding ground for duplicated code, chaos, and death
  • 14.
  • 15.
  • 16.
    Code SmellsLong ParameterListIn the past we passed in as parameters everything needed by a routine. With objects it’s not required; instead enough parameters passed in to the method in order to allow it to get everything rest it needsLong parameter lists are hard to understandLong parameter lists inconsistent and difficult to useLong parameter lists are forever changed as more data is required
  • 17.
  • 18.
    Code SmellsLong ParameterListAvoid output parameters (ref, out)Avoid boolean argumentsAvoid more than 3 arguments2 is preferable1 is better0 is the bestIntroduce Parameter ObjectRefactoring StepSeparate Query From ModifierRefactoring StepOne return value.
  • 19.
    DemoTo Query orTo Modify?
  • 20.
    Code SmellsSwitch StatementsTheproblem with switch statements is essentially that of duplication i.e. the same switch statement scattered about a program in different placesMost times you see a switch statement you should consider polymorphism
  • 21.
  • 22.
  • 23.
    Code SmellsSpeculative GeneralityAclass that exists to support some future and imaginary feature.“We might need this one day …”If you really do need it later, you can add it easily using Refactoring.It doesn’t mean you don’t need to anticipate requirements and features.
  • 24.
    Code SmellsCommentsWhen youfeel the need to write a comment, first try to refactor the code so that any comment becomes superfluous
  • 25.
    Code SmellsFeature EnvoyAmethod that seems more interested in a class other than the one it actually is inData and the behavior that references that data usually change together, but there are exceptions:VisitorStrategy
  • 26.
  • 27.
    Code SmellsMessage ChainsAclient asks one object for another object, which the client then asks for yet another object, which the client then asks for yet another another object, and so onCan be seen as a long line of GetThis() methods, or as a sequence of tempsAny change to the intermediate relationships causes the client to have to changeAccount.Owner.OwnerDetails.Address.Zip
  • 28.
  • 29.
  • 30.
    Roman Numbers: ToString()IThevalues of each roman letter can be additiveIIThe larger numerals must be placed to the left of the smaller numeralsIIIAt the fourth iteration, a subtractive principle may beemployed, with the base placed before the higher base:IIII or IV The subtracted digit must be at least one tenth of thevalue of the larger numeral. Therefore: 99 isn’t IC butrather XCIX
  • 31.
    2nd Meeting ofthe Software Craftsmanship Grouphttp://www.flickr.com/photos/psd/2086641/

Editor's Notes

  • #4 CMMI 5Complicated? Smart Ass?
  • #5 WHY?
  • #8 Duplicated Logic on a “Page” or “Code Behind”
  • #10 Examples:Execute similarities (CloneDetector) on the BlogEngine:DbRoleProvider, DbBlogProvider, DbMembershipProvider – Initialize method – 99% is duplicated. Also, Category and Post are duplicated on Title and Description, although they inherit from BusinessBase.Tools:http://www.getatomiq.com/overview/http://www.redhillconsulting.com.au/products/simian/http://clonedigger.sourceforge.net/
  • #11 Decomposition (valid reasons to create a method):Reduce ComplexityIndirectionRemove Duplicate CodeSupport SubclassingHide SequencesSimplify Complicated Boolean Tests
  • #13 Examples:BlogEngine.Core.Providers.XmlProvider. XMLBlogProvider.Posts.SelectPost – a huge methods with a lot of responsibilities.CardGame.BlackJackGame.DealNewGame – proves the newspaper paradigm
  • #16 Examples:BlogEngine.Core.Providers.BlogProvider – violates SR Principle and also defines a lot of different methods, has more than 200 lines.BlogEngine.Core.SyndicationGenerator – has more than 900 lines.BlogEngine.Core.API.MetaWeblog.MetaWeblogHandler – has more than 700 lines, most of the functions are private.
  • #20 Examples:- Method receiving booleanarg: CardGame.Card. The constructor Card takes a boolean argument, specifying whether the card is up or not. This is hard to read!!!- BlogEngine.Core.API.MetaWeblog.MetaWeBlogHandler.LookupCategoryGuidByName: Does 2 things: Returns whether found and returns the Category
  • #22 Refactor the MovieRent’s Rent and Movie classes to use State Pattern
  • #23 Examples:- BlogEngine.Core.API.MetaWebBlogHandler.ProcessRequest : A huge switch case.