SlideShare a Scribd company logo
Clean Coding Practices for Java Developers




 Clean Coding Practices for Java Developers




                                      John	
  Ferguson	
  Smart
                               john.smart@wakaleo.com
                               	
  h2p://www.wakaleo.com
                                          Twi2er:	
  wakaleo
So who is this guy, anyway?
               Consulta
                       nt
               Trainer
              Mentor
              Author
             Speaker
             Coder
   John Fer
            guson S
                    mar t
Who	
  are	
  you	
  wri;ng	
  code	
  for,	
  anyway?
Who	
  are	
  you	
  wri;ng	
  code	
  for,	
  anyway?




                                The	
  computer?
Who	
  are	
  you	
  wri;ng	
  code	
  for,	
  anyway?




                             Other	
  developers?
Who	
  are	
  you	
  wri;ng	
  code	
  for,	
  anyway?




                                Your	
  next	
  boss?
Clean Coding Practices for Java Developers



        Why	
  is	
  clean	
  code	
  so	
  important?
Easier	
  to	
  Understand




Easier	
  to	
  Change




            Cheaper	
  to	
  Maintain
Choose	
  your	
  names	
  well




"What's in a name? That which we call a rose
  By any other name would smell as sweet."
                 Romeo and Juliet (II, ii, 1-2)
   Really?
Use	
  a	
  common	
  vocabulary

getCustomerInfo()
getClientDetails()
getCustomerRecord()
...
    Which one do I use? Are they the same?



           getCustomer()
                Choose one and stick to it
Use	
  meaningful	
  names

int days;




              What does this represent?


int daysSinceCreation;

 int daysSinceLastModification;

    int durationInDays;

                         These are all more meaningful choices
Don’t	
  talk	
  in	
  code

class DtaRcrd102 {
    private Date genymdhms;
    private Date modymdhms;
    private final String pszqint = “102”;
    ...
}                                     Huh?

class Customer {
  private Date generationTimestamp;
  private Date modificationTimestamp;
  private final String recordId = “102”
  ...
}
But	
  don’t	
  state	
  the	
  obvious

List<Client> clientList;


                        Is ‘List’ significant or just noise?




List<Client> clients;

  List<Client> regularClients;

     List<Client> newClients;
In	
  short:	
  Don’t	
  make	
  me	
  think!
                                                        What does this do?




                                                   Clearer parameter name
More explicit method name


                                                       What are we counting?




 Method call rather than
  boolean expression
Make	
  your	
  code	
  tell	
  a	
  story
High-Level
Methods	
  should	
  be	
  small                                      Refactoring
  public void generateAggregateReportFor(final List<StoryTestResults> storyResults,
                                         final List<FeatureResults> featureResults) throws IOException {
      LOGGER.info("Generating summary report for user stories to "+ getOutputDirectory());

      copyResourcesToOutputDirectory();

      Map<String, Object> storyContext = new HashMap<String, Object>();
      storyContext.put("stories", storyResults);
      storyContext.put("storyContext", "All stories");
      addFormattersToContext(storyContext);
      writeReportToOutputDirectory("stories.html",
                                   mergeTemplate(STORIES_TEMPLATE_PATH).usingContext(storyContext));

      Map<String, Object> featureContext = new HashMap<String, Object>();
      addFormattersToContext(featureContext);
      featureContext.put("features", featureResults);
      writeReportToOutputDirectory("features.html",
                                   mergeTemplate(FEATURES_TEMPLATE_PATH).usingContext(featureContext));

      for(FeatureResults feature : featureResults) {
          generateStoryReportForFeature(feature);
      }

      generateReportHomePage(storyResults, featureResults);


                                          Code hard to understand
      getTestHistory().updateData(featureResults);

      generateHistoryReport();
  }
