`

策略模式——strategy

阅读更多

Strategy Pattern

       本文总结《Design Pattern in Java Chap23 Strategy.   以为用户推荐一款烟火制品选择采取不同推荐策略为例。先讲解如果不采用策略模式会怎样,然后将这些代码重构为策略模式。

 

1 、如果不使用策略模式 Customer::getRecommended() 中封装了复杂的策略选择和策略执行流程。 见图一

 

关键代码(choice & execution of various strategies)

    public Firework getRecommended() {

        //1 、如果有促销的烟火制品,从 config/strategy.dat 中取出并返回

        try {

            Properties p = new Properties();

            p.load(ClassLoader.getSystemResourceAsStream ( "config/strategy.dat" ));

            String promotedName = p.getProperty( "promote" );

            if (promotedName != null ) {

                Firework f = Firework.lookup (promotedName);

                if (f != null )

                    return f;

            }

        } catch (Exception ignored) {

            // If resource missing or it failed to load,

            // fall through to the next approach.

            ignored.printStackTrace();

        }

 

        //2 、注册用户使用 Rel8 引擎

        if (isRegistered()) {

            return (Firework) Rel8.advise ( this );

        }

 

        //3 、未注册用户,若是大客户,使用 LikeMyStuff 引擎

        if (isBigSpender()) {

            return (Firework) LikeMyStuff.suggest ( this );

        }

 

        //4 、未注册用户,若是小客户,随意推荐

        return Firework.getRandom ();

    }

 

由以上代码可知,主要有这样几种推荐策略:

         A. config/strategy.dat 中读取指定推荐的烟火制品

         B.Rel8 引擎

         C.LikeMyStuff 引擎

         D. 随机推荐

 

 

2 、使用策略模式 ,对以上代码进行重构

 

       现在,Customer 中的关键代码是:

public static void main(String[] args) {

        Firework recommendation = new Customer2().getRecommended();

        System. out .println(recommendation.toString());

    }

    public Firework getRecommended() {

        Firework recommend = getAdvisor().recommend( this );

        return recommend;

}

    private Advisor getAdvisor() {

        if ( advisor == null ) {

            if ( promotionAdvisor .hasItem())

                advisor = promotionAdvisor ;

            else if (isRegistered())

                advisor = groupAdvisor ;

            else if (isBigSpender())

                advisor = itemAdvisor ;

            else

                advisor = randomAdvisor ;

        }

        return advisor ;

}

可见,我们将策略选择流程封装在getAdvisor() 中了,getAdvisor() 返回一个策略接口Advisor 的子类实例;调用这个被返回的子类实例的recommend() 方法(重写Advisor 中的recommend() 方法),可以得到推荐的Firework 实例。

 

*****************************************************************

*****************************************************************

另外,对于以前写得很松散的以下两种推荐方式,分别写Advisor 子类对其进行封装。封装前如下:

public Firework getRecommended() {

        //1 、如果有促销的烟火制品,从 config/strategy.dat 中取出并返回

        try {

            Properties p = new Properties();

            p.load(ClassLoader.getSystemResourceAsStream ( "config/strategy.dat" ));

            String promotedName = p.getProperty( "promote" );

            if (promotedName != null ) {

                Firework f = Firework.lookup (promotedName);

                if (f != null )

                    return f;

            }

        } catch (Exception ignored) {

            // If resource missing or it failed to load,

            // fall through to the next approach.

            ignored.printStackTrace();

        }

 

        //2 、注册用户使用 Rel8 引擎

 

        //3 、未注册用户,若是大客户,使用 LikeMyStuff 引擎

 

        //4 、未注册用户,若是小客户,随意推荐

        return Firework.getRandom ();

    }

封装后如下:

public class PromotionAdvisor implements Advisor {

    private Firework promoted ;

 

    public PromotionAdvisor() {

        try {

            Properties p = new Properties();           

           p.load(ClassLoader.

              getSystemResourceAsStream ( "config/strategy.dat" ));

            String promotedFireworkName = p.getProperty( "promote" );

            if (promotedFireworkName != null )

                promoted = Firework.lookup (promotedFireworkName);

        } catch (Exception ignored) {

            promoted = null ;

        }

}

    public boolean hasItem() {

        return promoted != null ;

    }

    public Firework recommend(Customer c) {

        return promoted ;

}

}

 

public class RandomAdvisor implements Advisor {

    public Firework recommend(Customer c) {

        return Firework.getRandom ();

    }

}

 

3 、总结

 

    如何记忆策略模式呢:

           (1) 这里有一个概念(策略选择==> customer2.getAdvisor() )、两个实体(策略调用者==> customer2 ; 策略==> advisor接口实例 ):

           (2) 具体细节 是: “策略调用者”调用其“策略选择”customer2.getAdvisor()选择一个具体的advisor接口实例(如groupAdvisor实例)赋予其成员对象advisor;advisor接口提供统一接口方法advisor.recommend()供实际执行某一个“策略”。


  • 描述: 图一
  • 大小: 20.1 KB
  • 描述: 图二
  • 大小: 21.6 KB
  • 大小: 12 KB
分享到:
评论

相关推荐

    行为型——Strategy(策略模式)

    策略模式的核心组成部分包括环境(Context)、策略(Strategy)和具体策略(Concrete Strategy)。 1. **环境(Context)**:这是使用策略的对象,它维持一个对策略对象的引用,可以在运行时根据需要选择合适的策略。环境...

    设计模式——策略模式 & 单例模式

    策略模式和单例模式是软件设计中两种非常重要的设计模式,它们在实际开发中有着广泛的应用。在这篇文章中,我们将深入探讨这两种模式的核心概念、实现方式以及如何在实际项目中运用。 策略模式是一种行为设计模式,...

    设计模式——策略模式

    策略模式的核心组成部分包括环境(Context)角色、策略(Strategy)接口和具体策略(Concrete Strategy)类。环境角色是使用策略的角色,它维持一个对策略对象的引用,并在适当的时候调用策略对象的方法来执行相应的...

    C#面向对象设计模式纵横谈(23):(行为型模式) Strategy 策略模式

    策略模式的核心组成部分包括上下文(Context)、策略(Strategy)和具体策略(Concrete Strategy)。上下文是使用策略的对象,它定义了客户所期望的接口,并负责调用具体策略对象的算法。策略是所有具体策略的抽象接口,它...

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

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式主要通过定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户而变化。这种模式的核心是策略...

    设计模式浅谈1——策略模式

    在给定的压缩包文件“strategy”中,可能包含了实现策略模式的源代码示例,可以进一步研究每个类的功能和它们如何相互协作以实现策略模式。通过分析这些代码,我们可以深入理解策略模式的用法和优势,同时也可以学习...

    设计模式——可复用面向对象软件的基础(1)

    行为型模式如观察者模式(Observer)、命令模式(Command)和策略模式(Strategy)则关注于对象间的通信和行为,使代码更易于维护和适应变化。 设计模式的核心思想是将常见问题的解决方案标准化,提供了一种通用的...

    策略模式.rar策略模式.rarjava设计模式

    策略模式的核心组件包括上下文(Context)、策略接口(Strategy)和具体策略(Concrete Strategy)。上下文是使用策略的对象,它通过调用策略接口来执行特定的算法。策略接口定义了所有支持的算法的公共接口,具体...

    java 策略模式demo

    策略模式的核心包括三个角色:策略(Strategy)接口、具体策略(Concrete Strategy)类以及上下文(Context)。策略接口定义了所有支持的算法的公共接口,而具体策略类实现了这些算法。上下文则使用策略接口来调用...

    Android 设计模式:(一)观察者模式 —— 封装行为的大局观

    本文将深入探讨其中的一种——观察者模式(Observer Pattern),它是行为设计模式的一种,主要用来封装行为的变化,实现对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被...

    设计模式代码——c#

    C#设计模式(23种设计模式) 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) ...21. 策略模式(Strategy Pattern) 22. 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)

    设计模式-Java语言中的应用(pdf)

    行为型模式如策略(Strategy)、观察者(Observer)、访问者(Visitor)和模板方法(Template Method),关注对象之间的交互和职责分配。 在Java中,设计模式的应用广泛且深入。例如,单例模式在系统配置、线程池等...

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

    策略模式是一种设计模式,它属于对象行为型模式,主要用于封装一系列相关的算法,使得可以在运行时动态选择不同的算法。在Java中,策略模式通过定义接口或抽象类来规范这些算法的行为,然后通过继承或实现这些接口/...

    Java设计模式教程-策略模式Java开发Java经验技

    在"Java设计模式教程——策略模式Java开发Java经验技巧共13页.pdf.zip"这份资料中,可能会详细讲解如何在实际项目中应用策略模式,包括但不限于以下内容: 1. 策略模式的基本结构和工作原理。 2. 如何定义策略接口...

    C++ 策略模式 dome

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在C++中,策略模式通常通过定义一系列算法类并让它们之间可以互换来实现。这些算法都封装在一个接口或抽象基类中,使得客户端代码可以独立于具体算法...

    设计模式精解 译者:熊节 程序员必看书籍之一 part2

    设计模式精解(Design Patterns Explained) ...如何实现关键模式——Strategy(策略)、Observer(观察者)、Bridge(桥接)、Decorator(装饰)等等。 共同点/变化点分析、设计模式以及它们如何帮助理解抽象类。

    策略模式例子

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件开发中,我们经常遇到需要根据不同的条件或时间来改变算法的情况。策略模式就是为了解决这类问题而诞生的,它将每种算法封装到具有共同接口的...

    设计模式——策略模式的学习与理解

    策略模式是一种行为设计模式,它的主要目的是将不同的算法或行为封装在独立的可互换的类中,使得客户端代码能够灵活地选择并使用这些算法,而无需关心它们的具体实现。这种模式遵循了几条重要的设计原则: 1. **...

    《设计模式--基于C#的工程化实现及扩展》.(王翔)_《0528》.rar

    行为型模式则关注对象之间的交互和职责分配,如策略模式(Strategy)、观察者模式(Observer)和责任链模式(Chain of Responsibility)等,它们有助于提高代码的灵活性和可扩展性。 在C#中,设计模式的实现往往...

Global site tag (gtag.js) - Google Analytics