This article source: making here | | GitEE, click here

One, single responsibility principle

1. Concept description

For classes, that is, a class should be responsible for only one responsibility. If a class is responsible for two responsibilities, there may be a situation where responsibility 1 changes, causing responsibility 2 to change. Classes can be refined based on abstract logic or business logic.

2. Case demonstration

Both method and class refinement are available, and can be selected according to the actual business.

class Animal {
    public void dogVoice (a){
        System.out.println("Dog Bark: Want Want.");
    }
    public void cowVoice (a){
        System.out.println("Moo, moo."); }}class DogVoice {
    public String getDogVoice (a){
        return "Wangwang"; }}class CowVoice {
    public String getCowVoice (a){
        return "Moo"; }}Copy the code

3. Precautions

Reduce the code of a change caused by large-scale changes in the program, reduce the complexity of the class, improve the readability of the class, maintainability. In general, the single responsibility principle needs to be observed and can be violated as appropriate.

2. Interface isolation principle

1. Concept description

A client should not rely on interfaces it does not need, and the dependencies of one class to another should be based on the smallest interface.

2. Case demonstration

interface ReadBlog {
    String getBlog (a) ;
}
interface AdminBlog {
    Boolean insertBlog (a) ;
    Boolean updateBlog (a) ;
    Boolean deleteBlog (a) ;
}
/** * Readers only open the blog reading interface */
class Reader implements ReadBlog {
    @Override
    public String getBlog(a) {
        return null; }}/** * The administrator has full permission to manage the blog */
class AdminUser implements AdminBlog.ReadBlog {
    @Override
    public String getBlog(a) {
        return null;
    }
    @Override
    public Boolean insertBlog(a) {
        return null;
    }
    @Override
    public Boolean updateBlog(a) {
        return null;
    }
    @Override
    public Boolean deleteBlog(a) {
        return null; }}Copy the code

3. Precautions

The smaller the interface design granularity, the more flexible the application system program, and the more flexible the program becomes, the more complex the structure, the more difficult it is to develop and understand, and the less maintainable it is.

Three, dependence reversal principle

1. Concept description

A high-level module should not depend on a low-level module, both should depend on its abstraction; Abstractions should not depend on details, details should depend on abstractions; The central idea is interface oriented programming.

2. Case demonstration

public class C01_FarmFactory {
    public static void main(String[] args) {
        Animal animal = new Dog() ;
        FarmFactory farm = new Farming() ;
        farm.breed(animal) ;
        animal = newPig() ; farm.breed(animal) ; }}/** * the interface declares the dependent object */
interface FarmFactory {
    void breed (Animal animal) ;
}
class Farming implements FarmFactory {
    @Override
    public void breed(Animal animal) {
        System.out.println("Farm raising:"+animal.getAnimalName()); }}interface Animal {
    String getAnimalName (a) ;
}
class Dog implements Animal {
    @Override
    public String getAnimalName(a) {
        return "Sheepdog"; }}class Pig implements Animal {
    @Override
    public String getAnimalName(a) {
        return "Pig No. 1"; }}Copy the code

3. Precautions

Relative to the variability of system development, abstraction is relatively stable. An architecture based on abstraction is more stable and flexible than one based on detail. The lower modules should have abstract classes or interfaces as far as possible, and the program stability is better. The variable declaration type is abstract class or interface as far as possible, so that there is a transition space between the variable reference and the actual object, which is conducive to program expansion and optimization.

4. Richter’s substitution principle

1. Concept description

Assume the following scenario:

  • There is a type T1 and an instance of object O1
  • There is a type T2 and an instance of object O2

If all objects O1 of type T1 are replaced with objects O2 of type T2, the behavior of the program does not change. Then type T2 is a subtype of type T1. In other words, all references to a base class must be able to transparently use objects from its subclasses.

2. Case demonstration

public class C01_Calculate {
    public static void main(String[] args) {
        BizCalculate bizCalculate = new BizCalculate() ;
        System.out.println(bizCalculate.add(2.3)); }}class Calculate {}class BaseCalculate extends Calculate {
    public int add (int a,int b){
        returna+b; }}/** ** this is done in combination */
class BizCalculate extends Calculate {
    private BaseCalculate baseCalculate = new BaseCalculate() ;
    public int add (int a,int b){
        return this.baseCalculate.add(a,b); }}Copy the code

3. Precautions

When using inheritance, follow the Richter substitution principle, try not to rewrite the method of the parent class in the subclass; A subclass can extend the functionality of the parent class, but cannot change the functionality of the original parent class. Where appropriate, problems can be solved through aggregation, composition, dependency, and so on.

Five, open and close principle

1. Concept description

The principle of open and close is the most basic and important design principle in programming. In the design and design of code structure, we should consider open to extension, close to modification, abstract thinking to build the structure, and concrete implementation of extension details.

