设计模式--策略模式(由简单工厂到策略模式到两者结合图文详解+总结提升)

简介: 设计模式--策略模式(由简单工厂到策略模式到两者结合图文详解+总结提升)

概述

概念

    策略模式是一种行为型设计模式,它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

组成

1、Context(上下文):用于维护策略类的引用,并在运行时根据需要选择合适的策略。

2、Strategy(策略):定义一个公共接口,用于封装不同的算法或行为。

3、ConcreteStrategy(具体策略):实现策略接口,提供具体的算法或行为。

应用场景

    当一个系统需要根据不同的情况选择不同的算法或行为时,可以使用策略模式。

    当一个类中有多个条件语句,每个条件语句对应一个算法或行为时,可以考虑使用策略模式简化代码。

注意事项

    策略模式将算法或行为封装在不同的策略类中,因此需要对策略类进行合理的设计和组织。

    策略模式需要在运行时动态选择策略,因此需要在客户端代码中设置策略的选择逻辑。

类图

衍化过程

需求

    商场根据不同的促销活动,以不同的方式对商品进行折扣计算和结算。具体来说,商场收银的需求可以分为以下几个阶段的变化过程:

  1. 初始需求:商场最开始只有一种收费方式,即正常收费,即不打折不返现,直接按照原价进行结算。
  2. 变化需求1:商场决定进行促销活动,对部分商品进行打折处理。这时,商场需要根据商品的折扣率来计算折扣后的价格,并进行结算。
  3. 变化需求2:商场进一步决定进行满减活动,即满足一定条件后,可以返现一定金额。这时,商场需要根据商品的价格和满减条件来计算返现后的价格,并进行结算。
  4. 变化需求3:商场希望能够根据不同的促销活动,动态地选择不同的收费方式。这时,商场引入了策略模式,将不同的收费方式封装在不同的策略类中,并在运行时根据需要选择合适的策略进行结算。

前两版比较简单,这里不再赘述,主要从需求3说起:

    分为简单工厂实现、策略模式实现、简单工厂+策略模式

简单工厂实现

代码

收费相关类

//收费抽象类
abstract class CashSuper {
    public abstract double acceptCash(double money);
}
//正常收费类
public class CashNormal extends CashSuper {
    @Override
    public double acceptCash(double money) {
        return money;
    }
}
//打折收费类
public class CashRebate extends CashSuper {
    private double moneyRebate=1;
    public CashRebate(String moneyRebate){
        this.moneyRebate= Double.parseDouble(moneyRebate);
    }
    @Override
    public double acceptCash(double money) {
        return money*moneyRebate;
    }
}
//满减收费类
public class CashReturn extends CashSuper {
    private double moneyCondtion;
    private double moneyReturn;
    public CashReturn(String moneyCondition,String moneyReturn){
        this.moneyCondtion= Double.parseDouble(moneyCondition);
        this.moneyReturn= Double.parseDouble(moneyReturn);
    }
    @Override
    public double acceptCash(double money) {
        double result=money;
        if (money>=moneyCondtion){
            result=money-Math.floor(money/moneyCondtion)*moneyReturn;
        }
        return result;
    }
}

工厂

public class CashFactory {
    public  CashSuper creatCashAccept(String type) {
        CashSuper cs = null;
        switch (type){
            case "正常收费":
                cs=new CashNormal();
            break;
            case "满300返100":
                cs=new CashReturn("300","100");
            break;
            case "打八折":
                cs=new CashRebate("0.8");
                break;
        }
        return cs;
    }

客户端

public class Client {
    public static void main(String[] args) {
        CashFactory factory=new CashFactory();
        CashSuper cs=factory.creatCashAccept("满300返100");
        double result=cs.acceptCash(300);
        System.out.println(result);
    }
}

策略模式

类图

NS图

代码

收费上下文类

public class CashContext {
    private CashSuper cs;
    public CashContext(CashSuper csuper){
        this.cs=csuper;
    }
    public double getResult(double money){
        return cs.acceptCash(money);
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        //传的是不同的策略对象
        CashContext selectNormal = new CashContext(new CashNormal());
        CashContext selectRebate = new CashContext(new CashRebate("0.8"));
        CashContext selectReturn = new CashContext(new CashReturn("300","100"));
        System.out.println("选择正常:"+selectNormal.getResult(300));
        System.out.println("选择打八折:"+selectRebate.getResult(300));
        System.out.println("选择满减:"+selectReturn.getResult(300));
    }
}

策略模式+简单工厂

代码

收费上下文类(其中包括简单工厂)

public class CashContext {
   private CashSuper cs=null;
   //参数是个字符串,而不是收费策略对象
   public CashContext(String type){
       switch (type){
           case "正常收费":
               cs=new CashNormal();
               break;
           case "满300返100":
               cs=new CashReturn("300","100");
               break;
           case "打8折":
               cs=new CashRebate("0.8");
               break;
       }
   }
   public double getResult(double money){
       return cs.acceptCash(money);
   }
}

客户端

public class Client {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入销售模式:");
        String type = scanner.nextLine();
        //传的是字符串,而不是具体的策略类
        CashContext cash = new CashContext(type);
        System.out.println("请输入原价");
        double price = Double.parseDouble(scanner.nextLine());
        System.out.println("最后收费" + cash.getResult(price));
    }
}

总结升华

版本迭代的优化点及意义

1.前两版到简单工厂

     将算法封装,每一个优惠策略都是一个单独的类,而且它们都继承自一个抽象类,抽象类是此版本的一个巨大进步,出现了面向对象以及类的概念,后续的扩充、维护、复用打下了基础。

2.简单工厂到策略模式

    使用简单工厂违反开闭原则,考虑到了算法变化性,要这些算法随时可以互相替换,也正是策略模式概念中提到的,而封装变化点是面向对象一种重要的思维方式。

3.策略模式到简单工厂+策略模式

    策略模式中实例化对象还是交给了客户端去完成,结合了简单工厂之后,实例化对象由CashContext来完成,可以在客户端消除条件语句。

    另外,简单工厂模式客户端需要认识CashSuper和CashFactory,而简单工厂+策略模式,客户端之需要认识CashContext一个类就可以,降低了耦合性。

什么样的思路进行衍化的

有限到无限:

    依据业务需求,如果存在潜在的需要,就用无限的思维去进行设计(看到switch case就要思考是否需要无限的思维)

    如何去做到无限,使用想象力与创造力把有限的需求变成无限的需求,同时使用有限的方法去实现,落实到代码上是依据软件工程的7大原则和23个设计模式(独立或组合),达到可扩充、可复用、可维护的目标。

扩展思考–如何理解策略与算法

    策略模式中提到策略模式定义了算法家族,看类图的时候貌似策略和算法是一个概念,但是两者真的是一样的吗,如无必要勿增实体。那它们是什么关系呢,有没有一种可能,策略和算法并不是一一对应的关系,而独立算法和算法的组合都可以称之为策略呢,就像类图中Strategy与Context是聚合关系。这只是一个想法,策略模式也没有结束,后续还有策略模式+工厂方法+反射的实现,以及我所猜测的算法的组合也可称之为策略,敬请期待。

相关文章
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
70 14
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
97 4
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
163 8
「全网最细 + 实战源码案例」设计模式——策略模式
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
139 19
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
81 1
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
102 2
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
80 2

热门文章

最新文章

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问