High-Level
Methods	
  should	
  be	
  small                                       Refactoring
  public void generateAggregateReportFor(final List<StoryTestResults> storyResults,
                                         final List<FeatureResults> featureResults) throws IOException {
      LOGGER.info("Generating summary report for user stories to "+ getOutputDirectory());

       copyResourcesToOutputDirectory();

      private void Object> storyContext = new HashMap<String, Object>(); storyResults) throws IOException {
        Map<String, generateStoriesReport(final List<StoryTestResults>
        storyContext.put("stories", storyResults);
           Map<String, Object> context = new HashMap<String, Object>();
        storyContext.put("storyContext", "All stories");
           context.put("stories", storyResults);
        addFormattersToContext(storyContext); stories");
           context.put("storyContext", "All
        writeReportToOutputDirectory("stories.html",
           addFormattersToContext(context);
                                     mergeTemplate(STORIES_TEMPLATE_PATH).usingContext(storyContext));
           String htmlContents = mergeTemplate(STORIES_TEMPLATE_PATH).usingContext(context);
           writeReportToOutputDirectory("stories.html", htmlContents);
        Map<String, Object> featureContext = new HashMap<String, Object>();
      }
       addFormattersToContext(featureContext);
       featureContext.put("features", featureResults);                Refactor into clear steps
       writeReportToOutputDirectory("features.html",
                                    mergeTemplate(FEATURES_TEMPLATE_PATH).usingContext(featureContext));

       for(FeatureResults feature : featureResults) {
           generateStoryReportForFeature(feature);
       }

       generateReportHomePage(storyResults, featureResults);

       getTestHistory().updateData(featureResults);

       generateHistoryReport();
  }
High-Level
Methods	
  should	
  be	
  small                                     Refactoring
  public void generateAggregateReportFor(final List<StoryTestResults> storyResults,
                                         final List<FeatureResults> featureResults) throws IOException {
      LOGGER.info("Generating summary report for user stories to "+ getOutputDirectory());

      copyResourcesToOutputDirectory();

      generateStoriesReportFor(storyResults);

      Map<String, Object> featureContext = new HashMap<String, Object>();
      addFormattersToContext(featureContext);
      featureContext.put("features", featureResults);
      writeReportToOutputDirectory("features.html",
                                   mergeTemplate(FEATURES_TEMPLATE_PATH).usingContext(featureContext));

      for(FeatureResults feature : featureResults) {
          generateStoryReportForFeature(feature);
      }

      generateReportHomePage(storyResults, featureResults);

      getTestHistory().updateData(featureResults);

                   private void updateHistoryFor(final List<FeatureResults> featureResults) {
      generateHistoryReport();
  }                     getTestHistory().updateData(featureResults);
                   }
High-Level
Methods	
  should	
  be	
  small                         Refactoring

private void generateAggregateReportFor(final List<StoryTestResults> storyResults,
                                        final List<FeatureResults> featureResults)
    throws IOException {

        copyResourcesToOutputDirectory();

        generateStoriesReportFor(storyResults);
        generateFeatureReportFor(featureResults);
        generateReportHomePage(storyResults, featureResults);

        updateHistoryFor(featureResults);
        generateHistoryReport();
}
High-Level Refactoring
   Methods	
  should	
  only	
  do	
  one	
  thing

                                                                    Too much going on here...
public String getReportName(String reportType, final String qualifier) {
    if (qualifier == null) {
        String testName = "";
        if (getUserStory() != null) {
             testName = NameConverter.underscore(getUserStory().getName());
        }
        String scenarioName = NameConverter.underscore(getMethodName());
        testName = withNoIssueNumbers(withNoArguments(appendToIfNotNull(testName, scenarioName)));
        return testName + "." + reportType;
    } else {
        String userStory = "";
        if (getUserStory() != null) {
             userStory = NameConverter.underscore(getUserStory().getName()) + "_";
        }
        String normalizedQualifier = qualifier.replaceAll(" ", "_");
        return userStory + withNoArguments(getMethodName()) + "_" + normalizedQualifier + "." + reportType;
    }
}
                                                                    Mixing what and how
High-Level Refactoring
    Methods	
  should	
  only	
  do	
  one	
  thing

                                                               Chose what to do here
public String getReportName(final ReportType type, final String qualifier) {
    ReportNamer reportNamer = ReportNamer.forReportType(type);
    if (shouldAddQualifier(qualifier)) {
        return reportNamer.getQualifiedTestNameFor(this, qualifier);
    } else {
        return reportNamer.getNormalizedTestNameFor(this);
    }
}



                                     The how is the responsibility of another class
Encapsulate	
  boolean	
  expressions
for (TestStep currentStep : testSteps) {
    if (!currentStep.isAGroup() && currentStep.getScreenshots() != null) {
        for (RecordedScreenshot screenshot : currentStep.getScreenshots()) {
            screenshots.add(new Screenshot(screenshot.getScreenshot().getName(),
                    currentStep.getDescription(),
                    widthOf(screenshot.getScreenshot()),
                    currentStep.getException()));
        }
    }
}



                                                 What does this boolean mean?

for (TestStep currentStep : testSteps) {
    if (currentStep.needsScreenshots()) {
        ...
              public boolean needsScreenshots() {
                  return (!isAGroup() && getScreenshotsAndHtmlSources() != null);
              }




                                                   Expresses the intent better
Avoid	
  unclear/ambiguous	
  class	
  name
         for (TestStep currentStep : testSteps) {
             if (currentStep.needsScreenshots()) {
                 for (RecordedScreenshot screenshot : currentStep.getScreenshots()) {
                     screenshots.add(new Screenshot(screenshot.getScreenshot().getName(),
                             currentStep.getDescription(),
                             widthOf(screenshot.getScreenshot()),
                             currentStep.getException()));
                 }
             }
         }
                                                     Is this class name really accurate?

 public List<Screenshot> getScreenshots() {                           Too many screenshots!
     List<Screenshot> screenshots = new ArrayList<Screenshot>();
     List<TestStep> testSteps = getFlattenedTestSteps();

     for (TestStep currentStep : testSteps) {
         if (weNeedAScreenshotFor(currentStep)) {
             for (ScreenshotAndHtmlSource screenshotAndHtml : currentStep.getScreenshotsAndHtmlSources()) {
                 screenshots.add(new Screenshot(screenshotAndHtml.getScreenshotFile().getName(),
                         currentStep.getDescription(),
                         widthOf(screenshotAndHtml.getScreenshot()),
                         currentStep.getException()));
             }
         }
     }
     return ImmutableList.copyOf(screenshots);
Using a more revealing class name
 }
                                                              And a clearer method name
Encapsulate	
  overly-­‐complex	
  code

public List<Screenshot> getScreenshots() {
    List<Screenshot> screenshots = new ArrayList<Screenshot>();
    List<TestStep> testSteps = getFlattenedTestSteps();

    for (TestStep currentStep : testSteps) {
        if (currentStep.needsScreenshots()) {
            for (ScreenshotAndHtmlSource screenshotAndHtml : currentStep.getScreenshotsAndHtmlSources()) {
                screenshots.add(new Screenshot(screenshotAndHtml.getScreenshot().getName(),
                        currentStep.getDescription(),
                        widthOf(screenshotAndHtml.getScreenshot()),
                        currentStep.getException()));
            }
        }
    }
    return ImmutableList.copyOf(screenshots);
                                                 What does all this do?
}
      public List<Screenshot> getScreenshots() {
          List<Screenshot> screenshots = new ArrayList<Screenshot>();
          List<TestStep> testSteps = getFlattenedTestSteps();

          for (TestStep currentStep : testSteps) {
              if (weNeedAScreenshotFor(currentStep)) {
                  screenshots.addAll(
                      convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep)));
              }
          }

      }
          return ImmutableList.copyOf(screenshots);                          Clearer intention
Encapsulate	
  overly-­‐complex	
  code

public List<Screenshot> getScreenshots() {
    List<Screenshot> screenshots = new ArrayList<Screenshot>();
    List<TestStep> testSteps = getFlattenedTestSteps();

      for (TestStep currentStep : testSteps) {
          if (currentStep.needsScreenshots()) {
              screenshots.addAll(
                  convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep)));
          }
      }
      return ImmutableList.copyOf(screenshots);        What we are doing
}
    private Converter<ScreenshotAndHtmlSource, Screenshot> toScreenshotsFor(final TestStep currentStep) {
        return new Converter<ScreenshotAndHtmlSource, Screenshot>() {
            @Override
            public Screenshot convert(ScreenshotAndHtmlSource from) {
                return new Screenshot(from.getScreenshotFile().getName(),
                                      currentStep.getDescription(),
                                      widthOf(from.getScreenshotFile()),
                                      currentStep.getException());
            }
        };
    }

                                                                               How we do it
