solid dry kiss - uim · single responsibility principle 6 a class should have only one reason to...

45
SOLID DRY KISS

Upload: others

Post on 17-Jun-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

SOLID DRY KISS

Page 2: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Content

Single responsibility principle

Open/closed principle

Liskov substitution principle

Interface segregation principle

Dependency inversion principle

Don’t Repeat Yourself

Keep It Simple Stupid

Design principles

2

Page 3: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Design

It seems that perfection is attained, not when there is nothing more to add, but when there is nothing more to take away.

Antoine de Saint Exupéry

3

Page 4: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Design

4

Page 5: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Single responsibility principle

5

Page 6: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Single responsibility principle

6

A class should have only one reason to change.

So a responsibility is a family of functions that serves one particular actor.

An actor for a responsibility is the single source of change for that responsibility.

Page 7: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Single responsibility principle

7

class Book { public String getTitle() { return "A Great Book"; } public String getAuthor() { return "John Doe"; } public void turnPage() { // set actual page to next page } public void printCurrentPage() { System.out.println(“current page content"); }}

Page 8: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Single responsibility principle

8

class Book { public String getTitle() { return "A Great Book"; } public String getAuthor() { return "John Doe"; } public void turnPage() { // set actual page to next page } public String getCurrentPage() { return “current page content"; }}

Page 9: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Single responsibility principle

9

interface Formatter { public String formatPage(Book book);}class PlainTextFormatter implements Formatter { public String formatPage(Book book) { return book.getCurrentPage(); }}class HtmlFormatter implements Formatter { public String formatPage(Book book) { return "<div style=\"single-page\">" + book.getCurrentPage() + "</div>"; }}

Page 10: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

10

Page 11: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

11

Software entities (classes, modules, etc.) should be:

1. open for extension, 2. closed for modification.

Page 12: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

12

class Square { private double height; // getters & setters}

class Circle { private double radius;

// getters & setters}

Page 13: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

13

class AreaCalculator { public double calculate(Object[] shapes) { double area = 0; for (Object shape : shapes) { if (shape instanceof Square) { area += Math.pow(((Square)shape).getHeight(), 2); } else { area += Math.PI*Math.pow(((Circle)shape).getRadius(), 2); } } return area; }}

Page 14: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

14

class Triangle { private double[] sides;

// set/get first side // set/get second side // set/get third side}

Page 15: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

15

class AreaCalculator { public double calculate(Object[] shapes) { double area = 0; for (Object shape : shapes) { if (shape instanceof Square) { area += Math.pow(((Square)shape).getHeight(), 2); } else { area += Math.PI*Math.pow(((Circle)shape).getRadius(), 2); } // if (shape istanceof Triangle) } return area; }}

Page 16: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

16

class Square extends Shape { private double height; public double area() { return height*height; }}

class Circle extends Shape { private double radius;

public double area() { return Math.PI*radius*radius; }}

abstract class Shape { abstract public double area();}

Page 17: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

17

class AreaCalculator { public double calculate(Object[] shapes) { double area = 0; for (Object shape : shapes) { if (shape instanceof Square) { area += Math.pow(((Square)shape).getHeight(), 2); } else { area += Math.PI*Math.pow(((Circle)shape).getRadius(), 2); } // if (shape istanceof Triangle) } return area; }}

Page 18: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Open/closed principle

18

class AreaCalculator { public double calculate(Shape[] shapes) { double area = 0; for (Shape shape : shapes) { area += shape.area(); } return area; }}

Page 19: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

19

Page 20: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

Let ϕ(x) be a property provable about objects x of type T. Then ϕ(y) should be true for objects y of type S where S is a subtype of T.

If an object of type S can be substituted in all the places where an object of type T is expected, then S is a subtype of T.

20

Page 21: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

Is a square a special rectangle in OOP (is square subtype of rectangle)?

21

Page 22: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

class Rectangle {

protected double width; protected double height;

public double area() { return width*height; }

// getters & setters}

22

class Square extends Rectangle { @Override public void setHeight(double h) { height = h; width = h; }

@Override public void setWidth(double h) { setHeight(h); }}

Page 23: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

public void test(Rectangle rectangle) { rectangle.setWidth(10) rectangle.setHeight(5)

assert rectangle.area() == 10*5;}

test(new Rectangle()) // oktest(new Square()) // assertion error

23

Page 24: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

class Rectangle {

protected double width; protected double height;

public double area() { return width*height; }

// getters & setters}

24

class Square extends Rectangle { @Override public void setHeight(double h) { height = h; width = h; }

@Override public void setWidth(double h) { setHeight(h); }}

Page 25: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Liskov substitution principle

class Square extends Shape { private double side;

@Override public double area() { return side*side; } // getters & setters}

25

class Rectangle extends Shape { private double width; private double height;

@Override public double area() { return width*height; } // getters & setters}

abstract class Shape {

public double area();}

Page 26: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Interface segregation principle

26

No client should be forced to depend on methods it does not use

Page 27: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Interface segregation principle

27

public interface File {

String read();

void write();

void delete();}

public class ReadOnlyFile { @Override String read() { return this.content; } @Override void write() { // do nothing } @Override void delete() { // do nothing }}

Page 28: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Interface segregation principle

28

public interface FileReader {

String read();}

public interface FileWriter {

void write();}

public interface FileDeleter {

void delete();}

public class ReadOnlyFile implements FileReader { @Override String read() { return this.content; }}

Page 29: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Dependency inversion principle

29

Page 30: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

High level modules should not depend upon low level modules. Both should depend upon abstractions.

Abstractions should not depend upon details. Details should depend upon abstractions.

Dependency inversion principle

30

Page 31: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Dependency inversion principle

31

class Worker {

public void work() { // work }}

class Manager { private Worker worker; public Manager(Worker w) { worker = w; }

public void manage() { worker.work(); }}

Page 32: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Dependency inversion principle

32

class HardWorker { public void work() { // work hard }}

Page 33: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Dependency inversion principle

33

interface IWorker { void work();}

class Worker implements IWorker { public void work() { // work }}

class HardWorker implements IWorker { public void work() { // work hard }}

class Manager { private IWorker worker; public Manager(IWorker w) { worker = w; }

public void manage() { worker.work(); }}

Page 34: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Keep it simple stupid

34

Page 35: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Keep it simple stupid

35

The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.

FUNCTIONS SHOULD DO ONE THING . THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY .

Page 36: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Keep it simple stupid

36

Functions are the verbs of that language, and classes are the nouns. The art of programming is, and has always been, the art of language design.

Master programmers think of systems as stories to be told rather than programs to be written.

Page 37: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

A method f of a class C should only call the methods of these:

● C● an object created by f● an object passed as an argument to f● an object held in an instance variable of C

37

Page 38: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

38

Page 39: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

String outputDir = ctxt.getOptions() .getScratchDir() .getAbsolutePath();

Options opts = ctxt.getOptions();File scratchDir = opts.getScratchDir();final String outputDir = scratchDir.getAbsolutePath();

39

Page 40: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

Possible solutions:

ctxt.getAbsolutePathOfScratchDirectoryOption();

ctxt.getScratchDirectoryOption().getAbsolutePath()

40

Page 41: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

Reason of getting outputDir:

...String outFile = outputDir + "/" + className.replace('.', '/') + ".class";FileOutputStream fout = new FileOutputStream(outFile);BufferedOutputStream bos = new BufferedOutputStream(fout);

41

Page 42: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

Better solution:

BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);

42

Page 43: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Law of Demeter

What about this:

" some,long;weird,string ".trim() .toLowerCase() .replaceAll(";", ",") .split(",");

43

Page 44: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

To be continued ...

44

Page 45: SOLID DRY KISS - UIM · Single responsibility principle 6 A class should have only one reason to change. So a responsibility is a family of functions that serves one particular actor

Books

45

● Martin, Robert C.: Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall (2009)

● Beck, K.: Implementation Patterns. Pearson Education (2007)● Bloch, J.: Effective Java. Addison-Wesley Professional (2017)

Hardcore:● Boyarsky, J., Selikoff, S.: OCA / OCP Java SE 8 Programmer

Certification Kit: Exam 1Z0-808 and Exam 1Z0-809. Wiley (2016)