设计思想学习—工厂方法模式

简单工厂模式

主要内容

  • 简单工厂模式
  • 工厂方法模式

首先先来一个没有运用模式的普通案例
模拟计算器例子

public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("请输入第一个数字");
        String numA=sca.nextLine();
        System.out.println("请输入算数符号");
        String symbol=sca.nextLine();
        System.out.println("请输入第二个数字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        switch (symbol) {
        case "+":
            amount=first+second;
            break;
        case "-":
            amount=first-second;        
            break;
        case "*":
            amount=first*second;
            break;
        case "/":
            amount=first/second;
            break;
        }
        System.out.println(amount);
    }
}

简单工厂版

class Operation{
    public double getResult(){return 0.0;}
}
class Add extends Operation{
    public double getResult(double numA,double numB){
        return numA+numB;
    }
}
class Sub extends Operation{
    public double getResult(double numA,double numB){
        return numA-numB;
    }
}
class Mul extends Operation{
    public double getResult(double numA,double numB){
        return numA*numB;
    }
}
class Div extends Operation{
    public double getResult(double numA,double numB){
        return numA/numB;
    }
}
class OperationFactory{
    public Operation produce(String symbol){
        Operation operation=null;
        switch (symbol) {
        case "+":
            operation=new Add();
            break;
        case "-":
            operation=new Sub();
            break;
        case "*":
            operation=new Mul();
            break;
        case "/":
            operation=new Div();
            break;
        }
        return operation;
    }
}
public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("请输入第一个数字");
        String numA=sca.nextLine();
        System.out.println("请输入算数符号");
        String symbol=sca.nextLine();
        System.out.println("请输入第二个数字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        OperationFactory factory=new OperationFactory();
        Operation operation=factory.produce(symbol);
        amount=operation.getResult(first,second);
        System.out.println(amount);
    }
}

好处很显而易见了,简单工厂方法明确了各自的职责和权利,对于客户端来说不用在与具体的产品产生依赖关系。但是这里却违反了开闭原则,如果想要加入新的运算方法只能修改工厂方法,那么就引申出了GOF23种设计模式之一的工厂方法模式,首先来看下GOF和23种设计模式

GOF的23中设计模式

图片为转载

GoF
“四人帮”,又称Gang of Four,即Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides

创建型模式(5个):单例模式、原型模式、建造者模式、工厂模式、抽象工厂模式。

结构型模式(7个):桥接模式、外观模式、组合模式、装饰模式、适配器模式、代理模式、享元模式。

行为型模式(11个):迭代器模式、解释器模式、观察者模式、中介者模式、访问者模式、备忘录模式、状态模式、策略模式、模版方法模、命令模式、职责链模式式。

现在我们来回归工厂方法模式

工厂方法模式

先来看看实现了开闭原则的工厂模式代码

interface Factory{
    Operation creatOperation();
}
class AddFactory implements Factory{
    public Operation creatOperation(){
        return new Add();
    }
}
class SubFactory implements Factory{
    public Operation creatOperation(){
        return new Sub();
    }
}
class MulFactory implements Factory{
    public Operation creatOperation(){
        return new Mul();
    }
}
class DivFactory implements Factory{
    public Operation creatOperation(){
        return new Div();
    }
}
public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("请输入第一个数字");
        String numA=sca.nextLine();
        System.out.println("请输入算数符号");
        String symbol=sca.nextLine();
        System.out.println("请输入第二个数字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        Factory factory=null;
        //这里注意的是我们又把判断逻辑放在客户端这很不好
        //这个缺点先挂起,学习策略模式的时候一起解决
        switch (symbol) {
        case "+":
            factory=new AddFactory();
            break;
        case "-":
            factory=new SubFactory();
            break;
        case "*":
            factory=new MulFactory();
            break;
        case "/":
            factory=new DivFactory();
            break;
        }
        Operation operation=factory.creatOperation();
        amount=operation.getResult(first,second);
        System.out.println(amount);
    }
}

如果想要增加平方的方法就只有写一个平方类继承运算类,在写一个平方工厂实现工厂方法,然后客户端选择调用即可,而不用像简单工厂一样还要去加一个case

下面是简单工厂和工厂方法uml导图摘自《大话设计模式》
简单工厂
不符合开闭原则
工厂方法
只用增加相映的工厂和类

刚开始接触的时候我看了很多博客和书,却只是感觉到越来越复杂和麻烦,完全没有感受到这些方法带来的好处。毕竟纸上谈兵你是理解不了现实打战的种种,就像站在岸上学不会游泳一样。
但随着我一遍又一遍的尝试和自己项目经验的结合,然后回来研究拜读,发现又有不一样的收获,越看越能发现它的博大精深和迷人之处。
博客献给自己以及和我一样的小菜鸟,希望我们能在技术的道路上走得更远、更稳。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章