Avoid	
  deep	
  nes;ng

public List<Screenshot> getScreenshots() {
    List<Screenshot> screenshots = new ArrayList<Screenshot>();
    List<TestStep> testSteps = getFlattenedTestSteps();

        for (TestStep currentStep : testSteps) {
            if (currentStep.needsScreenshots()) {
                                                               Code doing too many things
                screenshots.addAll(
                    convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep)));
            }
        }
        return ImmutableList.copyOf(screenshots);
}                                                                 Break the code down into
    public List<Screenshot> getScreenshots() {                    logical steps
        List<Screenshot> screenshots = new ArrayList<Screenshot>();

         List<TestStep> testStepsWithScreenshots = select(getFlattenedTestSteps(),
                                                          having(on(TestStep.class).needsScreenshots()));

         for (TestStep currentStep : testStepsWithScreenshots) {
             screenshots.addAll(convert(currentStep.getScreenshotsAndHtmlSources(),
                                        toScreenshotsFor(currentStep)));
         }

         return ImmutableList.copyOf(screenshots);
    }                                                     Remove the nested condition
Keep	
  each	
  step	
  simple!
public List<Screenshot> getScreenshots() {
    List<Screenshot> screenshots = new ArrayList<Screenshot>();

        List<TestStep> testStepsWithScreenshots = select(getFlattenedTestSteps(),
                                                         having(on(TestStep.class).needsScreenshots()));

        for (TestStep currentStep : testStepsWithScreenshots) {
            screenshots.addAll(convert(currentStep.getScreenshotsAndHtmlSources(),
                                       toScreenshotsFor(currentStep)));
        }

        return ImmutableList.copyOf(screenshots);           Too much happening here?
}

    public List<Screenshot> getScreenshots() {
        List<Screenshot> screenshots = new ArrayList<Screenshot>();

          List<TestStep> testStepsWithScreenshots = select(getFlattenedTestSteps(),
                                                           having(on(TestStep.class).needsScreenshots()));

          for (TestStep currentStep : testStepsWithScreenshots) {
              screenshots.addAll(screenshotsIn(currentStep));
          }

          return ImmutableList.copyOf(screenshots);       This reads more smoothly
    }

    private List<Screenshot> screenshotsIn(TestStep currentStep) {
        return convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep));
    }
Code	
  should	
  communicate	
  fluently
Use	
  Fluent	
  APIs


               Complex domain object
                             Lots of variants
                                  Object tree



       FundsTransferOrder order = new FundsTransferOrder();
       order.setType("SWIFT");
       Party originatorParty = organizationServer.findPartyByCode("WPAC");
       order.setOriginatorParty(originatorParty);
       Party counterParty = organizationServer.findPartyByCode("CBAA");
       order.setCounterParty(counterParty);
       order.setDate(DateTime.parse("22/11/2011"));
       Currency currency = currencyTable.findCurrency("USD");
       Amount amount = new Amount(500, currency);
       order.setAmount(amount);
Complex code
       ...


  Need to know how to create the child objects
Use	
  Fluent	
  APIs




                                           More readable
                                               No object creation
                                                   Easier to maintain
FundsTransferOrder.createNewSWIFTOrder()
                                  .fromOriginatorParty("WPAC")
                                  .toCounterParty("CBAA")
                                  .forDebitor("WPAC")
                                  .and().forCreditor("CBAA")
                                  .settledOnThe("22/11/2011")
                                  .forAnAmountOf(500, US_DOLLARS)
                                  .asXML();
Use	
  Fluent	
  APIs


                                         Readable parameter style


TestStatistics testStatistics = testStatisticsProvider.statisticsForTests(With.tag("Boat sales"));

double recentBoatSalePassRate = testStatistics.getPassRate().overTheLast(5).testRuns();




                   Fluent method call
Use	
  Fluent	
  APIs
                             Fluent style...


                        A builder does the
                            dirty work

                           Represents how
                            to select steps

                                Override to
                               select different
                                 step types
Your	
  code	
  is	
  organic




     Help	
  it	
  grow
Replace	
  Constructors	
  with	
  Crea7on	
  Methods




                             Too many constructors
                                Business knowledge
                                hidden in the constructors
                                  Which one should I use?
Replace	
  Constructors	
  with	
  Crea7on	
  Methods




                                   Private constructor




        Static creator methods
          One implementing class
