Clean
 Code
Yukti Kaura
Use pronounceable names
class DtaRcrd102
 class DtaRcrd102         class Customer
                           class Customer
class InchToPointConvertor {
 class InchToPointConvertor {
    //convert the quantity in inches to points.
     //convert the quantity in inches to points.
    static float parseInch(float inch) {
     static float parseInch(float inch) {
       return inch * 72; //one inch contains 72
        return inch * 72; //one inch contains 72
points.
 points.
    }}
 }}



class InchToPointConvertor {
 class InchToPointConvertor {

      final static int POINTS_PER_INCH=72;
       final static int POINTS_PER_INCH=72;

      static float convertToPoints(float inch) {
       static float convertToPoints(float inch) {
         return inch * POINTS_PER_INCH;
          return inch * POINTS_PER_INCH;
      }}
 }}
class Account {
                     class Account {
                        //check if the password is complex enough, i.e.,
                         //check if the password is complex enough, i.e.,
                        //contains letter and digit/symbol.
                         //contains letter and digit/symbol.
                        boolean isComplexPassword(String password) {{
                         boolean isComplexPassword(String password)
                           //found aa digit or symbol?
                            //found    digit or symbol?
                           boolean dg_sym_found=false;
                            boolean dg_sym_found=false;
                           //found aa letter?
                            //found    letter?
                           boolean letter_found=false;
                            boolean letter_found=false;
                           for(int i=0; i<password.length(); i++){
                            for(int i=0; i<password.length(); i++){
                              char c=password.charAt(i);
                               char c=password.charAt(i);
                              if(Character.isLowerCase(c)||Character.isUpperCase(c))
                               if(Character.isLowerCase(c)||Character.isUpperCase(c))
                                letter_found=true;
                                 letter_found=true;
                              else dg_sym_found=true;
                               else dg_sym_found=true;
                           }}
                           return (letter_found) && (dg_sym_found);
                            return (letter_found) && (dg_sym_found);
                        }}
                     }}
class Account {
 class Account {
   boolean isComplexPassword(String password){
    boolean isComplexPassword(String password){
      return containsLetter(password) &&
       return containsLetter(password) &&
      (containsDigit(password) ||
       (containsDigit(password) ||
            containsSymbol(password));
             containsSymbol(password));
   }}
   boolean containsLetter(String password) {{
    boolean containsLetter(String password)
      return false;
       return false;
   }}
   boolean containsDigit(String password) {{
    boolean containsDigit(String password)
      return false;
       return false;
   }}
   boolean containsSymbol(String password) {{
    boolean containsSymbol(String password)
      return false;
       return false;
   }}
Goal of OOAD:
Identify the classes and relations between them for a given
problem.

Read the problem statement carefully and identify:
• Nouns (Classes)
• Verbs (Behavior)
• Actors (Users)


Identify relationships between classes
• Is-A (Generalization / Inheritance)
• Has-A (Composition)
• Uses (Dependency)
A basket contains oranges                                    11
                                              Basket
                                               Basket
and apples.

                                                                                **             **
                                                                      Apple
                                                                       Apple            Orange
                                                                                         Orange



                                         11             **
 Fruits have cost           Basket
                             Basket                                Fruit
                                                                    Fruit
                                                                  int Price;
                                                                   int Price;




                                      Apple
                                       Apple                                         Orange
                                                                                      Orange


                               Generalize to accommodate new requirements.
                                Generalize to accommodate new requirements.
Slide 34
A user has password. Password can be encrypted and decrypted.

                        11   11
        User
         User                        Password
                                      Password
                                  public String encrypt();
                                   public String encrypt();
     String userid;
      String userid;              public String decrypt();
                                   public String decrypt();




 Password is encrypted using a encryption service.

                        11   11
           User
            User                       Password
                                        Password               EncryptionService
                                                                EncryptionService
                                   public String encrypt();
                                    public String encrypt();   public String encrypt(String);
                                                                public String encrypt(String);
      String userid;
       String userid;              public String decrypt();
                                    public String decrypt();   public String decrypt(String);
                                                                public String decrypt(String);




Slide 35
Class should have one and only one reason to change.


