java - 战略模式的真实世界示例

我一直在阅读有关OCP主要内容以及如何使用策略模式来实现这一目标。

我打算尝试向几个人解释这个,但我能想到的唯一例子是根据“订单”的状态使用不同的验证类。

我在线阅读了几篇文章,但这些文章通常没有描述使用该策略的真实原因,如生成报告/账单/验证等...

是否有任何现实世界的例子,您认为战略模式很常见?

16个解决方案
89 votes

那这个呢:

您必须加密文件。

对于小文件,您可以使用“内存”策略,其中读取完整文件并保存在内存中(假设文件<1 gb)

对于大型文件,您可以使用其他策略,其中部分文件在内存中读取,部分加密结果存储在tmp文件中。

对于同一任务,这可能是两种不同的策略。

客户端代码看起来一样:

 File file = getFile();
 Cipher c = CipherFactory.getCipher( file.size() );
 c.performAction();



// implementations:
interface  Cipher  {
     public void performAction();
}

class InMemoryCipherStrategy implements Cipher { 
         public void performAction() {
             // load in byte[] ....
         }
}

class SwaptToDiskCipher implements Cipher { 
         public void performAction() {
             // swapt partial results to file.
         }

}

     Cipher c = CipherFactory.getCipher( file.size() );

将为密码返回正确的策略实例。

我希望这有帮助。

(我甚至不知道Cipher是否是正确的词:P)

OscarRyz answered 2019-09-11T03:04:57Z
48 votes