Replace	
  Constructors	
  with	
  Crea7on	
  Methods




                  Communicates	
  the	
  intended	
  use	
  be5er
                  Overcomes	
  technical	
  limits	
  with	
  constructors
                  Inconsistent	
  object	
  crea<on	
  pa5erns
Encapsulate	
  Classes	
  with	
  a	
  Factory
                     High-Level Refactoring
                                           Only this interface should
                                           be visible




Many different
implementations
                          Which implementation
                          should I use?
Encapsulate	
  Classes	
  with	
  a	
  Factory
                                 High-Level Refactoring
                             Helpful factory methods




Easier	
  to	
  create	
  the	
  right	
  instances
Hides	
  classes	
  that	
  don’t	
  need	
  to	
  be	
  exposed
Encourages	
  “programming	
  to	
  an	
  interface”
Need	
  a	
  new	
  method	
  when	
  new	
  classes	
  are	
  added
Need	
  access	
  to	
  factory	
  class	
  to	
  customize/extend
Plenty	
  of	
  other	
  refactoring	
  pa2erns...




                    But	
  know	
  why	
  you	
  are	
  applying	
  them
Learn	
  about	
  Func7onal	
  Programming!
Func;ons	
  as	
  a	
  1st	
  class	
  concept
Immutable	
  value	
  objects
No	
  side	
  effects
Benefit	
  from	
  concurrency
No	
  loops
5050



          A, B, C, D, F



          Parallel processing




       TRUE
Functional programming in Java?




Surely this is
 madness!
lambdaj
– DSL for manipulating collections in a functional style
– Replace loops with more concise and readable code




Functional constructs in Java
LambdaJ support many high level
collection-related functions


 filter                   aggregate


      sort
                       convert


extract        index             group
Find all adult ages                                    filter

            List<Integer> adultAges = new ArrayList<Integer>();
            for(int age : ages) {
                if (age >= 18) {
                    adults.add(age);
                }
            }




List<Integer> adultAges = filter(greaterThanOrEqualTo(18), ages);
Find all adults                                           filter

                List<Person> adults = new ArrayList<Person>();
                for(int person : people) {
                    if (person.getAge() >= 18) {
                        adults.add(person);
                    }
                }




List<Person> adults = filter(having(on(Person.class).getAge(), greaterThanOrEqualTo(18)),
                             people);
Find all the sales of Ferraris                                filter

            List<Sale> salesOfAFerrari = new ArrayList<Sale>();
            for (Sale sale : sales) {
                if (sale.getCar().getBrand().equals("Ferrari"))
                    salesOfAFerrari.add(sale);
            }




List<Sale> salesOfAFerrari = select(sales,
    having(on(Sale.class).getCar().getBrand(),equalTo("Ferrari")));
Sort sales by cost                                       sort

     List<Sale> sortedSales = new ArrayList<Sale>(sales);
     Collections.sort(sortedSales, new Comparator<Sale>() {
         public int compare(Sale s1, Sale s2) {
             return Double.valueOf(s1.getCost()).compareTo(s2.getCost());
         }
     });




List<Sale> sortedSales = sort(sales, on(Sale.class).getCost());
Index cars by brand                                   index


       Map<String, Car> carsByBrand = new HashMap<String, Car>();
       for (Car car : db.getCars()) {
           carsByBrand.put(car.getBrand(), car);
       }




Map<String, Car> carsByBrand = index(cars, on(Car.class).getBrand());
Find the total sales
                                                  aggregate

  double totalSales = 0.0;
  for (Sale sale : sales) {
      totalSales = totalSales + sale.getCost();
  }




      double totalSales = sumFrom(sales).getCost();
Find most costly sale
                                             aggregate

   double maxCost = 0.0;
   for (Sale sale : sales) {
       double cost = sale.getCost();
       if (cost > maxCost) maxCost = cost;
   }




          double maxCost = maxFrom(sales).getCost();
extract
Extract the costs of the cars as a list




      List<Double> costs = new ArrayList<Double>();
      for (Car car : cars) costs.add(car.getCost());




  List<Double> costs = extract(cars, on(Car.class).getCost());
guava immutable collections
guava immutable collections
   Defensive
   Thread-safe
   Efficient
Creating an immutable list

List<String> colors = ImmutableList.of("red", "green", "blue");




  ImmutableSet<Field> fields =
                     ImmutableSet.copyOf(stepLibraryClass.getDeclaredFields());



                                             Creating an immutable copy
The	
  Boy	
  Scout	
  Rule




   “Leave	
  the	
  camp	
  ground	
  cleaner	
  than	
  you	
  found	
  it”
Clean Coding Practices for Java Developers




                Thank You



                                    John	
  Ferguson	
  Smart
                             john.smart@wakaleo.com
                             	
  h2p://www.wakaleo.com
                                        Twi2er:	
  wakaleo

More Related Content

What's hot

Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a Monolith
Victor Rentea
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
Theo Jungeblut
 
The Art of Clean code
The Art of Clean codeThe Art of Clean code
The Art of Clean code
Victor Rentea
 
Clean code
Clean codeClean code
Clean code
Mahmoud Zizo
 
Clean Code
Clean CodeClean Code
Clean Code
swaraj Patil
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
Mattia Battiston
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
Kent Huang
 
Clean Code
Clean CodeClean Code
Clean Code
Victor Rentea
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code Principles
YeurDreamin'
 
Clean code
Clean code Clean code
Clean code
Achintya Kumar
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smells
Paul Nguyen
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
LivePerson
 
Clean code: meaningful Name
Clean code: meaningful NameClean code: meaningful Name
Clean code: meaningful Namenahid035
 
C# conventions & good practices
C# conventions & good practicesC# conventions & good practices
C# conventions & good practices
Tan Tran
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
Duoyi Wu
 