2. Case demonstration

public class C01_BookPrice {
    public static void main(String[] args) {
        ParityBook parityBook = new DiscountBook("Java".100.00); System.out.println(parityBook.getPrice()); }}interface Book {
    String getName (a) ;
    Double getPrice (a) ;
}
/** ** cheap books */
class ParityBook implements Book {
    private String name ;
    private Double price ;
    public ParityBook(String name, Double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String getName(a) {
        return this.name ;
    }
    @Override
    public Double getPrice(a) {
        return this.price ; }}/** * discount data extension price calculation strategy */
class DiscountBook extends ParityBook {
    public DiscountBook(String name, Double price) {
        super(name, price);
    }
    @Override
    public Double getPrice(a) {
        double oldPrice = super.getPrice();
        return oldPrice * 0.8; }}Copy the code

3. Precautions

The code structure designed based on the open and closed principle can improve the reusability and maintainability. It can restrain the changing behavior of classes through interfaces or abstract classes, encapsulate the changing behavior based on specified policies, and realize the openness to extension. The basic principle of using design pattern is to follow the open and closed principle.

6. Demeter principle

1. Concept description

Demeter’s principle is also known as the least known principle, which states that a class knows as little as possible about the classes it depends on. That is, for dependent classes, no matter how complex, try to encapsulate the logic inside the class. No information is exposed to the public except for the provided public methods. The closer the relationship between classes is, the greater the coupling degree is. There are many coupling ways, such as dependence, association, combination and aggregation.

  • Direct friend concept

If there is a coupling between two objects, they are said to be friends. Classes in which member variables, method parameters, and method return values appear are called direct friends, while classes in local variables are not direct friends. As a matter of principle, unfamiliar classes should not appear inside the class as local variables.

2. Case demonstration

public class C01_Employee {
    public static void main(String[] args) {
        HeadCompanyEmpManage empManage = new HeadCompanyEmpManage() ;
        BranchCompanyEmpManage branchEmp = newBranchCompanyEmpManage() ; empManage.printEmp(branchEmp); }}/** * Head office staff */
class HeadCompanyEmp {
    public String name ;
    public HeadCompanyEmp(String name) {
        this.name = name;
    }
    @Override
    public String toString(a) {
        return "HeadCompanyEmp{name='" + name + '} '; }}/** * branch staff */
class BranchCompanyEmp {
    public String name ;
    public BranchCompanyEmp(String name) {
        this.name = name;
    }
    @Override
    public String toString(a) {
        return "BranchCompanyEmp{name='" + name + '} '; }}/** * branch staff management */
class BranchCompanyEmpManage {
    // Add a branch employee
    public List<BranchCompanyEmp> addEmp (a){
        List<BranchCompanyEmp> list = new ArrayList<>() ;
        for (int i = 1 ; i <= 3 ; i++){
            list.add(new BranchCompanyEmp("Branch employees"+i)) ;
        }
        return list ;
    }
    // Get branch employees
    public void printBranchCompanyEmp (a){
        List<BranchCompanyEmp> list = addEmp () ;
        for(BranchCompanyEmp emp:list){ System.out.println(emp); }}}/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
class HeadCompanyEmpManage {
    // Add a head office employee
    public List<HeadCompanyEmp> addHeadEmp (a){
        List<HeadCompanyEmp> list = new ArrayList<>() ;
        for (int i = 1 ; i <= 3 ; i++){
            list.add(new HeadCompanyEmp("Head office staff"+i)) ;
        }
        return list ;
    }
    public void printEmp (BranchCompanyEmpManage empManage){
        // Print branch staff
        empManage.printBranchCompanyEmp();
        List<HeadCompanyEmp> headEmpList = addHeadEmp () ;
        for(HeadCompanyEmp headCompanyEmp:headEmpList){ System.out.println(headCompanyEmp); }}}Copy the code

3. Precautions

The original intent of the Demeter principle is to reduce coupling between classes, which can be reduced because each class reduces unnecessary dependencies. Reducing coupling does not require the complete absence of dependency. Excessive use of Demeter principle will easily produce a large number of intermediate classes, resulting in greater complexity. So there are business trade-offs when using the Demeter principle.

Summary of design principles

Design patterns, and the core of the design principles are: to determine the business applications may change the module, and the independence of these modules, based on the specified strategy for encapsulation, don’t with those changes small module coupling, encapsulated in the thought based on interfaces and abstract classes, rather than for the realization of the concrete programming. The core purpose is to reduce loose coupling between interacting objects. Design patterns and principles are not formulas that can be copied mechanically. Personal understanding: as long as the shape is similar, the charm is natural.

Eight, source code address

Making address https://github.com/cicadasmile/model-arithmetic-parent GitEE · https://gitee.com/cicadasmile/model-arithmetic-parentCopy the code