设计模式(Ⅲ)工厂方法模式+计算器类实现

793 阅读4分钟

工厂方法模式


一、模式定义

  • 工厂方法模式(Factory Method Pattern又称为工厂模式,也叫作虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建模型
  • 在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类
  • 工厂父类仅仅给出具体工厂必须实现的接口,而不负责哪一个产品被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品

二、模式结构

工厂方法模式包含四个角色:抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,即产品对象的共同父类或接口;具体产品实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,它们之间往往一一对应;抽象工厂中声明了工厂方法,用于返回一个产品,它是工厂方法模式的核心,任何在模式中创建对象的工厂类都必须实现该接口;具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例

工厂方法模式1.jpg

三、计算器问题

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();
    }
}
​
abstract class Operation{
    double a, b;
    abstract double getResult() throws Exception;
}
​
class Add extends Operation{
    double getResult(){
        return a + b;
    }
}
​
class Sub extends Operation{
    double getResult(){
        return a - b;
    }
}
​
class Mul extends Operation{
    double getResult(){
        return a * b;
    }
}
​
class Div extends Operation{
    if(b == 0){
        throw new Exception("除数不能为0");
    }
    return a / b;
}
​
public static void main(String[] args) throws Exception{
    Factory factory = new AddFactory();       //创建工厂
    Operation op = factory.creatOperation();  //创建产品
    op.a = 1;
    op.b = 2;
    double res = op.getResult();
}
类图

工厂方法模式2.jpg

四、优缺点

优点
  • 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名
  • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类
  • 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则
缺点
  • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销
  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度