设计模式-java工厂模式1(简单工厂模式+工厂方法模式)

java工厂模式1(简单工厂+工厂方法)

工厂模式负责将有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,而不必事先知道每次要实例化哪一个类,并且在创建对象时不会对客户端暴露创建逻辑,通过使用一个共同的接口来指向新创建的对象。

简单工厂模式

简单工厂模式主要是通过一个工厂类来实现对具体对象的创建,用户不需要知道创建对象的具体实现,它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类,简单工厂模式不属于23中设计模式之一,它主要含有三中角色

  1. 工厂类角色:根据客户需求决定具体要创建哪个类的对象。
  2. 抽象产品角色:是具体产品继承的父类或者实现的接口。
  3. 具体的产品角色:产品的具体实现,由工厂类创建根据需求创建对象。
    简单工厂模式的UML图如下
    简单工厂模式

下面采用基本的运算举例:
第一步:创建抽象的计算类

public abstract class Operation {
    public Operation(){}
    /**
     * 抽象的计算方法,具体实现放在子类中实现
     * @return 计算结果
     */
    public abstract double calculate(double number1,double number2);
}

第二步创建具体的计算类

/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:加法计算
 * Date:2017/11/27
 * Time:16:58
 */
public class AddOperation  extends Operation{
    public AddOperation(){
        super();
    }
    public double calculate(double number1 ,double number2) {
        return  number1 + number2;
    }
}
/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:减法计算
 * Date:2017/11/27
 * Time:17:00
 */
public class MinusOperation extends Operation {
    public MinusOperation(){super();}
    @Override
    public double calculate(double number1, double number2) {
        return number1 - number2;
    }
}

第三步:创建工厂类

public class CalculatorFactory {
    public static Operation createOperation(String opera ){
        Operation operation = null;
        switch (opera){
            case "+":
                operation = new AddOperation();
                break;
            case "-":
                operation = new MinusOperation();
                break;
        }
        return  null;
    }
}

第四步:测试

public class Test {
    public  static void main(String agrs[]){
        /**
         * 用户不用直接创建一个运算对象,
         * 只需要通过工厂获取一个运算对象
         * 运算对象的创建由计算的工厂实现
         */
        Operation operation = CalculatorFactory.createOperation("+");
        double result =  operation.calculate(1 ,2);
        System.out.print(result);
    }
}

简单工厂模式有一定的优点比如:用户不需要直接创建对象,仅仅使用对象就可以了,还有假如,某个需求需要在计算加法前有一些其他的操作,如果我们在代码里多次使用了new 加法计算,我们就需要在代码里多次修改,但是使用了简单工厂模式只需要修改工厂类就可以了,在工厂类中的获取加法计算前添加我们的新需求。

不过简单工厂模式也有缺点,比如:现在系统原来的计算不能满足新的需求了,我们需要加一个乘法运算。我们就需要完成下面的一些操作:
第一步增加乘法计算

/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:乘法计算
 * Date:2017/11/28
 * Time:9:38
 */
public class MultiplyOperation  extends Operation{
    public  MultiplyOperation(){super();}
    @Override
    public double calculate(double number1, double number2) {
        return number1 * number2;
    }
}

第二部修改工厂类

public class CalculatorFactory {
    public static Operation createOperation(String opera ){
        Operation operation = null;
        switch (opera){
            case "+":
                operation = new AddOperation();
                break;
            case "-":
                operation = new MinusOperation();
                break;
            case "*"://增加乘法的逻辑
                operation = new MultiplyOperation();
                break;
        }
        return  operation;
    }
}

经过上面的修改,虽然达到了我们的需求,可以计算乘法了,但是这样修改违反了设计模式的开闭原则(对扩展开放,对修改关闭),在这里我们增加了乘法计算类(对扩展开放),但是我们修改了计算工厂类(违反对修改关闭),所以我们这样是违反了开闭原则的。所以简单工厂模式适用于工厂类创建对象的类型比较少的情况下,但是一般不建议使用。

工厂方法模式