同样,一个旧的帖子但仍然出现在搜索上,所以我将再添加两个例子(代码在C#中)。 我非常喜欢策略模式,因为当项目经理说:“我们希望应用程序执行'X',但'X'尚不清楚,它可以在不久的将来改变时,它已经节省了很多次。“该视频解释了战略模式,以星际争霸为例。

属于这一类的东西:

  • 排序:我们想对这些数字进行排序,但我们不知道是否要使用BrickSort,BubbleSort或其他一些排序

  • 验证:我们需要根据“一些规则”检查项目,但目前尚不清楚该规则是什么,我们可能会想到新的规则。

  • 游戏:我们希望玩家在移动时走路或跑步,但也许在将来,他还应该能够游泳,飞行,传送,挖洞等。

  • 存储信息:我们希望应用程序将信息存储到数据库,但以后可能需要能够保存文件或制作网络摄像头

  • 输出:我们需要输出X作为普通字符串,但后来可能是CSV,XML,JSON等。


例子

我有一个项目,用户可以将项目分配给数据库中的人员。 将产品分配给某人的状态为“已批准”或“已拒绝”,这取决于某些业务规则。 例如:如果用户将产品分配给具有特定年龄的人,则应拒绝其状态; 如果项目中两个字段之间的差异大于50,则其状态将被拒绝等。

现在,在开发的那一刻,这些业务规则尚未完全清楚,并且可以随时出现新规则。 stragety-pattern的强大之处在于我制作了一个RuleAgent,它给出了一个IRules列表。

public interface IRule {
    bool IsApproved(Assignment assignment); 
 }

在将产品分配给某个人的那一刻,我创建了一个RuleAgent,给它一个规则列表(所有规则都实现了IRule),并要求它验证一个赋值。 它将贯穿其所有规则。 其中,因为它们都实现了相同的接口,所有都有IsApproved方法,如果其中任何一个返回false,则返回false。

现在,例如经理突然出现并说,我们还需要拒绝所有实习生的任务,或者对加班工作人员的所有任务...你做了这样的新课程:

public OvertimeRule : IRule
{
    public bool IsApproved(Assignment assignment) //Interface method
    {
        if (assignment.Person.Timesheet >= 40)
        {
            return false;
        }
        return true;
    }
}

public InternRule : IRule
{
    public bool IsApproved(Assignment assignment) //Interface method
    {
        if (assignment.Person.Title == "Intern")
        {
            return false;
        }
        return true;
    }
}

您可以看到,您不必继续添加或删除if语句或代码,只需创建一个实现IRUle接口的新规则类,并在需要时将其切换出来。


另一个很好的例子:Scott Allen在[http://www.asp.net/mvc/pluralsight]上的视频系列,他在应用程序的单元测试部分使用策略模式

他建立了一个网站,其中有一个页面,根据受欢迎程度显示项目。 然而,“热门”可以是很多东西(大多数观点,大多数订阅者,创建日期,大多数活动,最少量的评论等),并且如果管理层还不知道如何订购,并且可能想要尝试不同的 以后的订单。 使用order方法创建接口(IOrderAlgorithm或其他东西),让Orderer-object将排序委托给IOrderAlgorithm接口的具体实现。 你可以创建一个“CommentOrderer”,“ActivityOrderer”等......当新的需求出现时,只需将它们切换出来。

Céryl Wiltink answered 2019-09-11T03:06:55Z
11 votes

我可以想到几个相当简单的例子:

  • 排序列表。 策略是比较用于决定列表中的两个项目中的哪一个是“第一”
  • 您可能有一个应用程序,可以在运行时选择排序算法本身(QuickSort,HeapSort等)
  • Log4Net和Log4j中的Appenders,Layouts和Filters
  • UI工具包中的布局管理器
  • 数据压缩。 您可能有一个ICompressor接口,其唯一方法如下所示:

    byte [] compress(byte [] input);

    您的具体压缩类可能是RunLengthCompression,DeflateCompression等。

Eric Pohl answered 2019-09-11T03:08:08Z
9 votes

策略模式的一个常见用法是定义自定义排序策略(在没有高阶函数的语言中),例如, 在Java中按长度排序字符串列表,传递匿名内部类(策略接口的实现):

List<String> names = Arrays.asList("Anne", "Joe", "Harry");
Collections.sort(names, new Comparator<String>() {
  public int compare(String o1, String o2) {
    return o1.length() - o2.length();
  }
});
Assert.assertEquals(Arrays.asList("Joe", "Anne", "Harry"), names);

以类似的方式,策略可以用于具有对象数据库的本机查询,例如, 在db4o中:

List<Document> set = db.query(new Predicate<Document>() {
  public boolean match(Document candidate) {
    return candidate.getSource().contains(source);
  }
});
Fabian Steeg answered 2019-09-11T03:08:42Z
9 votes

主要说明:

  1. 策略是行为设计模式。 它用于在算法族之间切换。

  2. 此模式包含一个抽象策略接口和该接口的许多具体策略实现(算法)。

  3. 该应用程序仅使用策略界面。 根据某些配置参数,具体策略将标记为接口。

来自维基百科的UML图

enter image description here

一个真实的例子:航空公司在几个月(7月至12月)提供折扣。 您可以拥有一个票价模块,该模块根据月份数量决定定价选项。

看一个简单的例子。 此示例可以扩展到在线零售应用程序,它可以在特殊日子/欢乐时光轻松地为购物车项目提供折扣。

import java.util.*;

/* Interface for Strategy */
interface OfferStrategy {
    public String getName();
    public double getDiscountPercentage();
}
/* Concrete implementation of base Strategy */
class NoDiscountStrategy implements OfferStrategy{
    public String getName(){
        return this.getClass().getName();
    }
    public double getDiscountPercentage(){
        return 0;
    }
}
/* Concrete implementation of base Strategy */
class QuarterDiscountStrategy implements OfferStrategy{
    public String getName(){
        return this.getClass().getName();
    }
    public double getDiscountPercentage(){
        return 0.25;
    }
}
/* Context is optional. But if it is present, it acts as single point of contact
   for client. 

   Multiple uses of Context
   1. It can populate data to execute an operation of strategy
   2. It can take independent decision on Strategy creation. 
   3. In absence of Context, client should be aware of concrete strategies. Context acts a wrapper and hides internals
   4. Code re-factoring will become easy
*/
class StrategyContext {
    double price; // price for some item or air ticket etc.
    Map<String,OfferStrategy> strategyContext = new HashMap<String,OfferStrategy>();
    StrategyContext(double price){
        this.price= price;
        strategyContext.put(NoDiscountStrategy.class.getName(),new NoDiscountStrategy());
        strategyContext.put(QuarterDiscountStrategy.class.getName(),new QuarterDiscountStrategy());        
    }
    public void applyStrategy(OfferStrategy strategy){
        /* 
        Currently applyStrategy has simple implementation. You can use Context for populating some more information,
        which is required to call a particular operation            
        */
        System.out.println("Price before offer :"+price);
        double finalPrice = price - (price*strategy.getDiscountPercentage());
        System.out.println("Price after offer:"+finalPrice);
    }
    public OfferStrategy getStrategy(int monthNo){
        /*
            In absence of this Context method, client has to import relevant concrete Strategies everywhere.
            Context acts as single point of contact for the Client to get relevant Strategy
        */
        if ( monthNo < 6 )  {
            return strategyContext.get(NoDiscountStrategy.class.getName());
        }else{
            return strategyContext.get(QuarterDiscountStrategy.class.getName());
        }

    }
}
public class StrategyDemo{    
    public static void main(String args[]){
        StrategyContext context = new StrategyContext(100);
        System.out.println("Enter month number between 1 and 12");
        int month = Integer.parseInt(args[0]);
        System.out.println("Month ="+month);
        OfferStrategy strategy = context.getStrategy(month);
        context.applyStrategy(strategy);
    }

}

输出:

Enter month number between 1 and 12
Month =1
Price before offer :100.0
Price after offer:100.0

Enter month number between 1 and 12
Month =7
Price before offer :100.0
Price after offer:75.0

有用的文章:

dzone的战略模式

源头制定的战略模式

Ravindra babu answered 2019-09-11T03:10:07Z
8 votes

我有一个应用程序,它每天将它的用户群与我们的企业目录同步。 根据用户在大学中的状态,用户符合资格或不符合资格。 配置程序每天都会通过并确保应用程序中的那些应用程序被配置,而未被配置的那些(实际上根据优雅的降级算法,但这不是重点)。 星期六我做了一个更彻底的更新,同步每个用户的一些属性,并确保他们有适当的资格。 在月底,我根据当月的使用情况做一些账单回溯处理。

我使用可组合策略模式来执行此同步。 主程序基本上选择主策略,取决于星期几(仅同步变化/同步所有)和学期相对于学术日历的时间。 如果结算周期结束,那么它还会使用结算策略进行组合。 然后,它通过标准接口运行所选策略。

我不知道这有多常见,但我觉得它非常适合策略模式。

tvanfosson answered 2019-09-11T03:10:47Z
7 votes

我知道这是一个老问题,但我想我最近实施了另一个有趣的例子。

这是在文档传递系统中使用的策略模式的非常实用的示例。

我有一个PDF传送系统,它收到一个包含大量文档和一些元数据的存档。 根据元数据,它决定将文档放在哪里; 比方说,根据数据,我可以将文档存储在QuitterStrategy,MaximizeDeliveryToAStrategyA存储系统中,或者三者的混合。

不同的客户使用此系统,并且在出现错误时他们有不同的回滚/错误处理要求:一个人希望交付系统在第一个错误时停止,将所有文档保留在他们的存储中,但是停止该过程而不提供任何其他内容; 另一个人希望在MaximizeDeliveryToAStrategy存储时出现错误时从25205042794090909977回滚,但是将已经交付的内容留给A。很容易想象第三个或第四个也有不同的需求。

为了解决这个问题,我创建了一个包含交付逻辑的基本交付类,以及从所有存储中回滚内容的方法。 在出现错误的情况下,交付系统实际上不会调用这些方法。 相反,该类使用依赖注入来接收“回滚/错误处理策略”类(基于使用系统的客户),在发生错误时调用该类,如果适合该策略,则会调用回滚方法。

交付类本身会报告战略类的内容(将哪些文档传递到哪些存储,以及发生了哪些故障),并且每当发生错误时,它都会询问策略是否继续。 如果策略说“停止它”,则该类调用策略的“cleanUp”方法,该方法使用先前报告的信息来决定从交付类调用哪些回滚方法,或者根本不执行任何操作。

rollbackStrategy.reportSuccessA(...);
rollbackStrategy.reportFailureB(...);

if (rollbackStrategy.mustAbort()) {
    rollbackStrategy.rollback(); // rollback whatever is needed based on reports
    return false;
}

所以我现在有两个不同的策略:一个是QuitterStrategy(退出第一个错误并且没有清理),另一个是MaximizeDeliveryToAStrategy(尽可能不中止流程并且永远不会回滚传递给存储的东西 A,但如果交付到C失败,则从2520504279409099999回滚东西。

根据我的理解,这是战略模式的一个例子。 如果您(是的,您正在阅读)认为我错了,请在下面评论并告诉我。 我很好奇什么会构成策略模式的“纯粹”使用,以及我的实现的哪些方面违反了定义。 我觉得它看起来有点滑稽,因为战略界面有点胖。 到目前为止我看到的所有示例只使用了一种方法,但我仍然认为这封装了一种算法(如果一块业务逻辑可以被认为是一种算法,我认为它是这样做的)。

由于策略也会在交付执行期间通知事件,因此它也可以被视为观察者,但这是另一个故事。

从进行一些研究看起来,这似乎是一个“复合模式”(如MVC,一种在特定方式下使用多种设计模式的模式),称为Advisor。 它是关于交付是否应该继续的顾问,但它也是一个主动错误处理程序,因为它可以在被要求时回滚内容。

无论如何,这是一个非常复杂的例子,可能会让你觉得战略模式的用法过于简单/愚蠢。 当与其他模式一起使用时,它可能非常复杂并且更加适用。

Guilherme Vieira answered 2019-09-11T03:12:29Z
6 votes

策略模式是最常用的模式,专门用于验证和排序算法。

让我用一个简单的实际例子来解释

enum Speed {
  SLOW, MEDIUM, FAST;
}

class Sorter {
 public void sort(int[] input, Speed speed) {
    SortStrategy strategy = null;
    switch (speed) {
    case SLOW:
        strategy = new SlowBubbleSortStrategy();
        break;
    case MEDIUM:
        strategy = new MediumInsertationSortStrategy();
        break;

    case FAST:
        strategy = new FastQuickSortStrategy();
        break;
    default:
        strategy = new MediumInsertationSortStrategy();
    }
    strategy.sort(input);
 }

}

interface SortStrategy {

    public void sort(int[] input);
}

class SlowBubbleSortStrategy implements SortStrategy {

   public void sort(int[] input) {
    for (int i = 0; i < input.length; i++) {
        for (int j = i + 1; j < input.length; j++) {
            if (input[i] > input[j]) {
                int tmp = input[i];
                input[i] = input[j];
                input[j] = tmp;
            }
        }
    }
    System.out.println("Slow sorting is done and the result is :");
    for (int i : input) {
        System.out.print(i + ",");
    }
  }

 }

class MediumInsertationSortStrategy implements SortStrategy {

public void sort(int[] input) {
    for (int i = 0; i < input.length - 1; i++) {
        int k = i + 1;
        int nxtVal = input[k];
        while (input[k - 1] > nxtVal) {
            input[k] = input[k - 1];
            k--;
            if (k == 0)
                break;
        }
        input[k] = nxtVal;
    }
    System.out.println("Medium sorting is done and the result is :");
    for (int i : input) {
        System.out.print(i + ",");
    }

 }

}

class FastQuickSortStrategy implements SortStrategy {

public void sort(int[] input) {
    sort(input, 0, input.length-1);
    System.out.println("Fast sorting is done and the result is :");
    for (int i : input) {
        System.out.print(i + ",");
    }
}

private void sort(int[] input, int startIndx, int endIndx) {
    int endIndexOrig = endIndx;
    int startIndexOrig = startIndx;
    if( startIndx >= endIndx)
        return;
    int pavitVal = input[endIndx];
    while (startIndx <= endIndx) {
        while (input[startIndx] < pavitVal)
            startIndx++;
        while (input[endIndx] > pavitVal)
            endIndx--;
        if( startIndx <= endIndx){
            int tmp = input[startIndx];
            input[startIndx] = input[endIndx];
            input[endIndx] = tmp;
            startIndx++;
            endIndx--;
        }
    }
    sort(input, startIndexOrig, endIndx);
    sort(input, startIndx, endIndexOrig);
 }

}  

测试代码是

public class StrategyPattern {
  public static void main(String[] args) {
    Sorter sorter = new Sorter();
    int[] input = new int[] {7,1,23,22,22,11,0,21,1,2,334,45,6,11,2};
    System.out.print("Input is : ");
    for (int i : input) {
        System.out.print(i + ",");
    }
    System.out.println();
    sorter.sort(input, Speed.SLOW);
 }

}

同样的例子来自[http://coder2design.com/strategy-pattern/]

Jatinder Pal answered 2019-09-11T03:13:16Z
4 votes

策略模式的一个很好的例子是在一个我们可以拥有不同角色的游戏中,每个角色可以拥有多种武器进行攻击,但一次只能使用一种武器。 因此我们将角色作为背景,例如King,Commander,Knight,Soldier  和武器作为一种策略,其中attack()可能是取决于所使用武器的方法/算法。 因此,如果具体武器类是Sword,Axe,Crossbow,BowAndArrow等,他们都将实施attack()方法。 我相信不需要进一步解释。

Sandipan Karmakar answered 2019-09-11T03:13:42Z
2 votes

您确定“订单”的状态不是州模式吗? 我预感到订单的状态不会有不同的处理方式。

以订单上的方法Ship为例:

order.Ship();
  • 如果运输方式不同它的地位的功能,然后你有一个战略模式。
  • 但是如果Ship()方法仅成功订单付款时,和订单尚未发货,你有一个州模式。

我找到的状态模式(和其他模式)的最好例子是在“Head First Design Patterns”一书中,这是惊人的。紧随其后的是David Cumps的博客系列模式。

grootjans answered 2019-09-11T03:14:34Z
2 votes

假设您想编写一个算法来计算给定月份和年份的第n个Xday,例如2014年10月的第二个星期一。您想使用Android的Time类java.util.Calendar来表示日期,但您还想编写一个通用的 算法,也适用于java.util.Calendar

这就是我做的。

在DatetimeMath.java中:

public interface DatetimeMath { 
    public Object createDatetime(int year, int month, int day);

    public int getDayOfWeek(Object datetime);

    public void increment(Object datetime);
}

在TimeMath.java中:

public class TimeMath implements DatetimeMath {
    @Override
    public Object createDatetime(int year, int month, int day) {
        Time t = new Time();
        t.set(day, month, year);
        t.normalize(false);
        return t;
    }

    @Override
    public int getDayOfWeek(Object o) {
        Time t = (Time)o;
        return t.weekDay;
    }   

    @Override
    public void increment(Object o) {
        Time t = (Time)o;
        t.set(t.monthDay + 1, t.month, t.year);
        t.normalize(false);
    }
}

在Ordinal DayOfWeek Calculator.java中,具有遗传算法的类:

public class OrdinalDayOfWeekCalculator {   
    private DatetimeMath datetimeMath;

    public OrdinalDayOfWeekCalculator(DatetimeMath m) {
        datetimeMath = m;
    }

    public Object getDate(int year, int month, int dayOfWeek, int ordinal) {
        Object datetime = datetimeMath.createDatetime(year, month, 1);
        if (datetimeMath.getDayOfWeek(datetime) == dayOfWeek) {
            return datetime;
        } 
        int xDayCount = 0;
        while (xDayCount != ordinal) {
            datetimeMath.increment(datetime);
            if (datetimeMath.getDayOfWeek(datetime) == dayOfWeek) {
                xDayCount++;
            }
        }
        return datetime;
    }
}

在我的Android应用程序中,我会打电话

OrdinalDayOfWeekCalculator odowc = 
        new OrdinalDayOfWeekCalculator(new TimeMath());
Time canadianThanksgiving = (Time)odowc.getDate(
        year, Calendar.OCTOBER, Time.MONDAY, 2);

如果我想为java.util.Calendar重用相同的算法,我只想编写一个CalendarMath类,它在DatetimeMath中实现三个方法然后使用

OrdinalDayOfWeekCalculator odowc2 = 
        new OrdinalDayOfWeekCalculator(new CalendarMath());
Calendar canadianThanksgivingCal = (Calendar)odowc2.getDate(
        year, Calendar.OCTOBER, Calendar.MONDAY, 2);
anomal answered 2019-09-11T03:15:40Z
1 votes

我在一个应用程序中相当复杂的引擎中使用了策略方法,这是一个很好的例子。 本质上,引擎的作用是首先找到一个拥有小部件的人的列表,它的第二个角色是根据未知数量的参数(比如价格距离以前的业务一起)找出10个最好的人。 ,ammount库存,运输选项等等...)

基本上我们所做的是将问题分解为两个策略,第一个是数据检索,因为我们知道我们有多个小部件源,我们需要能够获取数据并将其转换为通用结构。

然后我们还意识到我们有多个算法,其中一些是基于加权参数,另一些是非常奇怪和支持我不能做到正义而没有拉出visios和图表而且你得到了图片,我们有很多算法 选择最好的人。

我们的服务本身就是它本质上定义了输入,输出并对数据进行了一些规范化,它还使用提供者模式来插入使用该策略的特定于应用程序的数据提供者和算法提供者。 这是一个相当有效的系统。

如果我们使用的策略或模板模式我们从未解决过,那么我们会进行一些辩论。

JoshBerke answered 2019-09-11T03:16:34Z
1 votes

几周前,我添加了一个由我们的域对象实现的通用Java接口。 此域对象是从数据库加载的,数据库表示是一个包含大约10个以上分支的星型模式。 拥有如此重量级域名对象的后果之一是我们必须制作代表相同架构的其他域对象,尽管重量较轻。 所以我让其他轻量级对象实现了相同的接口。 否则我们有:

public interface CollectibleElephant { 
    long getId();
    String getName();
    long getTagId();
}

public class Elephant implements CollectibleElephant { ... }
public class BabyElephant implements CollectibleElephant { ... }

最初,我想使用CollectibleElephant来排序Elephants。 很快,我的团队成员上了CollectibleElephant来运行安全检查,在他们被发送到GUI时过滤它们等等。

Alan answered 2019-09-11T03:17:08Z
1 votes

我们必须为具有非常复杂的数据库的企业平台创建第三方配置界面。 要提供的数据的提交是作为我们的数据类型的列表,这些数据类型被放入我们的应用程序中的优先级队列中,因此可以由于依赖性而以正确的顺序将它们写入数据库。

编写该数据的过程非常简单,不断弹出优先级队列的顶部,然后根据您提取的对象类型选择策略。

Coxy answered 2019-09-11T03:17:42Z
1 votes
public class StrategyDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        Item item1 = new Item("1234", 10);
        Item item2 = new Item("5678", 40);

        cart.addItem(item1);
        cart.addItem(item2);

        // pay by paypal
        cart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));

        // pay by credit card
        cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
    }
}

