zoukankan      html  css  js  c++  java
  • 策略模式 详解

    定义

    Strategy定义了一系列的算法,并且将每个算法封装来,而且使它们还可以相互替换;策略模式让算法独立于使用它的客户而独立变化;

    角色

    • 环境类(Context):用一个ConcreteStrategy对象来配置,维护一个对Strategy对象的引用,可定义一个接口来让Strategy访问它的数据;
    • 抽象策略类(AbstractStrategy):定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法;
    • 具体策略类(ConcreteStrategy): 以Strategy接口实现某具体算法;

    从网上找到的类图
    enter image description here

    适用场景

    • 许多相关的类仅仅是行为有异,“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态的在几种策略中选择一种;
    • 需要在不同情况下使用不同的策略,或者策略还可能在未来用其他方式来实现;
    • 需要对客户隐藏复杂的、与算法相关的数据结构;
    • 一个类定义了多种行为,并且这些行为在这个类中以多个条件语句的形式出现;

    例子

    比如鸟和鸟类的行为,鸟有很多种,有会飞的,也有不会飞的,有吱吱叫的,也有呱呱叫的等等,这个时候,我们可以将鸟作为Context,也就是环境类,各种不同的鸟类作为具体的ConcreteContext,继承自鸟类,然后将鸟类的行为作为一个鸟类的接口,比如飞的行为,叫的行为,这些行为分别是Strategy,再在这些行为下面包括具体的行为,继承行为,实现行为的接口,也就是ContreteStrategy;


    实现代码

    var Shipping = function () {
        this.company = "";
    };
    
    Shipping.prototype = {
        selectExpress : function(company) {
            this.company = company;
        },
    
        caculate : function(package) {
            return this.company.caculate(package);
        }
    };
    
    var ShunFeng = function () {
        this.caculate = function (package) {
            return 4.5 * package.weight;
        }
    };
    
    var ShenTong = function () {
        this.caculate = function (package) {
            return 4.8 * package.weight;
        }
    };
    
    var EMS = function () {
        this.caculate = function (package) {
            return 5.0 * package.weight;
        }
    };
    
    var log = (function () {
        var log = "";
    
        return {
            add : function(msg){
                log += msg + "$ 
    ";
            },
            show : function(){
                console.log(log);
                log = "";
            }
        }
    })();
    
    function run()
    {
        var package = {weight : 40};
    
        var sf = new ShunFeng();
        var st = new ShenTong();
        var ems = new EMS();
    
        var shipping = new Shipping();
    
        shipping.selectExpress(sf);
        log.add("ShunFeng :" + shipping.caculate(package));
        shipping.selectExpress(st);
        log.add("ShenTong :" + shipping.caculate(package));
        shipping.selectExpress(ems);
        log.add("EMS :" + shipping.caculate(package));
    
        log.show();
    }
    
    run();
    
    

    其实这就是一个选择快递公司,然后计算价钱的例子;


    优缺点

    注意的是

    • 客户必须要知道所有的策略类,并且自行决定使用哪一个策略类;
    • Strategy和Context之间的通信开销;因此很可能某些 ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息;简单的 ConcreteStrategy可能不使用其中的任何信息
    • 策略模式会造成很多的策略类,难以管理;

    关注公众号:数据结构与算法那些事儿,每天一篇数据结构与算法

  • 相关阅读:
    字符串初始化、查找字符+获取字符
    冒泡排序
    JAVA中值类型和引用类型的不同?
    二维数组初始化,属性,遍历,输出各元素总和。
    数组定义属性遍历循环,输出最大数
    for穷举,叠代练习
    HTML--Boby部分之<a>标签
    HTML--Boby内标签之多行文本及下拉框
    HTML--Boby部分Input之重置
    HTML--Boby部分Input之上传文件
  • 原文地址:https://www.cnblogs.com/George1994/p/6037630.html
Copyright © 2011-2022 走看看