风也温柔

计算机科学知识库

设计模式(十八)策略模式(对象行为型)(组图)

   (十八) ( Type)1. 类似的情况在软件开发中经常会遇到。实现某个功能有多种算法或策略。选择不同的算法或策略来完成这个函数。比如搜索、排序等,常用的方法是在一个类中硬编码(),如果需要提供多种搜索算法,可以将这些算法写到一个类中,在这个类中提供多个方法,每个方法对应于

  

  大家好,我是建筑师,一个会写代码,会背诗的建筑师。今天讲一下设计模式(十八)策略模式(对象行为类型),希望能帮助大家提高!!!

  设计模式(十八)策略模式(对象行为类型)

  1.概览

  在软件开发中经常会遇到类似的情况。有多种算法或策略来实现某个功能。我们可以根据不同的环境或条件选择不同的算法或策略来完成功能。比如搜索、排序等,常用的方法是在一个类中硬编码(Hard)。如果需要提供多种搜索算法,可以将这些算法写成一个类,在这个类中提供多个方法。一个方法对应一个特定的搜索算法;当然,这些搜索算法也可以封装在一个统一的方法中,通过if...else...or case等条件判断语句进行选择。这两种实现方式可以称为硬编码。如果您需要添加新的搜索算法,需要修改封装算法类的源码;替换搜索算法,还需要修改客户端调用代码。大量的搜索算法都封装在这个算法类中,这个类的代码会比较复杂,难以维护。如果我们在客户端包括这些策略,这种做法就更不可取了,而且客户端程序会很大,很难维护,如果有大量的算法可供选择,问题会更加严重。

  示例 1:菜单功能可以根据用户的“皮肤”偏好来决定是使用水平排列还是垂直排列。同事可以灵活增加菜单的显示风格。

  示例 2:旅行:我们可以考虑几种策略:我们可以骑自行车、汽车、火车、飞机。每种策略都可以达到相同的结果,但它们使用不同的资源。选择基于成本、时间、工具和易用性的策略。

  设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

  2.问题

  如何将算法与对象分离,以便算法可以独立于使用它的客户端而变化?

  3.解决方案

  3.解决方案

  :定义一系列算法,封装各个算法,让它们可以互换。这种模式允许算法独立于使用它的客户端而变化。也称为策略模式()。(的,每个人,他们。让 from 使用它。)

  策略模式将对象本身与操作规则区分开来,其功能非常强大,因为这种设计模式本身的核心思想就是面向对象编程的多态思想。

  4.适用性

  使用模式时

  1)• 许多相关的类只是表现不同。“策略”提供了一种方法来配置具有几种行为之一的类。也就是说,系统需要动态选择几种算法中的一种。

  2)• 需要使用不同的算法变体。例如,您可以定义一些反映不同空间/时间权衡的算法。当这些变体被实现为算法的类层次结构时,可以使用策略模式。

  3)• 算法使用客户不应该知道的数据。策略模式可用于避免暴露复杂的、与算法相关的数据结构。

  4)• 一个类定义了多个行为,这些行为在类的操作中表现为多个条件语句。将相关的条件分支移动到它们各自的类中以代替这些条件语句。

  5.结构

  设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

  6.图案的构成

  环境类():使用对象进行配置。维护对对象的引用。可以定义接口以允许访问其数据。

  s():为所有支持的算法定义公共接口。使用此接口调用定义的算法。

  具体策略类():用接口实现特定算法。

  7.效果

  模式具有以下一些优点:

  1) 一个相关的算法族类层次结构定义了一组可重用的算法或行为。继承有助于提取这些算法中的通用功能。

  2) 提供了继承关系的替代方案:继承提供了另一种支持多种算法或行为的方式。您可以直接子类化一个类以赋予它不同的行为。但这会将行为硬连接到其中,将算法的实现与算法的实现混合在一起,使其难以理解、难以维护、难以扩展,也无法动态更改算法。你最终会得到一堆相关的类,它们之间的唯一区别是它们使用的算法或行为。将算法封装在单独的类中可以让您独立于它进行更改,使其易于切换、易于理解、易于扩展。

  3) 消除一些 if else 条件:模式提供了一种替代方法,可以使用条件选择所需的行为。当不同的行为堆叠在一个类中时,很难避免使用条件语句来选择合适的行为。将行为封装在单独的类中消除了这些条件语句。带有许多条件语句的代码通常意味着使用模式。

  4) 实现的选择模式可以提供相同行为的不同实现。客户可以根据不同的时间/空间权衡要求,选择不同的策略。

  模式缺点:

  1)客户端必须了解所有策略类并自行决定使用哪一个:这种模式的一个潜在缺点是客户端必须知道它们之间的区别才能选择合适的。此时您可能必须向客户端公开特定的实现问题。因此,仅当这些不同的行为变体与客户相关的行为相关时,才需要模式。

  2)和之间的通信开销:无论各个实现所实现的算法是简单还是复杂,它们都共享定义的接口。所以很可能有些人不会使用通过这个接口传递给他们的所有信息;根本就不能用任何一个!这意味着有时会创建和初始化从未使用过的参数。如果存在这样的问题,那么 和 之间将需要更紧密的耦合。

  3)策略模式会产生大量的策略类:使用享元模式可以在一定程度上减少对象的数量。增加对象的数量会增加应用程序中的对象数量。有时,您可以通过实现为所有人共享的无状态对象来减少这种开销。任何剩余状态由 维护。此状态在对对象的每个请求中传递。 不应在调用之间保持状态。

  8.实现

  1)旅行:

  微升:

  设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

  代码:

  <pre class="language-java prettyprint linenums">`/**

  • 出行旅游
    */

interface TravelStrategy {

void travelAlgorithm();

}
/**

  • 策略模式
  • 定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化
    *
  • Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
    *
  • @Author guisuhuang
  • @Date 2022/4/13
    */

/**

  • Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
    *
  • @Author guisuhuang
  • @Date 2022/4/13
    */

/**

  • 具体策略类(ConcreteStrategy)1:乘坐飞机
    */

class AirPlanelStrategy implements TravelStrategy {

@Override
public void travelAlgorithm() {
    System.out.println("travel by AirPlain\r\n");
}

}
/**

  • 具体策略类(ConcreteStrategy)2:乘坐火车
    */

class TrainStrategy implements TravelStrategy {

@Override
public void travelAlgorithm() {
    System.out.println("travel by Train\r\n");
}

}
/**

  • 具体策略类(ConcreteStrategy)3:骑自行车
    */

class BicycleStrategy implements TravelStrategy {

@Override
public void travelAlgorithm() {
    System.out.println("travel by Bicycle\r\n");
}

}
/**
*

  • 环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
  • 算法解决类,以提供客户选择使用何种解决方案:
    */

class PersonContext {

private TravelStrategy strategy;
public PersonContext(TravelStrategy travel) {
    this.strategy = travel;
}
public void setTravelStrategy(TravelStrategy travel) {
    this.strategy = travel;
}
/**
 * 旅行
 */
public void travel() {
    strategy.travelAlgorithm();
}

}
public class client {

public static void main(String[] args) {
    // 乘坐火车旅行
    PersonContext person = new PersonContext(new TrainStrategy());
    person.travel();
    // 改骑自行车
    person.setTravelStrategy(new BicycleStrategy());
    person.travel();
}
pre>

  只听到建筑师办公室传来建筑师的声音:

  时代在人墟,等林长大,张总伺候请你喝酒。谁将向上或向下匹配?

  2)解决策略:系统提供了一个对数组数据进行操作的类,封装了对数组的常用操作。

  比如查找数组元素,排序数组元素等。现在以排序操作为例,使用策略模式设计数组操作类,

  它使客户端能够动态改变排序算法,可以根据需要选择冒泡排序、选择排序或插入排序,

  也可以灵活添加新的排序算法。

  通常我们使用工厂方法根据条件创建不同的策略模式:

  <pre class="language-java prettyprint linenums">此代码由Java架构师必看网-架构君整理 `/**

  • 策略模式
  • 定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化
    */