Clean code
Clean codeClean code
Clean code
Duc Nguyen Quang
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
Geshan Manandhar
 
Clean Code
Clean CodeClean Code
Clean Code
Dmytro Turskyi
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
Richard Dingwall
 

What's hot (20)

Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a Monolith
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
The Art of Clean code
The Art of Clean codeThe Art of Clean code
The Art of Clean code
 
Clean code
Clean codeClean code
Clean code
 
Clean Code
Clean CodeClean Code
Clean Code
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Clean Code
Clean CodeClean Code
Clean Code
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code Principles
 
Clean code
Clean code Clean code
Clean code
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smells
 
JavaScript Inheritance
JavaScript InheritanceJavaScript Inheritance
JavaScript Inheritance
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Clean code: meaningful Name
Clean code: meaningful NameClean code: meaningful Name
Clean code: meaningful Name
 
C# conventions & good practices
C# conventions & good practicesC# conventions & good practices
C# conventions & good practices
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Clean code
Clean codeClean code
Clean code
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Clean Code
Clean CodeClean Code
Clean Code
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 

Similar to Clean coding-practices

JavaZone 2014 - goto java;
JavaZone 2014 - goto java;JavaZone 2014 - goto java;
JavaZone 2014 - goto java;
Martin (高馬丁) Skarsaune
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
Ali Parmaksiz
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven DevelopmentAgileOnTheBeach
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
Juan Pablo
 
Rx workshop
Rx workshopRx workshop
Rx workshop
Ryan Riley
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
Iram Ramrajkar
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
Thierry Wasylczenko
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
Tomek Kaczanowski
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
Paco de la Cruz
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
Domenico Briganti
 
Bot builder v4 HOL
Bot builder v4 HOLBot builder v4 HOL
Bot builder v4 HOL
Cheah Eng Soon
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
Jason Lotito
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Anton Arhipov
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
Andres Almiray
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
DataArt
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
Joakim Gustin
 

Similar to Clean coding-practices (20)

JavaZone 2014 - goto java;
JavaZone 2014 - goto java;JavaZone 2014 - goto java;
JavaZone 2014 - goto java;
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven Development
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
 
Bot builder v4 HOL
Bot builder v4 HOLBot builder v4 HOL
Bot builder v4 HOL
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 

More from John Ferguson Smart Limited

My Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosMy Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin Scenarios
John Ferguson Smart Limited
 
Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...
John Ferguson Smart Limited
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
John Ferguson Smart Limited
 
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANTBE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
John Ferguson Smart Limited
 
Sustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplaySustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and Screenplay
John Ferguson Smart Limited
 
Feature Mapping Workshop
Feature Mapping WorkshopFeature Mapping Workshop
Feature Mapping Workshop
John Ferguson Smart Limited
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
John Ferguson Smart Limited
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
John Ferguson Smart Limited
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
John Ferguson Smart Limited
 
Shift left-devoxx-pl
Shift left-devoxx-plShift left-devoxx-pl
Shift left-devoxx-pl
John Ferguson Smart Limited
 
Screenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingScreenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testing
John Ferguson Smart Limited
 
Cucumber and Spock Primer
Cucumber and Spock PrimerCucumber and Spock Primer
Cucumber and Spock Primer
John Ferguson Smart Limited
 
All the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesAll the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practices
John Ferguson Smart Limited
 
CukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning WorkshopCukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning Workshop
John Ferguson Smart Limited
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
John Ferguson Smart Limited
 
Serenity and the Journey Pattern
Serenity and the Journey PatternSerenity and the Journey Pattern
Serenity and the Journey Pattern
John Ferguson Smart Limited
 
BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!
John Ferguson Smart Limited
 
BDD-Driven Microservices
BDD-Driven MicroservicesBDD-Driven Microservices
BDD-Driven Microservices
John Ferguson Smart Limited
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
John Ferguson Smart Limited
 
It's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersIt's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for Testers
John Ferguson Smart Limited
 

More from John Ferguson Smart Limited (20)

My Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosMy Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin Scenarios
 
Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
 
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANTBE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
 
Sustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplaySustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and Screenplay
 
Feature Mapping Workshop
Feature Mapping WorkshopFeature Mapping Workshop
Feature Mapping Workshop
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
 
Shift left-devoxx-pl
Shift left-devoxx-plShift left-devoxx-pl
Shift left-devoxx-pl
 
Screenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingScreenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testing
 
Cucumber and Spock Primer
Cucumber and Spock PrimerCucumber and Spock Primer
Cucumber and Spock Primer
 
All the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesAll the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practices
 
CukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning WorkshopCukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning Workshop
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
Serenity and the Journey Pattern
Serenity and the Journey PatternSerenity and the Journey Pattern
Serenity and the Journey Pattern
 
BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!
 
BDD-Driven Microservices
BDD-Driven MicroservicesBDD-Driven Microservices
BDD-Driven Microservices
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
It's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersIt's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for Testers
 

Recently uploaded

From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 

Recently uploaded (20)

From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 

