JAVA设计模式之策略模式 - Strategy

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

介绍

什么是策略模式(Strategy Pattern)

在软件开发过程中常常遇到这样的情况, 实现某一个功能有很多种算法或实现策略, 我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能. 如果将这些算法或者策略抽象出来, 提供一个统一的接口, 不同的算法或者策略有不同的实现类, 这样在程序客户端就可以通过注入不同的实现对象来实现算法或者策略的动态替换, 这种模式的可扩展性和可维护性也更高, 这就是策略模式.

策略模式的定义(Strategy Pattern)

策略模式: 定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立与使用算法的客户.(摘抄于Head First设计模式)

简单理解: 定义了一系列算法,每个算法封装起来,各个算法之间可以互相替换,且算法的变化不会影响到使用算法的客户,属于行为型模式.

使用场景

  1. 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
  2. 需要安全的封装多种同一类型的操作时;
  3. 出现同一抽象类有多个字类, 而有需要使用 if-else 或者 switch-case 来选择具体字类时;

例如:

或出现大量 if-else 判断时可以使用策略模式优化代码.

例如电商网站支付方式,一般分为银联,微信,支付宝,可以采用策略模式,每一种方式作为一种支付方式的实现,如果哪一个支付方式发生变化,只需要修改对应的实现即可,不需要修改调用的客户端,如果引入新的支付方式,如:随行付,则只需要增加一个对应的随行付实现类即可,遵循开闭原则.

组成部分(三个角色)

1. 抽象策略(Strategy):

通常由接口或抽象类实现. 定义了多个具体策略的公共接口, 具体策略中各种不同的算法以不同的方式实现这个接口; Context使用这些接口调用不同实现的算法.

2. 具体策略(ConcreteStrategy):

实现了Strategy接口或继承与抽象类, 封装了具体的算法和行为.

3. 环境类(Context):

持有一个公共策略接口的引用(Strategy), 直接给客户端调用.

优缺点及重点

优点:

  • 每个算法单独封装, 减少算法与算法调用者之间的耦合;
  • 算法可以自由切换;
  • 避免使用多重条件判断;
  • 扩展性良好;

缺点:

  • 策略类会增多.
  • 所有策略类都需要对外暴露.

重点

  • 给对象传入什么样的策略, 就执行什么样的动作.

实现

类图

说明: 代码来自Head First设计模式中SimUDuck的示例.

代码结构:

抽象策略(Strategy):

/**
 * 飞行行为
 */
public interface FlyBehavior {
    //各种飞行实现
    public void fly();

}

具体策略(ConcreteStrategy):

public class FlyWithWings implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I'm flying!");
    }
}

环境类(Context):

/**
 * 鸭子类
 */
public abstract class Duck {

    //持有一个公共策略接口的引用
    public FlyBehavior flyBehavior;
    public QuackBehavior quackBehavior;

    public void swim() {
        System.out.println("我会游泳...");
    }

    public abstract void display();

    public void performFly() {
        flyBehavior.fly();
    }

    public void performQuack() {
        quackBehavior.quack();
    }

    //提供set方法, 使鸭子可以动态改变飞行策略
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    //提供set方法, 使鸭子可以动态改变叫声策略
    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
}
/**
 * 绿头鸭
 */
public class MallardDuck extends Duck {

    @Override
    public void display() {
        System.out.println("绿头鸭");
    }

    public  MallardDuck() {
        /*MallardDuck 继承 Duck, 所以具有quackBehavior 和 flyBehavior实例变量
        当MallardDuck实例化时, 它的构造器会把继承的quackBehavior,
        flyBehavior实例变量初始化成Quack,FlyWithWings类型的新实例
         */
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }
}

测试类:

public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        //飞行
        mallard.performFly();
        //改变鸭子行为(传入飞行策略)
        mallard.setFlyBehavior(new FlyRocketPowered());
        mallard.performFly();
        //叫声
        mallard.performQuack();
    }

    执行结果:
    I'm flying!
    I'm flying with a rocket!
    呱呱叫

生活中的策略模式(我的猜想)

俗话说: 人是铁饭是钢, 一顿不吃饿的慌;吃饭也有策略模式, 你晓得嘛.