/**

  • 具体策略类(ConcreteStrategy)2:乘坐火车
    */

class TrainStrategy implements TravelStrategy {

public static final String TYPE = "Train";
@Override
public void travelAlgorithm() {
    System.out.println("travel by Train");
}

}
/**

  • 具体策略类(ConcreteStrategy)3:骑自行车
    */

class BicycleStrategy implements TravelStrategy {

public static final String TYPE = "Bicycle";
@Override
public void travelAlgorithm() {
    System.out.println("travel by Bicycle");
}

}
class AirPlanelStrategy implements TravelStrategy {

public static final String TYPE = "AirPlane";
@Override
public void travelAlgorithm() {
    System.out.println("travel by AirPlain");
}

}
class StrategyFactory {

private static final Map strategies = new HashMap();
static {
    strategies.put(AirPlanelStrategy.TYPE, new AirPlanelStrategy());
    strategies.put(TrainStrategy.TYPE, new TrainStrategy());
    strategies.put(BicycleStrategy.TYPE, new BicycleStrategy());
}
public static void register(String type, TravelStrategy travelStrategy) {
    strategies.put(type, travelStrategy);
}
public static TravelStrategy getStrategy(String type) {
    return strategies.get(type);
}

}
public class client {

public static void main(String[] args) {
    TravelStrategy travelStrategy = StrategyFactory.getStrategy(TrainStrategy.TYPE);
    travelStrategy.travelAlgorithm();
    TravelStrategy travelStrategy2 = StrategyFactory.getStrategy(BicycleStrategy.TYPE);
    travelStrategy2.travelAlgorithm();
}
pre>

