设计模式-工厂方法模式

    本篇文章主要讲解工厂方法模式。工厂方法模式:定义一个用于创建对象的接口,让子类去决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

    在看工厂方法模式之前先写个简单的计算器看下简单工厂。

    先看下结构图。

 设计模式-工厂方法模式

    接着看下代码实现。

    首先创建一个运算抽象类。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 运算抽象类
 * User: lwx
 * Date: 2019-03-09
 * Time: 20:45
 */
public abstract class Operation {

    double numberA = 0;
    double numberB = 0;

    abstract double getResult();

}

    然后是四种运算的实现类。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 加法实现类
 * User: lwx
 * Date: 2019-03-09
 * Time: 20:47
 */
public class OperationAdd extends Operation {

    double getResult() {
        return numberA + numberB;
    }

}
package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 减法实现类
 * User: lwx
 * Date: 2019-03-09
 * Time: 20:48
 */
public class OperationSub extends Operation {

    double getResult() {
        return numberA - numberB;
    }
}
package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 乘法实现类
 * User: lwx
 * Date: 2019-03-09
 * Time: 20:49
 */
public class OperationMul extends Operation {

    double getResult() {
        return numberA * numberB;
    }

}
package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 除法实现类
 * User: lwx
 * Date: 2019-03-09
 * Time: 20:51
 */
public class OperationDiv extends Operation {

    double getResult() {
        if (numberB == 0){
            throw new ArithmeticException("除数不能为0");
        }
        return numberA / numberB;
    }

}

    接着创建运算工厂类,根据运算符去创建对应的实现类。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 运算工厂类
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:06
 */
public class OperationFactory {

    public static Operation createOperation(String operate) {
        Operation operation = null;
        switch (operate) {
            case "+":
                operation = new OperationAdd();
                break;
            case "-":
                operation = new OperationSub();
                break;
            case "*":
                operation = new OperationMul();
                break;
            case "/":
                operation = new OperationDiv();
                break;
        }
        return operation;
    }

}

   最后是测试类和测试结果。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lwx
 * Date: 2019-03-09
 * Time: 20:59
 */
public class OperationTest {

    public static void main(String[] args) {
        Operation operation = OperationFactory.createOperation("+");
        operation.numberA = 5;
        operation.numberB = 10;
        System.out.println(operation.getResult());
    }

}

设计模式-工厂方法模式

    以上就是简单工厂的示例代码,只需要传入运算符号工厂类就可以自动返回对应的计算实现类。     

    接下来把上面的计算器改成工厂方法模式。

    老规矩先看下结构图。

设计模式-工厂方法模式

    在上面代码的基础上加入工厂接口类以及具体实现类,上面的运算工厂类就不用了。

    先创建一个工厂接口。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 工厂接口
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:15
 */
public interface Factory {

    Operation createOperation();

}

    然后是四种运算的具体实现工厂类。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 加法类工厂
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:16
 */
public class AddFactory implements Factory {

    @Override
    public Operation createOperation() {
        return new OperationAdd();
    }

}

 

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 减法工厂类
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:17
 */
public class SubFactory implements Factory {

    @Override
    public Operation createOperation() {
        return new OperationSub();
    }

}
package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 乘法工厂类
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:18
 */
public class MulFactory implements Factory {

    @Override
    public Operation createOperation() {
        return new OperationMul();
    }

}
package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description: 除法工厂类
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:19
 */
public class DivFactory implements Factory {

    @Override
    public Operation createOperation() {
        return new OperationDiv();
    }

}

    最后看下工厂方法模式的测试类和运行结果。

package com.lwx.factory;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lwx
 * Date: 2019-03-09
 * Time: 21:58
 */
public class FactoryTest {

    public static void main(String[] args) {
        Factory factory = new DivFactory();
        Operation operation = factory.createOperation();
        operation.numberA = 8;
        operation.numberB = 10;
        System.out.println(operation.getResult());
    }
    
}

设计模式-工厂方法模式

     简单工厂模式的优缺点:

     优点:

      1.简单工厂包含必要的逻辑判断,简单工厂实现了对象的创建和使用的分离。

      2.客户端无需知道所创建的集体产品类的类名,只需要知道具体产品类对应的参数即可。

      3.在不修改客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

    缺点:

      1.工厂类职责过重,从代码中可以看出简单工厂包含加减乘除的逻辑判断语句,它一旦有问题,整个系统都要出问题。

      2.再添加新类的时候,简单工厂类就要修改,违反了开放———封闭原则,这样不利于系统的扩展和维护。

    所以出现了工厂方法,工厂方法是简单工厂的进一步延伸,完美解决了开放——封闭原则的问题。  

    工厂方法模式的优缺点:

    优点:

      1.工厂方法用来创建客户所需的产品,同时隐藏了哪种具体产品类被实例化的细节,用户只需要关注工厂,不需要关注创建的细节。

      2.在增加新的运算类时不用修改代码,只需要增加对应的工厂就好,完全符合开放——封闭原则。

    缺点:

      1.在增加新的产品时,也必须增加新的工厂类,会带来额外的开销。

    俩个工厂各有利弊,简单工厂违反了最基本的原则,工厂方法完美解决了简单工厂的弊端,但是工厂方法的工厂个数过多,导致系统庞大。

    

    最后附上demo的githup地址:https://github.com/yijinqincai/design_patterns