人(环境类)饿了要吃饭(抽象策略), 但是吃什么你知道吗? 这时你的大脑就会调集你的毕生功力(经验, 生活经历, 常识等等),来知道有哪些东西是可以吃的,比如鸡腿,面包或粥等等(具体策略,暴露所有策略).大脑选择(动态选择策略)吃其中的一种或多种食物来应对身体的不满.

生活中这样的例子还有很多,网上购物(不同的商品即: 具体策略), 世界那么大, 我想去转转.(转转的方式即: 具体策略)等.

结语

设计模式源于生活

原文地址:https://www.cnblogs.com/J-Simon/p/10885798.html

时间: 2024-08-08 17:53:42

JAVA设计模式之策略模式 - Strategy的相关文章

设计模式之策略模式(Strategy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

如何让孩子爱上设计模式 ——14.策略模式(Strategy Pattern)

如何让孩子爱上设计模式 --14.策略模式(Strategy Pattern) 描述性文字 本节讲解的是行为型设计模式中的第一个模式: 策略模式, 这个模式非常简单,也很好理解. 定义一系列的算法,把每个算法封装起来,并使得他们可以相互替换, 让算法独立于使用它的客户而变化. 一般用来替换if-else,个人感觉是面向过程与面向对象思想的 过渡,这里举个简易计算器的栗子,帮助理解~ 普通的if-else/switch计算器 普通的面向过程if-else简易计算器代码如下: 运行结果如下: 这里我

Java设计模式之策略模式(Strategy)

前言: 最近一直在学习基于okHttp网络请求,学习的过程中就想起了之前项目中有这么一个需求不同的接口要采用不同的加密方式,比如登录之前要采用RSA加密,登录之后要采用AES加密,当时是采用靠传递一个参数过去来对参数进行不同的加密算法,这样会让代码难以维护而且难以扩展,那该如何解决呢?今天来学习一下策略模式Strategy!用它来解决这个问题. 策略模式:        策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模

二十四种设计模式:策略模式(Strategy Pattern)

策略模式(Strategy Pattern) 介绍定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,持久化数据在SqlServer数据库中或Xml文件里(两种可互换的算法).由客户端决定使用哪种算法. MessageModel using System; using System.Collections.Generic; using System.Text; na

Java设计模式1——策略模式(Strategy Pattern)

最近觅得一本好书<您的设计模式>,读完两章后就能断言,一定是一头极品屌丝写的,而且是专写给开发屌丝男的智慧枕边书,小女子就委屈一下,勉强看看,人笨,谁让他写得这么通俗易懂呢!为了加深理解,用自己的方式记录下来. 上第一章的策略模式之前讲个故事,解释一下类设计的背景:刘备要去江东娶老婆,临走时诸葛亮给伴郎赵云三个锦囊妙计,嘱咐按天机拆开解决棘手问题.这才有了后来的周瑜赔了夫人又折兵.三个妙计放在锦囊中,赵云从锦囊中取妙计获胜.先看类图: 1.三个妙计是具体的实现类,我们设计一个接口,再写三个实现

Java 设计模式之 策略模式

思维导图: 我们先来看 STRATEGY 设计模式的通俗解释: 跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,但目的都是为了得到 MM 的芳心,我的追 MM 锦囊中有好多 Strategy 哦.策略模式: 策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换. 策略模式使得算法可以在不影响到客户端的情况下发生变化.策略模式把行为和环境分开.环境类负责维持和查询行为类,各种算法在具体的策略类中提供.由于算

折腾Java设计模式之策略模式

博客原文地址 简介 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.简单理解就是一组算法,可以互换,再简单点策略就是封装算法. 意图 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决 在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护. 何时使用 一个系统有许多许多类,而区分它们的只是他们直接的行为. 如何解决 将这些算法封装成一个一个的类,任意地替换. 主要角色 上下文C

java设计模式之——策略模式

1.策略模式有什么好处? 策略模式的好处在于你可以动态的改变对象的行为. 2.设计原则 设计原则是把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口(c++中可以用虚类),然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为.下面是一个例子. 策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响 到客户端的情况下发生变化.通常,策略模式适用于当一个应用程序需

JAVA中的策略模式strategy

原文出自:http://ttitfly.iteye.com/blog/136467 1. 以一个算术运算为例,传统做法为: java 代码 package org.common; public class Calculate { public String getResult(float a,float b,char c){ float add = a+b; float sub = a-b; float mult = a*b; float division = a/b; switch(c){ c