           Rectangle
            Rectangle                                        Rectangle
                                                              Rectangle
                                                            Point topLeftCorner
                                                              Point topLeftCorner
             public draw()
              public draw()
                                                          Point bottomRightCorner
                                                           Point bottomRightCorner
             public area()
              public area()



     Two responsibilities:
     1.Mathematical model of the geometry of rectangle
     2.Render rectangle to a graphical user interface.       Geometric
                                                             Geometric
                                                              Rectangle
                                                               Rectangle
                                                               public area()
                                                                public area()




Slide 36
Module should not know internal details of objects it manipulates.
     A method M of an object O may only invoke the methods of the
     following kinds of objects:
     •O itself
     •M's parameters
     •any objects created/instantiated within M                  Class PaperBoy { {
                                                                  Class PaperBoy
     •O's instance variables                                         void collectPaymetents() { {
                                                                      void collectPaymetents()
Class PaperBoy { {
 Class PaperBoy                                                        float payment ==2.0;
                                                                        float payment 2.0;
    void collectPaymetents() { {
     void collectPaymetents()                                          float fundsCollected ==0.0;
                                                                        float fundsCollected 0.0;
       float payment ==2.0;
        float payment 2.0;                                             for (Customer customer : :customerList) { {
                                                                        for (Customer customer customerList)
       float fundsCollected ==0.0;
        float fundsCollected 0.0;
                                                                             try { {
                                                                              try
       for (Customer customer : :customerList) { {
        for (Customer customer customerList)                                    fundsCollected +=
                                                                                  fundsCollected +=
                                                                   customer.makePayment(payment);
            float moneyInWallet ==customer.getWallet().getMoney(); customer.makePayment(payment);
              float moneyInWallet customer.getWallet().getMoney();           }}
                                                                             catch (NotEnoughMoneyComeLaterException
                                                                              catch (NotEnoughMoneyComeLaterException
            ifif(moneyInWallet >= payment) { {
                 (moneyInWallet >= payment)                        e) { {
                                                                    e)
                  customer.getWallet.setMoney(moneyInWallet ––
                   customer.getWallet.setMoney(moneyInWallet                 }}
payment);
 payment);                                                                }}
                  fundsCollected += payment;
                   fundsCollected += payment;                      }}
            }}
       }}
   } } Slide 37
}}
In object oriented languages, power of polymorphism comes from Liskov’s
substitution principle.

“A subclass can be used as an argument where a base class is expected”

 Class Mechanic { {
  Class Mechanic

      public void repair (Car car) { {
       public void repair (Car car)

      }}

 }}

 class HyundaiCar implements Car { {
  class HyundaiCar implements Car
 }}

 class MarutiCar implements Car { {
  class MarutiCar implements Car
 }}
                                              HyundaiCar faultyHyundai ==new HyundaiCar();
                                               HyundaiCar faultyHyundai new HyundaiCar();
                                              mechanic.repair (faultyHyunai);
                                               mechanic.repair (faultyHyunai);
 class HyundaiSantro extends HyundaiCar { {
  class HyundaiSantro extends HyundaiCar      MarutiCar faultyMaruti ==new MarutiCar();
                                               MarutiCar faultyMaruti new MarutiCar();
 }}
                                              mechanic.repair(faultyMaruti);
                                               mechanic.repair(faultyMaruti);
                                                                                             Slide 38
Class Driver { {
 Class Driver

     public void drive (Car car) { {
      public void drive (Car car)

     }}

     public void drive (Truck truck) { {
      public void drive (Truck truck)

     }}
}}

                                           Class Driver { {
                                            Class Driver

                                                public void drive (Vehicle vehicle) { {
                                                 public void drive (Vehicle vehicle)

                                                }}

                                           }}


                                                                                          Slide 39
Class should be open for extension, but closed for modification.


ifif( (isGoingToMovie() ) ){ {
        isGoingToMovie()

     Vehicle vehicle ==new Car();
      Vehicle vehicle new Car();

     driver.drive (vehicle ) )
      driver.drive (vehicle

}}
                                                 Vehicle vehicle ==getVehicle(conditions);
                                                  Vehicle vehicle getVehicle(conditions);
else ( (ifRelocatingToNewHome ()()) ){ {
 else ifRelocatingToNewHome                      driver.drive (vehicle ););
                                                  driver.drive (vehicle
     Vehicle vehicle ==new Truck();
      Vehicle vehicle new Truck();

     driver.drive (vehicle ););
      driver.drive (vehicle

}}




