设计模式 - 工厂方法模式

定义:定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式在简单工厂模式的基础上抽象出了工厂接口,将创建产品的工作推迟到实现工厂接口的具体工厂类中,当我们需要增加一个产品的时候,简单工厂模式下需要对工厂类进行修改,这就违反了对修改封闭的原则,而工厂方法模式就弥补了这个不足之处,接下来我们来看下工厂方法模式的结构类图

主要可以分为四类:其一是产品接口;其一是具体的产品类;其一是工厂接口,其中包含一个创建创建产品的接口;还有就是用来生产具体产品的具体工厂类,当我们需要增加一个产品的时候,只需要增加一个具体的产品类和具体的工厂类,不会对原来的代码有任何的修改。接下来看下具体的代码实现

产品接口

public interface Product {
    void use();
}

两个具体的产品类

public class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("使用产品A");
    }
}
public class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("使用产品B");
    }
}

工厂接口

public interface Factory {
    Product createProduct();
}

具体的工厂类

public class ConcreteFactoryA implements Factory {

    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}
public class ConcreteFactoryB implements Factory {

    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

测试类的调用和输出结果

Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.use();

Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.use();

相比与简单工厂模式,我们不需要在工厂类中判断要创建哪种的产品类,但是却将判断的逻辑移到了测试客户端代码中,客户端要知道该创建哪种工厂对象才能创建出需要的产品对象。上述代码并没有逻辑判断的代码,我们通过将简单工厂模式中的简单计算器的例子使用工厂方法模式来实现,就能清晰的看到其中逻辑判断的转移,具体的实现代码如下,其中产品接口和具体的产品类与简单工厂的一致就不贴出来了

运算工厂接口

public interface OperationFactory {
    AbstractOperation createOperation();
}

具体的运算工厂类(只贴出来一个,其他类似)

public class OperationAddFactory implements OperationFactory {
    @Override
    public AbstractOperation createOperation() {
        return new OperationAdd();
    }
}

最后就是拥有条件判断的客户端代码和输出(随用户的输入变化而变化)

Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字A:");
double numberA = scanner.nextDouble();
System.out.println("请输入运算符号:");
String operationType = scanner.next();
System.out.println("请输入数字A:");
double numberB = scanner.nextDouble();
OperationFactory of;
switch (operationType) {
    case "+":
        of = new OperationAddFactory();
        break;
    case "-":
        of = new OperationSubFactory();
        break;
    case "*":
        of = new OperationMulFactory();
        break;
    case "/":
        of = new OperationDivFactory();
        break;
    default:
        throw new RuntimeException("输入的运算符号错误:" + operationType);
}
AbstractOperation operation = of.createOperation();
operation.setNumberA(numberA);
operation.setNumberB(numberB);
System.out.println(operation.getResult());

以上就是整个功能的实现代码,可以通过点击以下链接获取代码和类图

代码和类图

posted @ 2019-02-28 09:12  回忆成长  阅读(304)  评论(0编辑  收藏  举报