Design Patterns - Seven Principles

Seven principles of software development

First, the opening and closing principle: the face of the expansion open, closed face modification

(1) refers to the development process in the despreading code is possible, not to modify the original code, so as not to affect the logic before.

(2) Construction of the frame is emphasized that abstract, realized with extension detail.

(3) can improve software reusability and maintainability of the system

(2) Example: the original class curriculum, curriculum outsiders to discount, how they deal with it?
Original curriculum categories:

package test1;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public interface Course {
    public String getId();
    public String getName();
    public double getPrice();
}

 

package test1;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class JavaCourse implements Course {
  private String id;
  private String name;
  private double price;

    @Override
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public JavaCourse(String id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
}

 

 New discount coursework

package test1;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class JavaDiscountCourse extends JavaCourse{

    public JavaDiscountCourse(String id, String name, double price) {
        super(id, name, price);
    }

    public double getOriginPrice() {
        return super.getPrice();
    }

    public double getPrice() {
        return super.getPrice()*0.8;
    }

}

 

 

Corresponding modifications made without modifying the original based on the logic

Test categories:

package test1;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class Test {
    public static void main(String[] args) {
        JavaDiscountCourse cource = new JavaDiscountCourse("001","java",100.0);
        System.out.println(cource.getPrice());
        System.out.println(cource.getOriginPrice());
    }
}

 

 Second, the Dependency Inversion Principle: dependent on the abstract interface, do not depend on the specific implementation.

(1) the requirements of the abstract can be programmed not to implement programming.

(2) reduces the coupling between the client and the implementation module.

(3) Example: the original conversion tools can convert word, pdf two types of files, now that tools need to be extended so that it can convert on the basis of the original excel file

If the program is realized in accordance with dependence:

package test2;

/**
 * Des: office documents like transfer pdf
 * author:songyan
 * date: 2019/10/6
 **/
public class Trans {
    public void transWord(){
        System.out.println ( "converter" );
    }
    public void transPDF(){
        System.out.println ( "PDF conversion" );
    }
}

 

 

Client:

package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class Client {
    public static void main(String[] args) {
        Trans trans = new Trans();
        trans.transWord();
        trans.transPDF ();
    }
}

 

The drawbacks of using this approach is that, if you want to extend the functionality of tools like conversion tool, you need to modify the code before, this approach is obviously very unsafe, likely will affect before the code.

Better yet:

package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class TransUtil {
    public void trans(OfficeDocument document){
        document.trans();
    }
}

 

package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class WordDocument implements OfficeDocument {
    @Override
    public  void trans () {
        System.out.println ( "Word Document Conversion" );
    }
}

 

package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class PDFDocuemnt implements OfficeDocument{

    @Override
    public  void trans () {
        System.out.println ( "PDF conversion" );
    }
}

 

package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class Test {
    public static void main(String[] args) {
        TransUtil trnas = new TransUtil();
        trnas.trans(new WordDocument());
        trnas.trans(new PDFDocuemnt());

    }
}

 

Conversion tools is an interface for processing the object of processing, when you want to extend the functionality only need to add a class can be realized, for example:

package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class ExcelDocument implements OfficeDocument{

    @Override
    public  void trans () {
        System.out.println ( "Excel conversion" );
    }
}
package test2;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class Test {
    public static void main(String[] args) {
        TransUtil trnas = new TransUtil();
        trnas.trans(new WordDocument());
        trnas.trans(new PDFDocuemnt());
        trnas.trans(new ExcelDocument());

    }
}

 

Before using this method requires only the spreading code, without the need to modify the code before the fact, that is to say the opening and closing above principle.

This example is actually a "dependency injection", then the dependency injection manner and include constructor injection, setter injection method, the following brief introduction about this two ways

1) constructor injection

package test2.generator;

import test2.OfficeDocument;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class TransUtil {
    private OfficeDocument officeDocument;

    public TransUtil(OfficeDocument officeDocument) {
        this.officeDocument = officeDocument;
    }

    public  void trans () {
        officeDocument.trans();
    }
}
package test2.generator;

import test2.WordDocument;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class Test {
    public static void main(String[] args) {
        TransUtil transUtil = new TransUtil(new WordDocument());
        transUtil.trans ();
    }
}

 

2) setter injection mode

package test2.setter;

import test2.OfficeDocument;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class TransUtil {
    private OfficeDocument officeDocument;

    public void setOfficeDocument(OfficeDocument officeDocument) {
        this.officeDocument = officeDocument;
    }

    public  void trans () {
        officeDocument.trans();
    }
}
package test2.setter;