interface PaymentStrategy {
    public void pay(int amount);
}

class CreditCardStrategy implements PaymentStrategy {

    private String name;
    private String cardNumber;
    private String cvv;
    private String dateOfExpiry;

    public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate) {
        this.name = nm;
        this.cardNumber = ccNum;
        this.cvv = cvv;
        this.dateOfExpiry = expiryDate;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with credit/debit card");
    }

}

class PaypalStrategy implements PaymentStrategy {

    private String emailId;
    private String password;

    public PaypalStrategy(String email, String pwd) {
        this.emailId = email;
        this.password = pwd;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using Paypal.");
    }

}

class Item {

    private String upcCode;
    private int price;

    public Item(String upc, int cost) {
        this.upcCode = upc;
        this.price = cost;
    }

    public String getUpcCode() {
        return upcCode;
    }

    public int getPrice() {
        return price;
    }

}

class ShoppingCart {

    // List of items
    List<Item> items;

    public ShoppingCart() {
        this.items = new ArrayList<Item>();
    }

    public void addItem(Item item) {
        this.items.add(item);
    }

    public void removeItem(Item item) {
        this.items.remove(item);
    }

    public int calculateTotal() {
        int sum = 0;
        for (Item item : items) {
            sum += item.getPrice();
        }
        return sum;
    }

    public void pay(PaymentStrategy paymentMethod) {
        int amount = calculateTotal();
        paymentMethod.pay(amount);
    }
}
Vivek Goel answered 2019-09-11T03:18:02Z
0 votes

来自维基百科

在计算机编程中,策略模式(也称为策略模式)是一种行为软件设计模式,可以在运行时选择算法。 代码不是直接实现单个算法,而是接收关于在一系列算法中使用哪些算法的运行时指令

在Windows Paint应用程序中,您可以看到策略模式,您可以在其中在不同的部分中单独选择形状和颜色。 这里的形状和颜色是可以在运行时更改的算法。

如果您想绘制一个红色的圆圈,而不是提供“RedCircle”选项,他们会让您选择圆圈和您选择的颜色。

Shape redCircle = new RedCircle(); // Without stretegy Pattern
Shaped redCircle = new Shape("red","circle"); // With Strategy pattern

没有策略模式将增加具有形状和颜色的笛卡尔积的类的数量。 此外,每个实现的接口都会更改。

bharanitharan answered 2019-09-11T03:18:59Z
translate from https://stackoverflow.com:/questions/370258/real-world-example-of-the-strategy-pattern