设计模式 - 策略模式,就该这样学!

本文详细介绍了策略模式的概念,通过百货公司促销活动和博客系统文章发布的案例,展示了如何使用策略模式进行算法替换和策略选择,讨论了其优点(如易扩展和避免条件语句)以及缺点(客户端需知道所有策略)。
摘要由CSDN通过智能技术生成

目录

一、行为型模式

1.1、策略模式

1.1.1、概论

1.1.2、案例实现

1.1.3、案例实现(项目实战)

1.1.4、优缺点

1.1.5、使用场景


一、行为型模式


1.1、策略模式

1.1.1、概论

策略模式设计的每一个算法都封装了起来,使他们可以相互替换,通过一个对象委派不同的算法给相应的客户进行使用.

例如一家百货公司,规定在逢年过节的时候进行促销活动.  针对不同的节日(春节、中秋节、端午节)推出不同的促销活动,然后由 促销员 将促销活动展示给客户. 

策略模式主要角色如下:

  • 抽象策略类:由一个接口或者抽象类来实现,给出了所有 具体策略类 所需的接口.
  • 提交策略类:实现了抽下你个策略定义的接口,提供具体的算法实现.
  • 环境类:持有一个策略类引用,最终给客户端调用.

1.1.2、案例实现

针对以上案例进行实现.

/**
 * 抽象策略: 促销活动接口
 */
public interface Strategy {

    void show();

}
/**
 * 具体策略类: 春节活动类
 */
public class StrategyA implements Strategy {

    @Override
    public void show() {
        System.out.println("春节到了,全场买一送一!");
    }

}
/**
 * 具体策略类: 中秋节活动类
 */
public class StrategyB implements Strategy {

    @Override
    public void show() {
        System.out.println("中秋节到了,全场满 50 送月饼!");
    }

}
/**
 * 具体策略类: 端午节活动类
 */
public class StrategyC implements Strategy {

    @Override
    public void show() {
        System.out.println("端午节到了,全场满 80 送粽子!");
    }

}
/**
 * 环境类: 销售员类
 */
public class SalesMan {

    private Strategy strategy;

    public SalesMan(Strategy strategy) {
        this.strategy = strategy;
    }

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void showAction() {
        strategy.show();
    }

}
public class Client {

    public static void main(String[] args) {
        //1.春节
        SalesMan man = new SalesMan(new StrategyA());
        man.showAction();
        System.out.println("======================");
        //2.中秋节
        man.setStrategy(new StrategyB());
        man.showAction();
        System.out.println("======================");
        //3.端午节
        man.setStrategy(new StrategyC());
        man.showAction();
        System.out.println("======================");
    }

}

执行结果如下:

1.1.3、案例实现(项目实战)

在博客系统中,发布文章常常有很多种不同的状态,比如普通发布、私密发布、定时发布......  如果单纯使用 when 语句的话,会导致业务代码耦合度高.  因此这里非常适合使用策略模式,选择指定的策略来进行文章的发布.

data class Article (
    val title: String,
    val content: String,
)

//定义发布策略接口
interface ArticlePubStrategy {

    fun publish(article: Article)

}

//普通发布-策略实现
class NormalPubStrategy: ArticlePubStrategy {

    override fun publish(article: Article) {
        //实现普通发布逻辑
        println("normal article save to db! title: ${article.title}")
    }

}

//私密发布-策略实现
class PrivatePubStrategy: ArticlePubStrategy {

    override fun publish(article: Article) {
        //实现私密发布逻辑
        println("private article save to db! title: ${article.title}")
    }

}

//定时发布-策略实现
class TimedPubStrategy: ArticlePubStrategy {

    override fun publish(article: Article) {
        //实现定时发布逻辑
        println("time article save to db! title: ${article.title}")
    }

}

//环境类: 策略上下文,用来选择策略
class ArticlePubContext(
    var articlePubStrategy: ArticlePubStrategy
) {

    fun publish(article: Article) {
        articlePubStrategy.publish(article)
    }

}
fun main() {
    val pubContext = ArticlePubContext(NormalPubStrategy())
    val article = Article(
        title = "Spring | Home",
        content = "Level up your Java™ code. With Spring Boot in your app.",
    )
    //正常发布
    pubContext.publish(article)
    println("=========================================")
    //私密发布
    pubContext.articlePubStrategy = PrivatePubStrategy()
    pubContext.publish(article)
    println("=========================================")
    //定时发布
    pubContext.articlePubStrategy = TimedPubStrategy()
    pubContext.publish(article)
}

运行效果如下:

 

1.1.4、优缺点

优点:

  • 策略类之间可以自由切换:由于策略类都实现同一个接口,所以使得他们之间可以根据不同的需求场景任意切换.
  • 易扩展,符合开闭原则:增加一个新的的策略只需要添加一个具体的策略类即可,不需要修改原有代码.
  • 避免使用多重条件选择语句(if else),充分体现面向对象设计思想.

缺点:

客户端必须知道所有的策略类,并自行决定使用哪个策略类.

策略模式将造成产生多个策略类(一个策略产生一个类).

1.1.5、使用场景

  1. 一个系统需要动态的在几种算法中选择一种时,可以将每个算法封装到策略类中.
  2. 一个类定义了多个行为,并且这些行为在这个类中以多个条件语句(if else)出现,就可以将每个分支移入他们各自的策略类中以替代这些条件语句.
  3. 每个策略算法彼此独立,要对客户隐藏具体算法实现细节.

Design Patterns: Elements of Reusable Object-Oriented Software(以下简称《设计模式》),一书由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides合著(Addison-Wesley,1995)。这四位作者常被称为“四人组(Gang of Four)”,而这本书也就被称为“四人组(或 GoF)”书。他们首次给我们总结出一套软件开发可以反复使用的经验,帮助我们提高代码的可重用性、系统的可维护性等,解决软件开发中的复杂问题。设计模式已诞生20多年,其间相继出版的关于设计模式的经典著作不计其数。如果说GoF的《设计模式》是设计模式领域的“圣经”,那么之后出版的各种关于设计模式的书籍可称为“圣经”的“批注版”或者“白话版”。本书正是基于GoF的《设计模式》来编写的。  本课程由《设计模式就该这样》作者亲授,课程内容和书籍完全同步,可以作为作者对“圣经”实践的精华总结,是一门可以真正能够落地的“设计模式”的课程,也是目前全网唯一一门结合框架源码如何落地“设计模式”这个角度来理解设计模式的课程。本课程将结合JDK、Spring、MyBatis、Tomcat、Netty等经典框架源码展开对设计模式的分析。当然,本课程中还会结合作者多年的“踩坑填坑”经验和“教答疑”经验,用比“圣经”更深刻、更全面、更通俗、更生动、更有趣、更接地气的方式并且结合真实业务场景分析每种设计模式的优缺点,治愈“设计模式选择困难症”。选设计模式就像相亲选对象,一旦做好了接受TA缺点的准备,那TA就一定属于你。所以,本课程内容对于日常开发而言更具有指导意义。内容均从实战角度出发,在日常应用中,设计模式从来都不是单个设计模式独立使用的。在实际应用中,通常多个设计模式混合使用,你中有我,我中有你。下图完整地描述了设计模式之间的混用关系,希望对大家有所帮助。在《设计模式就该这样》一书中,还有大量的UML图及易混淆的设计模式对比案例分析,也欢迎大家关注。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈亦康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值