The study notes Westward simple factory pattern design pattern (Java version)

Two characters in the book: dishes and bird
story from one topic to start: Please use C ++, Java, C # any object-oriented language calculator to achieve a console program, asked to enter two numbers and arithmetic symbols, get results.

The first answer dishes, as follows:

import java.util.Scanner;

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

        System.out.println("请输入数字A: ");
        double A = in.nextDouble();

        System.out.println("请选择运算符号(+ - * /): ");
        String c = in.next();

        System.out.println("请输入数字B: ");
        double B = in.nextDouble();

        double res = 0;
        
        if(c.equals("+")){
            res = A + B;
        }
        if(c.equals("-")){
            res = A - B;
        }
        if(c.equals("*")){
            res = A * B;
        }
        if(c.equals("/")){
            res = A / B;
        }
        System.out.println("结果是: " + res);
    }
}

Much at a glance three questions in the question without regard to the intention of the person, ha
first place: regulatory issues not named: A, B, c named best not to appear in the code
the second place: branch judgment is the problem: if four conditions mean that each judge have to do, the computer equivalent of doing useful work three times
third place: division by zero is not considered

Side dishes to modify the code ...

import java.util.Scanner;

public class SimpleFactoryModel {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        try {
            System.out.println("请输入数字A: ");
            double numberA = in.nextDouble();

            System.out.println("请选择运算符号(+ - * /): ");
            String strOperate = in.next();

            System.out.println("请输入数字B: ");
            double numberB = in.nextDouble();

            double result = 0;

            switch (strOperate){
                case "+":result = numberA + numberB;break;
                case "-":result = numberA - numberB;break;
                case "*":result = numberA * numberB;break;
                case "/":
                    if(numberB!=0){
                        result = numberA / numberB;
                    }else {
                        System.out.println("除数不能为0!");
                    }break;
            }
            if(numberB!=0){
                System.out.println("结果是: " + result);
            }
        }catch (Exception e){
            System.out.println("您的输入有错:"+e.getMessage());
        }
    }
}

Big Bird: Yes Yes, change the code quickly Well, but this code is written in line with the topic of people does it mean?
Side dishes: You mean object-oriented?
Big Bird: Haha, non-vegetable side dishes also!

Do not go away, the following story is very exciting!
A fragment: the words of the Three Kingdoms period, Cao Cao led millions of troops to attack Wu, the army stationed in the Yangtze River Red Cliff, even as a military ship, appeared to exterminate Wu, dominate the world, Cao Cao Yue, so all the civil and military banquet, at banquet room, Cao Cao poetic reverie, feel Yin: singing and drinking, life is really cool ! . . . All the civil and military chanted: prime minister poetry! , So a life courtiers speed printing artisans stereotyped to spread world.

Fragment II: proofs out to Cao Cao look, feel wrong Cao Cao, said: drink and sing, too vulgar remark, it should be for the wine and song better, so this minister ordered craftsmen to start over. Seeing stereotype of artisans night work, completely in vain, heart complain incessantly, he had to do so.

Fragments of three: proofs out again, please look over Cao Cao, Cao Cao thin a product, think it is not good, that life is too cool too direct, should be replaced by language enough to ask a mood, and therefore should read: wine and song, life geometry ? When the courtiers tell craftsmen, artisans fainted. . .

Three Kingdoms, yet there are movable type, so when you want to change the word, we must all re-engraved the whole stereotype, but with movable type, you only need to change the words, and the rest did not work for nothing, would not Miaozai!

Maintainable : to change, just change the word to change it;
Reusable : These words are not used up on useless, can be reused in subsequent printing;
Extensible : If you want to add the word poem, only subject lettering can be added;
good flexibility : arrange words can be horizontal, vertical can be, you can move only need to type;

Before movable type appeared, the above four features are not satisfied, you want to modify, must be re-engraved; to add words, you must re-engraved; To rearrange, must be re-engraved; after India finished the book, this version is no longer any the value of reuse.
Four great inventions of ancient China, gunpowder, the compass, papermaking are technological advances, and movable type is the ideological success, object-oriented victory. So how to write easy to maintain, easy to expand, and easy calculator program reuse it?

Multiplexing is not a copy, there is a programming principle is as much as possible to avoid duplication .

Calculator calculates and displays can be divided, i.e. business logic and interface logic, will be packaged into a computing business class, separated from the display interface, the business end of the code is as follows:

public class Operation{
    public static double GetResult(double numberA,double numberB,String strOperate){
        double result = 0;

        switch (strOperate){
            case "+":result = numberA + numberB;break;
            case "-":result = numberA - numberB;break;
            case "*":result = numberA * numberB;break;
            case "/":result = numberA / numberB;break;
        }
        return result;
    }
}

Client code as follows:

import java.util.Scanner;

public class SimpleFactoryModel {

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

        try {
            System.out.println("请输入数字A: ");
            double numberA = in.nextDouble();

            System.out.println("请选择运算符号(+ - * /): ");
            String strOperate = in.next();

            System.out.println("请输入数字B: ");
            double numberB = in.nextDouble();
            if(strOperate.equals("/") && numberB==0){
                System.out.println("请重新输入数字B(除数不能为0): ");
                numberB = in.nextDouble();
            }

            double result = Operation.GetResult(numberA,numberB,strOperate);
            System.out.println("结果是:"+result);

        }catch (Exception e){
            System.out.println("您的输入有错:"+e.getMessage());
        }
    }
}

The code above did consider object-oriented, but only used three characteristics of object-oriented one: package , two other characteristics of inheritance and polymorphism can also be applied is not it?

