Design Pattern

Advanced Programming

SUT • Spring 2019

Contents

  • OOP Design

  • Design Patterns

OOP Design

interfaces

  • Defines a protocol

  • an interface promises a certain functionality

  • All the classes implementing the interface provide their own implementations for the promised functionality

  • A class combines the state and the behavior of a real object

  • An interface specifies (only) the behavior of an abstract entity

Famous Java Interfaces

  • Comparable<T>

    • int compareTo(T o)

  • java.io.Serializable

    • No method

    • Sometimes, interfaces have no method

    • The interface itself, is the protocol

  • Collection, Itertable, Iterator

Mechanisms of Code Reuse

  • Generics

  • Inheritance

  • Composition

  • interface

Composition

  • Inheritance: is-a

  • Composition: has-a

  • Circle has a center


  •  

  • Other examples?

public class Circle {
    private Point center;
}

Composition vs. Inheritance

  • You can make a base class

  • And put the common functionality of many classes in it

  • But always check:

    • Whether the is-a relationship exists between the derived classes and the base class

    • If the is-a relationship does not hold, Use composition instead of inheritance

    • Favor Composition over Inheritance

Example

public Class Sorting {
    public list sort(List list) {
        // sort implementation
        return list;
    }
}

class DynamicDataSet extends Sorting {
    // DynamicDataSet implementation
}

class SnapshotDataSet extends Sorting {
    // SnapshotDataSet implementation
}

Problems with this Inheritance

  • is-a    

    • DynamicDataSet is-a Sorting? No.

  • What if the two types of data set classes have a genuine base class, DataSet?

Notes

  • Favor composition over inheritance

    • Use composition to get code that is easy to change

    • and loosely coupled

  • Make your classes dependent on interfaces, not on the actual implementation

    • findBest(List<T>)

    • class DynamicDataSet { Sorting sorting; }

    • Do not depend on MergeSorting

IDE Support

  • Refactoring techniques are widely supported by IDEs

  • Practice it in Intelij

The Two Hats

  • Kent Beck's metaphor of two hats
  • Divide your time between two distinct activities
    • adding function
    • refactoring

Why Should I Refactor?

  • Refactoring Improves the Design of Software
  • Refactoring Makes Software Easier to Understand
  • Refactoring Helps You Find Bugs
  • Refactoring Helps You Program Faster
  • Refactoring makes your code more maintainable

When Should You Refactor?

  • The Rule of Three:

    • Refactor When You Add Function

    • Refactor When You Need to Fix a Bug

    • Refactor As You Do a Code Review

Example

public class Main {
    public void main(String[] args){
        Scanner s = new Scanner(System.in);

        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        int a1 = s.nextInt();
        System.out.print("Enter the length: ");
        int a2 = s.nextInt();

        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        int b1 = s.nextInt();
        System.out.print("Enter the length: ");
        int b2 = s.nextInt();

        int x = a1*a2;
        int y = b1*b2;

        if(x == y)
            System.out.println("Equal");
    }
}

Find bad smells!

Refactor the Code!

Example

public class Main {
    public void main(String[] args){
        Scanner scanner = new Scanner(System.in);

        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        int width1 = scanner.nextInt();
        System.out.print("Enter the length: ");
        int length1 = scanner.nextInt();

        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        int width2 = scanner.nextInt();
        System.out.print("Enter the length: ");
        int length2 = scanner.nextInt();

        int area1 = width1*length1;
        int area2 = width2*length2;

        if(area1 == area2)
            System.out.println("Equal");
    }
}

Rename…

Example

public  class Rectangle{
    private int length , width;
    public int getLength() {
        return length;
    }
    public void setLength(int length) {
        this.length = length;
    }
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public Rectangle(int length, int width) {
        this.length = length;
        this.width = width;
    }
}

Extract Class…

Example

public class Main {
 public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);

        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        int width = scanner.nextInt();
        System.out.print("Enter the length: ");
        int length = scanner.nextInt();
        Rectangle rectangle1 = new Rectangle(length, width);

        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        width = scanner.nextInt();
        System.out.print("Enter the length: ");
        length = scanner.nextInt();
        Rectangle rectangle2 = new Rectangle(length, width);

        int area1 = rectangle1.getWidth()*rectangle1.getLength();
        int area2 = rectangle2.getWidth()*rectangle2.getLength();

        if(area1 == area2)
            System.out.println("Equal");
    }
}

Extract Class…

Example

public class Rectangle {
    private static Rectangle readRectangle(Scanner scanner) {
        int width;
        int length;
        System.out.println("Rectangle Info.");
        System.out.print("Enter the width: ");
        width = scanner.nextInt();
        System.out.print("Enter the length: ");
        length = scanner.nextInt();
        Rectangle rectangle = new Rectangle(length, width);
        return rectangle;
    }
}

Extract Method…

Refactored Code

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        
        Rectangle rectangle1 = readRectangle(scanner);
        Rectangle rectangle2 = readRectangle(scanner);
        
        int area1 = rectangle1.area();
        int area2 = rectangle2.area();
        
        if(area1 == area2)
            System.out.println("Equal");
    }
}

Final Refactor ...

References

  • Refactoring: improving the design of existing code, Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts (1999)

Design Pattern

Title Text

Design Pattern

By Behnam Hatami

Design Pattern

Design Pattern / Advanced Programming Course @ SUT, Spring 2019

  • 961