工厂方法模式是简单工厂模式的延伸,它完全实现‘开闭原则’,实现了可扩展。可以应用于产品结果复杂的场合。在工厂方法模式中工厂类不再负责所有的对象的创建,它将具体创建产品的工作交给子类工厂去做。这个工厂类是一个抽象工厂角色,负责给出具体子类工厂必须实现的接口,而不是决定哪一个产品类应当被实例化这种细节,实例化产品细节应该放在子类工厂中。
在工厂方法模式中设计到的角色有以下几种:
工厂方法模式的用例图大致为:
工厂方法模式
1. 抽象工厂角色:是工厂方法模式的核心,规定了子类工厂必须实现的方法,在模式中创建对象的工厂都要实现这个接口
2. 具体工厂角色:实现了抽象工厂模式的接口,它含有具体创建产品的逻辑,何时创建产品由它决定。
3. 抽象产品角色:是具体产品继承的父类或者实现的接口。规定了产品的公共特性
4. 具体产品角色:继承自抽象产品角色,由具体工厂角色创建。

下面还是使用算数计算的例子:
第一步:创建抽象产品角色

public abstract class Operation {
    public Operation(){}
    /**
     * 抽象的计算方法,具体实现放在子类中实现
     * @return 计算结果
     */
    public abstract double calculate(double number1,double number2);
}

第二步:创建具体的产品角色

/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:加法计算
 * Date:2017/11/27
 * Time:16:58
 */
public class AddOperation  extends Operation{
    public AddOperation(){
        super();
    }
    public double calculate(double number1 ,double number2) {
        return  number1 + number2;
    }
}
/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:减法计算
 * Date:2017/11/27
 * Time:17:00
 */
public class MinusOperation extends Operation {
    public MinusOperation(){super();}
    @Override
    public double calculate(double number1, double number2) {
        return number1 - number2;
    }
}

第三部:创建抽象工厂角色

public interface CalculatorFactory {
    /**
     * 创建计算方式
     * @return
     */
    public Operation createOperation( );
}

第四步:创建具体的工厂角色

/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:加法工厂
 * Date:2017/11/28
 * Time:11:06
 */
public class AddOperationFactory  implements  CalculatorFactory{
    @Override
    public Operation createOperation() {
        //这里可以做一些其他的操作
        return new AddOperation();
    }
}
/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:减法工厂
 * Date:2017/11/28
 * Time:11:07
 */
public class MinusOperationFactory implements CalculatorFactory {
    @Override
    public Operation createOperation() {
        //这里可以做一些其他的操作
        return new MinusOperation();
    }
}

第五步:测试

public class Test {
    public  static void main(String agrs[]){
        /**
         * 用户不用直接创建一个运算对象,
         * 只需要通过具体的工厂获取一个运算对象
         * 运算对象的创建由具体的工厂实现
         */
        CalculatorFactory add = new AddOperationFactory();
        Operation operation =  add.createOperation();
        double result =  operation.calculate(1 ,2);
        System.out.print(result);
    }
}

工厂模式方法中解决了简单工厂模式不符合开放封闭原则,假如我们现在需要增加一个乘法计算。只需要增加一个具体的乘法产品和乘法的工厂

/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:乘法
 * Date:2017/11/28
 * Time:9:38
 */
public class MultiplyOperation extends Operation{
    @Override
    public double calculate(double number1, double number2) {
        return number1 * number2;
    }
}
/**
 * Created by IntelliJ IDEA.
 * User:hubin
 * Description:乘法工厂
 * Date:2017/11/28
 * Time:14:26
 */
public class MultiplyOperationFactory implements  CalculatorFactory {
    @Override
    public Operation createOperation() {
        //这里可以做一些其他的操作
        return new MultiplyOperation();
    }
}

这样就不用修改原有的工厂,只需要增加一个乘法工厂就可以解决问题而不需要修改原来的代码,而且在创建计算对象采用相应的工厂创建,避免了直接new 对象的硬编码,便于修改。

猜你喜欢

转载自blog.csdn.net/hubin916/article/details/78646224