Side dishes: You're such a small calculator program can also be used in object-oriented three characteristics, how inheritance and polymorphism may need them, I really can not understand
bird: very inquiring mind Well, let me see your skill deepen the level, you first think about it, the code now can be flexible it can be modified and extended
side dishes: business and the interface has been separated Yeah, not very flexible yet
Big bird: Let me ask you now want to add a square root calculation (sqrt), how do you change the
side dishes: operation only need to modify the class, plus a branch in the switch can be a
bird: so the question is, you just open with a plus operation, but let Math the operations are involved in compiling , if you accidentally put into the addition subtraction, it's not too bad! Figuratively, the company now requires you to maintain the company's payroll system, originally only technical staff (salary), sales and marketing staff (basic salary + commission), managers (salary + stock) three operations algorithm, now to increase part-time workers (hourly) algorithm, in accordance with the wording you before, the company should give you the original class includes operation of the three algorithms, allow you to modify, if your heart beat a little thinking, TMD, the company gave my salary so low, I was really depressed, Oh, let me taking it every chance, so you increase the outside part-time algorithm, added the technical staff (salary) algorithm

if(员工是小菜)
	salary = salary * 1.1;

That means your monthly salary will increase by 10%, would have been to add a feature, allows the original run good code generation has changed, the risk is too great, you understand the
side dishes: Oh, your mean, I should separate operation such as addition, subtraction, modify one without affecting the other a few, add a new operation algorithm does not affect other code, is that right
bird: they want it, how to use inheritance and state
. . .
Idea is as follows:
1. Mathematical:

/**
 *角色:抽象产品 Product
 * 职责:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
 */
public abstract class Operation{ 
    private double numberA = 0;
    private double numberB = 0;

    public double getNumberA() {
        return numberA;
    }
    public void setNumberA(double numberA) {
        this.numberA = numberA;
    }
    public double getNumberB() {
        return numberB;
    }
    public void setNumberB(double numberB) {
        this.numberB = numberB;
    }

    public abstract double GetResult();
}

2. The addition operation type class inherits

/**
 * 角色:具体产品 Concrete Product
 * 职责:简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例
 */
public class OperationAdd extends Operation {
    @Override
    public double GetResult(){
        return getNumberA() + getNumberB();
    }
}

There are similar classes subtraction, multiplication and division based categories as follows:

public class OperationSub extends Operation{
    @Override
    public double GetResult(){
        return getNumberA() - getNumberB();
    }
}

public class OperationMul extends Operation {
    @Override
    public double GetResult() {
        return getNumberA() * getNumberB();
    }
}

public class OperationDiv extends Operation {
    @Override
    public double GetResult() {
        return getNumberA()/getNumberB();
    }
}

3. DETAILED factory class is responsible for instantiating objects which

/**
 * 角色:工厂 Creator
 * 职责:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。
 *      工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
 */
public class OperationFactory {
    public static Operation createOperate(String operate){ //operate是运算符
        Operation operation = null; //operation是实例化对象
        //只需要输入运算符号,运算类工厂就可以实例化出合适的对象,通过多态,返回父类的方式实现计算结果
        switch (operate){
            case "+":
                operation = new OperationAdd();
                break;
            case "-":
                operation = new OperationSub();
                break;
            case "*":
                operation = new OperationMul();
                break;
            case "/":
                operation = new OperationDiv();
                break;
            case "@"://以@符号表示两数之和的开跟运算,在添加新的运算方式时,在case分支中要记得添加具体的实例化对象
                operation = new OperationSqrt();
                break;
        }
        return operation;
    }
}

4. client code:

/**
 * 什么是工厂:用一个单独的类来做这个类创造实例的过程,这就是工厂
 * 简单工厂模式解决了对象的创建问题
 * 在已知某些条件后,对于类的选择(这些待选择的类都是同一父类的子类)时使用简单工厂模式
 */
import java.util.Scanner;
public class SimpleFactoryModel {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        try {
            System.out.println("请输入数字A: ");
            double numberA = in.nextDouble();

            System.out.println("请选择运算符号(+ - * /): ");
            String strOperate = in.next();

            System.out.println("请输入数字B: ");
            double numberB = in.nextDouble();
            if(strOperate.equals("/") && numberB==0){
                System.out.println("请重新输入数字B(除数不能为0): ");
                numberB = in.nextDouble();
            }

            Operation operation;
            operation = OperationFactory.createOperate(strOperate); //实例化运算类
            operation.setNumberA(numberA); //确定运算数字
            operation.setNumberB(numberB);
            double result = operation.GetResult(); //调用方法得到运算结果
            System.out.println("结果是:"+result);

        }catch (Exception e){
            System.out.println("您的输入有错:"+e.getMessage());
        }
    }
}

So if we want to modify the adder, OperationAdd only need to modify it, if the other operators to increase the square root operation, as long as the corresponding increase in operator class, and modify the operation type plants, increase in a switch branch.
Such as increasing the number of open and with two operation, to increase the sub-categories, the branch has been increased in the previous code

public class OperationSqrt extends Operation {
    @Override
    public double GetResult() {
        double mul = getNumberA()+getNumberB();
        return Math.sqrt(mul);
    }
}

to sum up:

Simple methods createOperate by factory class to instantiate specific object (a subclass of the class of operation), is between the operator and the dependency type, operation type and addition type, etc. subtraction is inheritance.

A small calculator can also write good code, the programming is an art, it is an art, not just be satisfied with the results of written code to run properly on the bin, one should always consider how to make the code more concise and easier maintenance, easy to extend and reuse, the only way to truly improve.

This is just the beginning to understand object-oriented, come on with it!

Published 22 original articles · won praise 21 · views 6973

Guess you like

Origin blog.csdn.net/weixin_43108122/article/details/104551007