zoukankan      html  css  js  c++  java
  • 设计模式笔记 工厂方法模式

      再简单工厂模式中,如果要添加新的产品,为了配合使用就必须修改工厂类,无疑这就破坏了”开放-闭合“原则。但是这也是简单工厂的优点,简单工厂类包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,取出来客户端对具体产品的依赖。为了解耦合和符合”开放-闭合“原则,工厂模式来了。

      定义:定义一个用于创建对象的工厂接口,让子类决定实例化哪一个类。核心工厂类成为一个抽象工厂角色,负责工厂子类必须实现的接口,达到添加新的产品时不必修改核心工厂类,而是添加工厂子类。

      UML类图如下

      继续沿用上篇简单工厂中的例子,实现如下。

      首先是产品类,这里是运算符类,两个操作数参数和一个运算方法,此处用的是抽象类:

    public abstract class Operation {
        private double numberA;
        private double numberB;
    
        public double getNumberA() {
            return numberA;
        }
    
        public void setNumberA(double numberA) {
            this.numberA = numberA;
        }
    
        public double getNumberB() {
            return numberB;
        }
    
        public void setNumberB(double numberB) {
            this.numberB = numberB;
        }
    
        public abstract double getResult();
    }
    

       具体产品衍生类,便是各个运算符的运算(加减乘除等),需要继承或实现产品类:

    public class OperationAdd extends Operation {
    
        @Override
        public double getResult() {
            return getNumberA() + getNumberB();
        }
    }
    public class OperationSub extends Operation {
    
        @Override
        public double getResult() {
            return getNumberA() - getNumberB();
        }
    }
    public class OperationMul extends Operation {
    
        @Override
        public double getResult() {
            return getNumberA() * getNumberB();
        }
    }
    public class OperationDiv extends Operation {
    
        @Override
        public double getResult() {
            return getNumberA() / getNumberB();
        }
    }
    

      其次是核心工厂类,是一个接口

    public interface IFactory {
        public Operation createOperation();
    }
    

       具体实现工厂的子类,便是各个运算符的运算(加减乘除等),需要实现核心工厂类:

    public class AddFactory implements IFactory {
        @Override
        public Operation createOperation() {
            return new OperationAdd();
        }
    }
    public class SubFactory implements IFactory {
        @Override
        public Operation createOperation() {
            return new OperationSub();
        }
    }
    public class MulFactory implements IFactory {
        @Override
        public Operation createOperation() {
            return new OperationMul();
        }
    }
    public class DivFactory implements IFactory {
        @Override
        public Operation createOperation() {
            return new OperationDiv();
        }
    }
    

       最后是客户端,调用

    public class POC {
        public static void main(String[] args) {
            coal();
        }
    
        public static void coal() {
            try {
                double numberA, numberB;
                String opr;
                @SuppressWarnings("resource")
                Scanner sc = new Scanner(System.in);
                System.out.print("输入第一个数字:");
                String numberAStr = sc.next();
    
                numberA = Double.parseDouble(numberAStr);
                System.out.print("输入操作符:");
                opr = sc.next();
    
                System.out.print("输入第二个数字:");
                String numberBStr = sc.next();
                numberB = Double.parseDouble(numberBStr);
    
                IFactory factory = null;
                switch (opr) {
                case "+":
                    factory = new AddFactory();
                    break;
                case "-":
                    factory = new SubFactory();
                    break;
                case "*":
                    factory = new MulFactory();
                    break;
                case "/":
                    factory = new DivFactory();
                    break;
    
                default:
                    factory = new AddFactory();
                    break;
                }
                Operation operation = factory.createOperation();
                operation.setNumberA(numberA);
                operation.setNumberB(numberB);
                System.out.println(numberAStr + opr + numberBStr + "=" + operation.getResult());
            } catch (Exception e) {
                System.out.println("输入有误,请重新开始。。。");
                coal();
            }
        }
    }
    

     

      可以看出添加产品时没有修改的变化,只有扩展的变化。但是,实例化工厂时选择判断的问题还是存在的,只是从工厂类移动到了客户端。但是,工厂方法模式既克服了简单工厂违背的设计原则,也保持了封装对象创建过程的优点,更换对象时不需要大范围的更改,降低了客户端与产品对象的耦合度。

      工厂方法模式是简单工厂的进一步抽象和推广,利用了多态性保证了简单工厂的优点克服了缺点。但是没有避免修改客户端代码的诟病还是存在,所以可以利用反射解决分支问题,关于这点,以后再谈。

  • 相关阅读:
    restful规范以及drf框架
    vue的第三方插件,vuex,axios,element-ui ,jq+bs
    路由,生命周期钩子函数,数据间的交互,全局配置js与css
    实例成员补充,项目环境配置以及vue组件
    vue指令实例成员
    初识vue
    django中如何暴露后端任意文件资源
    django中间件以及请求生命流程图
    wraps修饰器
    cookie与session
  • 原文地址:https://www.cnblogs.com/adamJin/p/7063451.html
Copyright © 2011-2022 走看看