                                                                                    Slide 40
Extract Try/Catch Blocks
Error Handling Is One Thing
List<Employee> employees = getEmployees();
    for(Employee e : employees) {
       totalPay += e.getPay();
    }
    public List<Employee> getEmployees() {
       if( .. there are no employees .. )
          return Collections.emptyList();
    }


public double xProjection(Point p1, Point p2) {
      return (p2.x – p1.x) * 1.5;
   }
   public double xProjection(Point p1, Point p2) {
      if (p1 == null || p2 == null) {
         throw InvalidArgumentException ("Invalid argument
               for MetricsCalculator.xProjection");
      }
      return (p2.x – p1.x) * 1.5;
   }
Clean code - Agile Software Craftsmanship

Clean code - Agile Software Craftsmanship

  • 1.
  • 14.
    Use pronounceable names classDtaRcrd102 class DtaRcrd102 class Customer class Customer
  • 19.
    class InchToPointConvertor { class InchToPointConvertor { //convert the quantity in inches to points. //convert the quantity in inches to points. static float parseInch(float inch) { static float parseInch(float inch) { return inch * 72; //one inch contains 72 return inch * 72; //one inch contains 72 points. points. }} }} class InchToPointConvertor { class InchToPointConvertor { final static int POINTS_PER_INCH=72; final static int POINTS_PER_INCH=72; static float convertToPoints(float inch) { static float convertToPoints(float inch) { return inch * POINTS_PER_INCH; return inch * POINTS_PER_INCH; }} }}
  • 20.
    class Account { class Account { //check if the password is complex enough, i.e., //check if the password is complex enough, i.e., //contains letter and digit/symbol. //contains letter and digit/symbol. boolean isComplexPassword(String password) {{ boolean isComplexPassword(String password) //found aa digit or symbol? //found digit or symbol? boolean dg_sym_found=false; boolean dg_sym_found=false; //found aa letter? //found letter? boolean letter_found=false; boolean letter_found=false; for(int i=0; i<password.length(); i++){ for(int i=0; i<password.length(); i++){ char c=password.charAt(i); char c=password.charAt(i); if(Character.isLowerCase(c)||Character.isUpperCase(c)) if(Character.isLowerCase(c)||Character.isUpperCase(c)) letter_found=true; letter_found=true; else dg_sym_found=true; else dg_sym_found=true; }} return (letter_found) && (dg_sym_found); return (letter_found) && (dg_sym_found); }} }} class Account { class Account { boolean isComplexPassword(String password){ boolean isComplexPassword(String password){ return containsLetter(password) && return containsLetter(password) && (containsDigit(password) || (containsDigit(password) || containsSymbol(password)); containsSymbol(password)); }} boolean containsLetter(String password) {{ boolean containsLetter(String password) return false; return false; }} boolean containsDigit(String password) {{ boolean containsDigit(String password) return false; return false; }} boolean containsSymbol(String password) {{ boolean containsSymbol(String password) return false; return false; }}
  • 33.
    Goal of OOAD: Identifythe classes and relations between them for a given problem. Read the problem statement carefully and identify: • Nouns (Classes) • Verbs (Behavior) • Actors (Users) Identify relationships between classes • Is-A (Generalization / Inheritance) • Has-A (Composition) • Uses (Dependency)
  • 34.
    A basket containsoranges 11 Basket Basket and apples. ** ** Apple Apple Orange Orange 11 ** Fruits have cost Basket Basket Fruit Fruit int Price; int Price; Apple Apple Orange Orange Generalize to accommodate new requirements. Generalize to accommodate new requirements. Slide 34
  • 35.
    A user haspassword. Password can be encrypted and decrypted. 11 11 User User Password Password public String encrypt(); public String encrypt(); String userid; String userid; public String decrypt(); public String decrypt(); Password is encrypted using a encryption service. 11 11 User User Password Password EncryptionService EncryptionService public String encrypt(); public String encrypt(); public String encrypt(String); public String encrypt(String); String userid; String userid; public String decrypt(); public String decrypt(); public String decrypt(String); public String decrypt(String); Slide 35
  • 36.
    Class should haveone and only one reason to change. Rectangle Rectangle Rectangle Rectangle Point topLeftCorner Point topLeftCorner public draw() public draw() Point bottomRightCorner Point bottomRightCorner public area() public area() Two responsibilities: 1.Mathematical model of the geometry of rectangle 2.Render rectangle to a graphical user interface. Geometric Geometric Rectangle Rectangle public area() public area() Slide 36
  • 37.
    Module should notknow internal details of objects it manipulates. A method M of an object O may only invoke the methods of the following kinds of objects: •O itself •M's parameters •any objects created/instantiated within M Class PaperBoy { { Class PaperBoy •O's instance variables void collectPaymetents() { { void collectPaymetents() Class PaperBoy { { Class PaperBoy float payment ==2.0; float payment 2.0; void collectPaymetents() { { void collectPaymetents() float fundsCollected ==0.0; float fundsCollected 0.0; float payment ==2.0; float payment 2.0; for (Customer customer : :customerList) { { for (Customer customer customerList) float fundsCollected ==0.0; float fundsCollected 0.0; try { { try for (Customer customer : :customerList) { { for (Customer customer customerList) fundsCollected += fundsCollected += customer.makePayment(payment); float moneyInWallet ==customer.getWallet().getMoney(); customer.makePayment(payment); float moneyInWallet customer.getWallet().getMoney(); }} catch (NotEnoughMoneyComeLaterException catch (NotEnoughMoneyComeLaterException ifif(moneyInWallet >= payment) { { (moneyInWallet >= payment) e) { { e) customer.getWallet.setMoney(moneyInWallet –– customer.getWallet.setMoney(moneyInWallet }} payment); payment); }} fundsCollected += payment; fundsCollected += payment; }} }} }} } } Slide 37 }}
  • 38.
    In object orientedlanguages, power of polymorphism comes from Liskov’s substitution principle. “A subclass can be used as an argument where a base class is expected” Class Mechanic { { Class Mechanic public void repair (Car car) { { public void repair (Car car) }} }} class HyundaiCar implements Car { { class HyundaiCar implements Car }} class MarutiCar implements Car { { class MarutiCar implements Car }} HyundaiCar faultyHyundai ==new HyundaiCar(); HyundaiCar faultyHyundai new HyundaiCar(); mechanic.repair (faultyHyunai); mechanic.repair (faultyHyunai); class HyundaiSantro extends HyundaiCar { { class HyundaiSantro extends HyundaiCar MarutiCar faultyMaruti ==new MarutiCar(); MarutiCar faultyMaruti new MarutiCar(); }} mechanic.repair(faultyMaruti); mechanic.repair(faultyMaruti); Slide 38
  • 39.
    Class Driver {{ Class Driver public void drive (Car car) { { public void drive (Car car) }} public void drive (Truck truck) { { public void drive (Truck truck) }} }} Class Driver { { Class Driver public void drive (Vehicle vehicle) { { public void drive (Vehicle vehicle) }} }} Slide 39
  • 40.
    Class should beopen for extension, but closed for modification. ifif( (isGoingToMovie() ) ){ { isGoingToMovie() Vehicle vehicle ==new Car(); Vehicle vehicle new Car(); driver.drive (vehicle ) ) driver.drive (vehicle }} Vehicle vehicle ==getVehicle(conditions); Vehicle vehicle getVehicle(conditions); else ( (ifRelocatingToNewHome ()()) ){ { else ifRelocatingToNewHome driver.drive (vehicle );); driver.drive (vehicle Vehicle vehicle ==new Truck(); Vehicle vehicle new Truck(); driver.drive (vehicle );); driver.drive (vehicle }} Slide 40
  • 41.
    Extract Try/Catch Blocks ErrorHandling Is One Thing
  • 42.
    List<Employee> employees =getEmployees(); for(Employee e : employees) { totalPay += e.getPay(); } public List<Employee> getEmployees() { if( .. there are no employees .. ) return Collections.emptyList(); } public double xProjection(Point p1, Point p2) { return (p2.x – p1.x) * 1.5; } public double xProjection(Point p1, Point p2) { if (p1 == null || p2 == null) { throw InvalidArgumentException ("Invalid argument for MetricsCalculator.xProjection"); } return (p2.x – p1.x) * 1.5; }