OOP原则

kevin 2023-04-22

SOLID princial

介绍单一指责原则,开闭原则,里氏替换原则,接口隔离原则和依赖倒置原则

单一职责原则(Single Responsibility Principle SRP)

一个类应该只有一个发生变化的原因,或者说每个类或者方法只有一个职责

public class customer{
	private string name;
  //getter and setter
  
  public void storeCustomer(string customerName){
    // store customer into a DB
  }
  
  public void generateCustomerReport(string customerName){
  	// generate a report
  }
}
public class customer{
  private string name;
  // getter and setter
}

public class customerBD{
   public void storeCustomer(string customerName){
    // store customer into a DB
  }
}

public class customerReportGenerator{
   public void generateCustomerReport(string customerName){
  	//generate a report
	}
}

开闭原则(Open Closed Principle OCP)

Software entities (classes, modules, methods, etc.) should be open for extension, but closed for modification

In practice, this means creating software entities whose behavior can be changed without the need to edit and recompile the code itself.

一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭

public class Rectangle{
  private int height;
  private int width;
}

public class Square{
  private int side;
}

public class ShapePrinter{
  public void drawShape(Object shape){
    if(shape instanceof Rectangle){
      // draw
    }else if(shape instanceof Square){
      // draw
    }
  }
}


/* If these classes are compiled into a library, and When we want to draw a new type of shape, we have to open* the library, add a new shape class and then modify the drawShape method in the ShapePrinter class
/
public interface IDrawable{
  void draw();
}

public class Rectangle implements IDrawable{
  private int height;
  private int width;
  
  public void draw(){
    // draw
  }
}

public class Square implements IDrawable{
  private int side;
  public void draw(){
    // draw
  }
}

public class ShapePrinter{
  public void drawShape(IDrawable shape){
    shape.draw();
  }
}

/* When we want to draw a new type of shape, we just add a new shape class, and need not to open the complied * * library(keep it close).
/

里氏替换原则(Liskov Substitution Principle LSP)

Subtypes must be substitutable for their base types.

所有引用基类的地方必须能透明地使用其子类的对象

package demo_java.rectangle;

public class Rectangle{
    private int width;
    private int height;

    public void setWidth(int width) {
        this.width = width;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    
    public int getArea(){
        return width * height;
    }
}


package demo_java.rectangle;

public class Square extends Rectangle{
    @Override
    public void setWidth(int width) {
        super.setWidth(width);
        super.setHeight(width);
    }

    @Override
    public void setHeight(int height) {
        super.setWidth(height);
        super.setHeight(height);
    }
}

package demo_java.rectangle;

public class test {
    public static void main(String[] args) {
        Rectangle rectangle =  new Rectangle();
        rectangle.setHeight(5);
        rectangle.setWidth(2);

    }
}

package demo_java.rectangle;

public class test {
    public static void main(String[] args) {
        Rectangle rectangle =  new Rectangle();
        rectangle.setHeight(5);
        rectangle.setWidth(2);

    }
}

package demo_java.refactorRectangle;

public class Square extends Rectangle {
    public Square(int side) {
        super(side,side);
    }    
}
/* 
* The methods setWidth and setHeight  are removed, to ensure that Square has not useless inherited members.
/

接口隔离原则(Interface Segregation Principle)

Thin, focused interfaces are better than “fat” interfaces that offer more functionality.

  1. 客户端不应该依赖它不需要的接口。
  2. 类间的依赖关系应该建立在最小的接口上。

依赖倒置原则(Dependence Inversion Principle)

High level modules should not depend on low level modules; both should depend on abstractions.

Abstractions should not depend on details

Details should depend upon abstractions

  1. 上层模块不应该依赖底层模块,它们都应该依赖于抽象。
  2. 抽象不应该依赖于细节
  3. 细节应该依赖于抽象。

image-20230311175821924

image-20230311175847679

DeliveryCompany is a high abstraction class that refers generally to companies with different businesses.

However, DeliveryCompany depends on the low-level concrete DeliverDriver class, which violates the DIP principle.

If a company has a new delivery method, such as human or drone delivery, then the DeliveryCompany class needs to be modified.

image-20230311180009624

image-20230311180018158

image-20230311180026039