  9、与其他模式相关

  1)状态模式

  策略模式与许多其他设计模式非常相似。策略模式和状态模式最大的区别在于策略模式只执行一次条件选择,而状态模式则是随着实例参数(对象实例的状态)的变化不断地改变执行模式。换句话说,策略模式就是

  对象初始化时改变执行模式,状态模式是根据对象实例的循环时间动态改变对象实例的执行模式。

  •

  能

  按环境类状态的数量

  来决定是使用策略模式还是状态模式。

  •

  策略模式的环境类自己选择具体的策略类,具体的策略类不需要关心环境类

  ;和

  状态模式的环境类需要因外部因素而进入特定的状态。

  为了通过它的方法实现状态切换

  ,所以

  环境类和状态类之间存在双向关系。

  •

  使用策略模式时,

  客户需要知道选择了哪种具体策略

  ,在使用状态模式时java实现旋转门算法

  客户端不需要关心具体的状态

  ,环境类的状态会根据用户的操作自动转换。

  •

  如果系统中某一类的对象存在多个状态,则不同状态下的行为是不同的,这些

  当状态之间可能发生转换时使用状态模式

  ;

  如果系统中有一个类的行为的多个实现,并且

  当这些实现可互换时使用策略模式

  .

  2)简单工厂的区别:点击打开链接

  工厂模式是一种创建模式,侧重于对象的创建,并提供创建对象的接口。让对象的创建与特定客户无关。

  策略模式是一种对象行为模式,侧重于对行为和算法的封装。它定义了一系列算法,封装了每个算法,并使其可以互换。使算法独立于使用它的客户端而变化

  以我们上面提到的旅行为例:

  我们去旅行。策略模式方式:有多种出行方式供您选择,选择火车还是自行车,完全由客户决定制定出行计划(例如,您需要购买火车票) ,或机票)。工厂模式是当你决定了哪个旅行计划之后,你不需要关注旅行计划是如何为你创建的,也就是说,你可以告诉我计划的名称设计模式(十八)策略模式(对象行为型)(组图),然后工厂会代表您制定具体计划(工厂将代替您购买)。火车票)。

  上例中的代码:

  $ = 新的(新的());

  $->();

  我们看到客户端需要自己创建具体的行程(new())实例。具体实例被传递。

  在工厂模式中,你只需要告诉你是什么样的旅行java实现旋转门算法,而不是传递一个具体的实例,而是一个标识符(旅行计划标识符)。

  10.总结与分析

  1)策略模式是一种比较容易理解和使用的设计模式,

  策略模式是算法的封装

  ,

  它将算法的职责与算法本身分开

  ,

  将管理委托给不同的对象

  . 策略模式通常

  将一系列算法封装成一系列策略类

  ,作为抽象策略类的子类。一句话,就是“准备一套算法,把每个算法都封装起来,让它们可以互换”。

  2)在策略模式下,应该由客户端决定

  在什么情况下使用什么特定的策略角色。

  2)

  3)

  策略模式只对算法进行封装,并提供新的算法插入到现有系统中

  ,以及旧算法从系统中“退出”的难易程度

  ,策略模式不决定何时使用哪种算法,算法的选择由客户端决定。这在一定程度上提高了系统的灵活性,但是客户端需要了解所有具体策略类之间的区别才能选择合适的算法,这也是策略模式的缺点之一,增加了使用客户在一定程度上。困难。

  转载注明原文出处:设计模式(十八)策略模式(对象行为类型)设计模式(十八)策略模式(对象行为类型)博客-CSDN博客_策略模式

  感谢大家的支持,我会继续努力的!扫码打赏,如你所说

  设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

  设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

  我想你会喜欢:

  文章来源:https://javajgs.com/archives/92037