import test2.WordDocument;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class Test {
    public static void main(String[] args) {
        TransUtil  transUtil= new TransUtil();
        transUtil.setOfficeDocument(new WordDocument());
        transUtil.trans ();
    }
}

 

Abstract basis for robust than to build up the basis of the details of the framework, therefore, everyone needs to get after the abstract-oriented programming interface, first at the bottom to the top level design code structure.

Third, the single responsibility principle: a class, an interface, a method should be only one function

(1) If there are multiple functions, the functions of which occurred after a change, you need to modify the function of this class, it may affect the other functions. So we need to split them to some extent.

(2) reduce the complexity of the class, the class improve readability, increase maintainability of the system, reducing the risk caused by changes

(3) Example: There is a class of tool nginx operation is as follows:

package test3;

/**
 * Nginx Tools
 * author:songyan
 * date: 2019/10/6
 **/
public class NginxUtil {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void start(){
        System.out.println ( "Start nginx" );
    }
}

 

There are methods nginx basic design information, but also to start nginx methods, for example, nginx start method has changed, this time on the need to modify nginxUtil class, it may have an impact on his other methods that modify the course so we can make the following division of him, he is isolated:

package test3;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class NginxInfo {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package test3;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class NginxOperator {
    public void start(){
        System.out.println ( "nginx start" );
    }
}

 

The interface is similar. .

Examples of methods which do not meet the single responsibility principle:

    public void modefied(String name,String fav){
        System.out.println ( "Modify name" );
        System.out.println ( "Modify hobby" );
    }

 

Examples of methods in line with the principle of single duties:

    public void modefiedName(String name){
        System.out.println ( "Edit name" );
    }
    public void modefiedFav(String fav){
        System.out.println ( "Modify hobby" );
    }

 

In fact, at first glance it may not feel this way where the benefits can not write in, I suddenly thought of my recent mission, before the modification colleagues write in a system, which most of the logic of the code is stack together, one way to have a few hundred lines of code to do what are, may sometimes need only a point to change them, but might affect the rest of the code, there is a drawback is that the code inside the complex, may to find the place you want to change is very difficult.

It boils down to this, in the process of writing code to maintain as much as possible if a single accused principles will improve the readability of the class, to improve the maintainability of the system, reducing the risk caused by changes.

Fourth, the interface segregation principle: the use of a plurality of specific interface, the interface without using the single general

(1) a class of a class is the interface should be based on a minimum of interfaces.

(2) try to single interface, rather than creating a single bloated interface

(3) Interface possible refinement process to minimize interface (not better, to moderate)

(4) Example: A few days before the transfer pdf document summarizes the office of the manner in which openoffice, aspose support windows, linux two systems, but only supports jacob windows system, the following code will be some problems.

In the following code, a way to convert windows, Linux way conversion in an interface:

package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public interface Itrans {
    void windowsTrans();
    void linuxTrans();

}

 

In openoffice, aspose two ways, there is no problem, see below:

package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class AsposeTrans implements  Itrans{
    @Override
    public void windowsTrans() {
        System.out.println ( "Aspose converted in the windows" );

    }

    @Override
    public void linuxTrans() {
        System.out.println ( "linux conversion of the Aspose" );

    }
}
package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class OpenofficeTrans implements Itrans{
    @Override
    public void windowsTrans() {
        System.out.println ( "oppenoffice converted in the windows" );
    }

    @Override
    public void linuxTrans() {
        System.out.println ( "oppenoffice conversion of linux" );
    }
}

 

However, you will find jacob, he does not support conversion of Linux, but to achieve this, then the interface must override this interface. .

package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class JacobTrans implements Itrans{
    @Override
    public void windowsTrans() {
        System.out.println ( "Jacob conversion in the windows" );
    }

    @Override
    public void linuxTrans() {

    }
}

 

For the above situation can do the following to improve, we split into two interface methods in the interface:

package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public interface IWindowsTrans {
    void windowsTrans();
}
package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public interface ILinuxTrans {
    void linuxTrans();
}

 

Both systems support for ways to achieve two interfaces

package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class AsposeTrans implements  IWindowsTrans,ILinuxTrans{
    @Override
    public void windowsTrans() {
        System.out.println ( "Aspose converted in the windows" );

    }

    @Override
    public void linuxTrans() {
        System.out.println ( "linux conversion of the Aspose" );

    }
}

 

System to support only one way to implement an interface that requires only

package test4;

/**
 * author:songyan
 * date: 2019/10/6
 **/
public class JacobTrans implements  IWindowsTrans{
    @Override
    public void windowsTrans() {
        System.out.println ( "Jacob conversion in the windows" );
    }
    
}

 

Guess you like

Origin www.cnblogs.com/excellencesy/p/11627841.html