Clean coding-practices

  • 1. Clean Coding Practices for Java Developers Clean Coding Practices for Java Developers John  Ferguson  Smart john.smart@wakaleo.com  h2p://www.wakaleo.com Twi2er:  wakaleo
  • 2. So who is this guy, anyway? Consulta nt Trainer Mentor Author Speaker Coder John Fer guson S mar t
  • 3. Who  are  you  wri;ng  code  for,  anyway?
  • 4. Who  are  you  wri;ng  code  for,  anyway? The  computer?
  • 5. Who  are  you  wri;ng  code  for,  anyway? Other  developers?
  • 6. Who  are  you  wri;ng  code  for,  anyway? Your  next  boss?
  • 7. Clean Coding Practices for Java Developers Why  is  clean  code  so  important?
  • 8. Easier  to  Understand Easier  to  Change Cheaper  to  Maintain
  • 9. Choose  your  names  well "What's in a name? That which we call a rose By any other name would smell as sweet." Romeo and Juliet (II, ii, 1-2) Really?
  • 10. Use  a  common  vocabulary getCustomerInfo() getClientDetails() getCustomerRecord() ... Which one do I use? Are they the same? getCustomer() Choose one and stick to it
  • 11. Use  meaningful  names int days; What does this represent? int daysSinceCreation; int daysSinceLastModification; int durationInDays; These are all more meaningful choices
  • 12. Don’t  talk  in  code class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = “102”; ... } Huh? class Customer { private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = “102” ... }
  • 13. But  don’t  state  the  obvious List<Client> clientList; Is ‘List’ significant or just noise? List<Client> clients; List<Client> regularClients; List<Client> newClients;
  • 14. In  short:  Don’t  make  me  think! What does this do? Clearer parameter name More explicit method name What are we counting? Method call rather than boolean expression
  • 15. Make  your  code  tell  a  story
  • 16. High-Level Methods  should  be  small Refactoring public void generateAggregateReportFor(final List<StoryTestResults> storyResults, final List<FeatureResults> featureResults) throws IOException { LOGGER.info("Generating summary report for user stories to "+ getOutputDirectory()); copyResourcesToOutputDirectory(); Map<String, Object> storyContext = new HashMap<String, Object>(); storyContext.put("stories", storyResults); storyContext.put("storyContext", "All stories"); addFormattersToContext(storyContext); writeReportToOutputDirectory("stories.html", mergeTemplate(STORIES_TEMPLATE_PATH).usingContext(storyContext)); Map<String, Object> featureContext = new HashMap<String, Object>(); addFormattersToContext(featureContext); featureContext.put("features", featureResults); writeReportToOutputDirectory("features.html", mergeTemplate(FEATURES_TEMPLATE_PATH).usingContext(featureContext)); for(FeatureResults feature : featureResults) { generateStoryReportForFeature(feature); } generateReportHomePage(storyResults, featureResults); Code hard to understand getTestHistory().updateData(featureResults); generateHistoryReport(); }
  • 17. High-Level Methods  should  be  small Refactoring public void generateAggregateReportFor(final List<StoryTestResults> storyResults, final List<FeatureResults> featureResults) throws IOException { LOGGER.info("Generating summary report for user stories to "+ getOutputDirectory()); copyResourcesToOutputDirectory(); private void Object> storyContext = new HashMap<String, Object>(); storyResults) throws IOException { Map<String, generateStoriesReport(final List<StoryTestResults> storyContext.put("stories", storyResults); Map<String, Object> context = new HashMap<String, Object>(); storyContext.put("storyContext", "All stories"); context.put("stories", storyResults); addFormattersToContext(storyContext); stories"); context.put("storyContext", "All writeReportToOutputDirectory("stories.html", addFormattersToContext(context); mergeTemplate(STORIES_TEMPLATE_PATH).usingContext(storyContext)); String htmlContents = mergeTemplate(STORIES_TEMPLATE_PATH).usingContext(context); writeReportToOutputDirectory("stories.html", htmlContents); Map<String, Object> featureContext = new HashMap<String, Object>(); } addFormattersToContext(featureContext); featureContext.put("features", featureResults); Refactor into clear steps writeReportToOutputDirectory("features.html", mergeTemplate(FEATURES_TEMPLATE_PATH).usingContext(featureContext)); for(FeatureResults feature : featureResults) { generateStoryReportForFeature(feature); } generateReportHomePage(storyResults, featureResults); getTestHistory().updateData(featureResults); generateHistoryReport(); }
  • 18. High-Level Methods  should  be  small Refactoring public void generateAggregateReportFor(final List<StoryTestResults> storyResults, final List<FeatureResults> featureResults) throws IOException { LOGGER.info("Generating summary report for user stories to "+ getOutputDirectory()); copyResourcesToOutputDirectory(); generateStoriesReportFor(storyResults); Map<String, Object> featureContext = new HashMap<String, Object>(); addFormattersToContext(featureContext); featureContext.put("features", featureResults); writeReportToOutputDirectory("features.html", mergeTemplate(FEATURES_TEMPLATE_PATH).usingContext(featureContext)); for(FeatureResults feature : featureResults) { generateStoryReportForFeature(feature); } generateReportHomePage(storyResults, featureResults); getTestHistory().updateData(featureResults); private void updateHistoryFor(final List<FeatureResults> featureResults) { generateHistoryReport(); } getTestHistory().updateData(featureResults); }
  • 19. High-Level Methods  should  be  small Refactoring private void generateAggregateReportFor(final List<StoryTestResults> storyResults, final List<FeatureResults> featureResults) throws IOException { copyResourcesToOutputDirectory(); generateStoriesReportFor(storyResults); generateFeatureReportFor(featureResults); generateReportHomePage(storyResults, featureResults); updateHistoryFor(featureResults); generateHistoryReport(); }
  • 20. High-Level Refactoring Methods  should  only  do  one  thing Too much going on here... public String getReportName(String reportType, final String qualifier) { if (qualifier == null) { String testName = ""; if (getUserStory() != null) { testName = NameConverter.underscore(getUserStory().getName()); } String scenarioName = NameConverter.underscore(getMethodName()); testName = withNoIssueNumbers(withNoArguments(appendToIfNotNull(testName, scenarioName))); return testName + "." + reportType; } else { String userStory = ""; if (getUserStory() != null) { userStory = NameConverter.underscore(getUserStory().getName()) + "_"; } String normalizedQualifier = qualifier.replaceAll(" ", "_"); return userStory + withNoArguments(getMethodName()) + "_" + normalizedQualifier + "." + reportType; } } Mixing what and how
  • 21. High-Level Refactoring Methods  should  only  do  one  thing Chose what to do here public String getReportName(final ReportType type, final String qualifier) { ReportNamer reportNamer = ReportNamer.forReportType(type); if (shouldAddQualifier(qualifier)) { return reportNamer.getQualifiedTestNameFor(this, qualifier); } else { return reportNamer.getNormalizedTestNameFor(this); } } The how is the responsibility of another class
  • 22. Encapsulate  boolean  expressions for (TestStep currentStep : testSteps) { if (!currentStep.isAGroup() && currentStep.getScreenshots() != null) { for (RecordedScreenshot screenshot : currentStep.getScreenshots()) { screenshots.add(new Screenshot(screenshot.getScreenshot().getName(), currentStep.getDescription(), widthOf(screenshot.getScreenshot()), currentStep.getException())); } } } What does this boolean mean? for (TestStep currentStep : testSteps) { if (currentStep.needsScreenshots()) { ... public boolean needsScreenshots() { return (!isAGroup() && getScreenshotsAndHtmlSources() != null); } Expresses the intent better
  • 23. Avoid  unclear/ambiguous  class  name for (TestStep currentStep : testSteps) { if (currentStep.needsScreenshots()) { for (RecordedScreenshot screenshot : currentStep.getScreenshots()) { screenshots.add(new Screenshot(screenshot.getScreenshot().getName(), currentStep.getDescription(), widthOf(screenshot.getScreenshot()), currentStep.getException())); } } } Is this class name really accurate? public List<Screenshot> getScreenshots() { Too many screenshots! List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testSteps = getFlattenedTestSteps(); for (TestStep currentStep : testSteps) { if (weNeedAScreenshotFor(currentStep)) { for (ScreenshotAndHtmlSource screenshotAndHtml : currentStep.getScreenshotsAndHtmlSources()) { screenshots.add(new Screenshot(screenshotAndHtml.getScreenshotFile().getName(), currentStep.getDescription(), widthOf(screenshotAndHtml.getScreenshot()), currentStep.getException())); } } } return ImmutableList.copyOf(screenshots); Using a more revealing class name } And a clearer method name
  • 24. Encapsulate  overly-­‐complex  code public List<Screenshot> getScreenshots() { List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testSteps = getFlattenedTestSteps(); for (TestStep currentStep : testSteps) { if (currentStep.needsScreenshots()) { for (ScreenshotAndHtmlSource screenshotAndHtml : currentStep.getScreenshotsAndHtmlSources()) { screenshots.add(new Screenshot(screenshotAndHtml.getScreenshot().getName(), currentStep.getDescription(), widthOf(screenshotAndHtml.getScreenshot()), currentStep.getException())); } } } return ImmutableList.copyOf(screenshots); What does all this do? } public List<Screenshot> getScreenshots() { List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testSteps = getFlattenedTestSteps(); for (TestStep currentStep : testSteps) { if (weNeedAScreenshotFor(currentStep)) { screenshots.addAll( convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep))); } } } return ImmutableList.copyOf(screenshots); Clearer intention
  • 25. Encapsulate  overly-­‐complex  code public List<Screenshot> getScreenshots() { List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testSteps = getFlattenedTestSteps(); for (TestStep currentStep : testSteps) { if (currentStep.needsScreenshots()) { screenshots.addAll( convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep))); } } return ImmutableList.copyOf(screenshots); What we are doing } private Converter<ScreenshotAndHtmlSource, Screenshot> toScreenshotsFor(final TestStep currentStep) { return new Converter<ScreenshotAndHtmlSource, Screenshot>() { @Override public Screenshot convert(ScreenshotAndHtmlSource from) { return new Screenshot(from.getScreenshotFile().getName(), currentStep.getDescription(), widthOf(from.getScreenshotFile()), currentStep.getException()); } }; } How we do it
  • 26. Avoid  deep  nes;ng public List<Screenshot> getScreenshots() { List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testSteps = getFlattenedTestSteps(); for (TestStep currentStep : testSteps) { if (currentStep.needsScreenshots()) { Code doing too many things screenshots.addAll( convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep))); } } return ImmutableList.copyOf(screenshots); } Break the code down into public List<Screenshot> getScreenshots() { logical steps List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testStepsWithScreenshots = select(getFlattenedTestSteps(), having(on(TestStep.class).needsScreenshots())); for (TestStep currentStep : testStepsWithScreenshots) { screenshots.addAll(convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep))); } return ImmutableList.copyOf(screenshots); } Remove the nested condition
  • 27. Keep  each  step  simple! public List<Screenshot> getScreenshots() { List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testStepsWithScreenshots = select(getFlattenedTestSteps(), having(on(TestStep.class).needsScreenshots())); for (TestStep currentStep : testStepsWithScreenshots) { screenshots.addAll(convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep))); } return ImmutableList.copyOf(screenshots); Too much happening here? } public List<Screenshot> getScreenshots() { List<Screenshot> screenshots = new ArrayList<Screenshot>(); List<TestStep> testStepsWithScreenshots = select(getFlattenedTestSteps(), having(on(TestStep.class).needsScreenshots())); for (TestStep currentStep : testStepsWithScreenshots) { screenshots.addAll(screenshotsIn(currentStep)); } return ImmutableList.copyOf(screenshots); This reads more smoothly } private List<Screenshot> screenshotsIn(TestStep currentStep) { return convert(currentStep.getScreenshotsAndHtmlSources(), toScreenshotsFor(currentStep)); }
  • 29. Use  Fluent  APIs Complex domain object Lots of variants Object tree FundsTransferOrder order = new FundsTransferOrder(); order.setType("SWIFT"); Party originatorParty = organizationServer.findPartyByCode("WPAC"); order.setOriginatorParty(originatorParty); Party counterParty = organizationServer.findPartyByCode("CBAA"); order.setCounterParty(counterParty); order.setDate(DateTime.parse("22/11/2011")); Currency currency = currencyTable.findCurrency("USD"); Amount amount = new Amount(500, currency); order.setAmount(amount); Complex code ... Need to know how to create the child objects
  • 30. Use  Fluent  APIs More readable No object creation Easier to maintain FundsTransferOrder.createNewSWIFTOrder() .fromOriginatorParty("WPAC") .toCounterParty("CBAA") .forDebitor("WPAC") .and().forCreditor("CBAA") .settledOnThe("22/11/2011") .forAnAmountOf(500, US_DOLLARS) .asXML();
  • 31. Use  Fluent  APIs Readable parameter style TestStatistics testStatistics = testStatisticsProvider.statisticsForTests(With.tag("Boat sales")); double recentBoatSalePassRate = testStatistics.getPassRate().overTheLast(5).testRuns(); Fluent method call
  • 32. Use  Fluent  APIs Fluent style... A builder does the dirty work Represents how to select steps Override to select different step types
  • 33. Your  code  is  organic Help  it  grow
  • 34. Replace  Constructors  with  Crea7on  Methods Too many constructors Business knowledge hidden in the constructors Which one should I use?
  • 35. Replace  Constructors  with  Crea7on  Methods Private constructor Static creator methods One implementing class
  • 36. Replace  Constructors  with  Crea7on  Methods Communicates  the  intended  use  be5er Overcomes  technical  limits  with  constructors Inconsistent  object  crea<on  pa5erns
  • 37. Encapsulate  Classes  with  a  Factory High-Level Refactoring Only this interface should be visible Many different implementations Which implementation should I use?
  • 38. Encapsulate  Classes  with  a  Factory High-Level Refactoring Helpful factory methods Easier  to  create  the  right  instances Hides  classes  that  don’t  need  to  be  exposed Encourages  “programming  to  an  interface” Need  a  new  method  when  new  classes  are  added Need  access  to  factory  class  to  customize/extend
  • 39. Plenty  of  other  refactoring  pa2erns... But  know  why  you  are  applying  them
  • 40. Learn  about  Func7onal  Programming!
  • 41. Func;ons  as  a  1st  class  concept
  • 46. 5050 A, B, C, D, F Parallel processing TRUE
  • 47. Functional programming in Java? Surely this is madness!
  • 48. lambdaj – DSL for manipulating collections in a functional style – Replace loops with more concise and readable code Functional constructs in Java
  • 49. LambdaJ support many high level collection-related functions filter aggregate sort convert extract index group
  • 50. Find all adult ages filter List<Integer> adultAges = new ArrayList<Integer>(); for(int age : ages) { if (age >= 18) { adults.add(age); } } List<Integer> adultAges = filter(greaterThanOrEqualTo(18), ages);
  • 51. Find all adults filter List<Person> adults = new ArrayList<Person>(); for(int person : people) { if (person.getAge() >= 18) { adults.add(person); } } List<Person> adults = filter(having(on(Person.class).getAge(), greaterThanOrEqualTo(18)), people);
  • 52. Find all the sales of Ferraris filter List<Sale> salesOfAFerrari = new ArrayList<Sale>(); for (Sale sale : sales) {     if (sale.getCar().getBrand().equals("Ferrari"))         salesOfAFerrari.add(sale); } List<Sale> salesOfAFerrari = select(sales, having(on(Sale.class).getCar().getBrand(),equalTo("Ferrari")));
  • 53. Sort sales by cost sort List<Sale> sortedSales = new ArrayList<Sale>(sales); Collections.sort(sortedSales, new Comparator<Sale>() {     public int compare(Sale s1, Sale s2) {         return Double.valueOf(s1.getCost()).compareTo(s2.getCost());     } }); List<Sale> sortedSales = sort(sales, on(Sale.class).getCost());
  • 54. Index cars by brand index Map<String, Car> carsByBrand = new HashMap<String, Car>(); for (Car car : db.getCars()) {     carsByBrand.put(car.getBrand(), car); } Map<String, Car> carsByBrand = index(cars, on(Car.class).getBrand());
  • 55. Find the total sales aggregate double totalSales = 0.0; for (Sale sale : sales) {     totalSales = totalSales + sale.getCost(); } double totalSales = sumFrom(sales).getCost();
  • 56. Find most costly sale aggregate double maxCost = 0.0; for (Sale sale : sales) {     double cost = sale.getCost();     if (cost > maxCost) maxCost = cost; } double maxCost = maxFrom(sales).getCost();
  • 57. extract Extract the costs of the cars as a list List<Double> costs = new ArrayList<Double>(); for (Car car : cars) costs.add(car.getCost()); List<Double> costs = extract(cars, on(Car.class).getCost());
  • 59. guava immutable collections Defensive Thread-safe Efficient
  • 60. Creating an immutable list List<String> colors = ImmutableList.of("red", "green", "blue"); ImmutableSet<Field> fields = ImmutableSet.copyOf(stepLibraryClass.getDeclaredFields()); Creating an immutable copy
  • 61. The  Boy  Scout  Rule “Leave  the  camp  ground  cleaner  than  you  found  it”
  • 62. Clean Coding Practices for Java Developers Thank You John  Ferguson  Smart john.smart@wakaleo.com  h2p://www.wakaleo.com Twi2er:  wakaleo