zoukankan      html  css  js  c++  java
  • 设计模式2:策略模式+简单工厂模式

    在简单工厂模式中,我们的客户端代码是这样的:

    public class SimpleFactoryDemo {
        public static void main(String[] args) {
            if(args.length == 0){
                System.out.println("Usage: java StrategyDemo operation num1 num2");
                return;
            }
            Operation operation = OperationFactory.createOperation(args[0]);
            operation.setNumA(Double.parseDouble(args[1]));
            operation.setNumB(Double.parseDouble(args[2]));
            double result = operation.getResult();
            System.out.println(result);
        }
    }

    客户端需要知道Operation类,使用setNumA,setNumB,getResult方法,这其实让客户端与Operation类存在了某种耦合关系

    为了解除这种耦合关系,我们在简单工厂模式中结合了策略模式。

    如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

    通俗的说,构造策略类时,我们传入一个对象,然后策略类调用这个对象的方法取得返回。这个对象可以是某个接口的任意子类,这样就让策略类拥有了根据对象来动态的决定方法的能力

    但是单纯的策略类有一大坏处,由于调用策略类需要先传入某个子类的对象,这就使得客户端代码与多个子类存在耦合。我们可以结合简单工厂模式使得客户端代码与多个子类代码解耦。

    策略模式UML图实例:

    请看代码,Operation及其子类:

    public abstract class Operation {
        private double numA = 0;
        private double numB = 0;
        
        public double getNumA() {
            return numA;
        }
    
        public void setNumA(double numA) {
            this.numA = numA;
        }
    
        public double getNumB() {
            return numB;
        }
    
        public void setNumB(double numB) {
            this.numB = numB;
        }
        
        public abstract double getResult();
    }
    
    public class OperationAdd extends Operation {
    
        @Override
        public double getResult() {
            return getNumA() + getNumB();
        }
    
    }
    
    public class OperationSub extends Operation {
    
        @Override
        public double getResult() {
            // TODO Auto-generated method stub
            return getNumA() - getNumB();
        }
    
    }
    
    public class OperationMul extends Operation {
    
        @Override
        public double getResult() {
            return getNumA() * getNumB();
        }
    
    }
    
    public class OperationDiv extends Operation {
    
        @Override
        public double getResult() {
            // TODO Auto-generated method stub
            return getNumA() / getNumB();
        }
    
    }

    OperationContext类:

    public class OperationContext {
        private Operation oper = null;
        
        public OperationContext(String operation) {
            switch (operation) {
            case "+":
                oper = new OperationAdd();
                break;
            case "-":
                oper = new OperationSub();
                break;
            case "*":
                oper = new OperationMul();
                break;
            case "/":
                oper = new OperationDiv();
                break;
            default:
                throw new IllegalArgumentException ("Unsupport operation!");
            }
        }
        
        public double getResult(double numA, double numB) {
            oper.setNumA(numA);
            oper.setNumB(numB);
            return oper.getResult();
        }
    }

    客户端:

    public class StrategyDemo {
        public static void main(String[] args) {
            if(args.length == 0){
                System.out.println("Usage: java StrategyDemo operation num1 num2");
                return;
            }
            OperationContext oc = new OperationContext(args[0]);
            double result = oc.getResult(Double.parseDouble(args[1]), 
                    Double.parseDouble(args[2]));
            System.out.println(result);
        }
    }
  • 相关阅读:
    git 拉取远程代码 git branch -vv --all
    常用命令统计
    topology key
    gstreamer 相关直播源(rtmp rtsp)
    汉诺塔问题 最简单的图文讲解递归实现
    RTP 用ffmpeg
    kurento + nodejs 开源项目 webRTC 转成 RTMP输出
    RTP SDP 详解 RTCP 附带说了一下SRTP RTSP
    RxSwiftCommunity/Action使用介绍
    zsh Shell 增加自动补全、语法高亮
  • 原文地址:https://www.cnblogs.com/zcy-backend/p/6646666.html
Copyright © 2011-2022 走看看