设计模式之策略模式


设计模式是经验总结,是学习软件设计的有效方法,因此,了解和理解现有的设计模式,是提高软件设计的有效途径之一,这里将介绍相关的设计模式,并通过示例了理解其用法。

策略模式(Strategy Pattern)

对于策略模式的细节,这里不再啰嗦,只做一个简单的介绍。
策略模式定义了算法族,分别封装起来,使它们间可以互相替换,让算法的变化独立于使用它们的客户。
策略模式
在策略模式中,一个类的行为或其算法可以在运行时更改。属于行为型模式。
意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
何时使用: 一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决: 将这些算法封装成一个一个的类,任意地替换。
关键代码: 实现同一个接口。
应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项: 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

示例

我们学习软件设计模式,就要学习其思想,从代码示例中精炼出适合自己的设计经验,从而提高自己的能力。
这里以日期格式为例,来说明如何使用策略模式。
首先,创建一个使用日期的接口,代码如下:

package cn.lut.curiezhang.designpattern.strategy;

public interface IDateFormat {
    public void spendDate(int day, int month, int year);
}

这个接口就可以匹配不同的策略,从而展现不同的日期格式的应用,例如,美洲日期格式,代码如下:

package cn.lut.curiezhang.designpattern.strategy;

public class AmericaFormat implements IDateFormat {
    @Override
    public void spendDate(int day, int month, int year) {
        System.out.println("美洲格式:" +
                (month > 9 ? month : "0" + month) +
                "/" +
                (day > 9 ? day : "0" + day) +
                "/" +
                year);
    }
}

类似地,我们可以创建欧洲格式的日期,例如:

package cn.lut.curiezhang.designpattern.strategy;

public class EuropeFormat implements IDateFormat {
    @Override
    public void spendDate(int day, int month, int year) {
        System.out.println("欧洲格式:" +
                (day > 9 ? day : "0" + day) +
                "." +
                (month > 9 ? month : "0" + month) +
                "." +
                year);
    }
}

当然,如果需要,你还可以根据地域不同,创建不同的日期格式,这很容易做到。
有了这些不同的日期格式,又应该怎么使用呢?
现在,创建一个使用这些格式的场景,在这个场景中,只针对接口编程,不关联具体的日期格式类型,代码如下:

package cn.lut.curiezhang.designpattern.strategy;

public class Date {
    private IDateFormat format = null;
    private int day, month, year = 0;

    public Date(int day, int month, int year) {
        this.day = day;
        this.month = month;
        this.year = year;
    }

    public void setFormat(IDateFormat format) {
        this.format = format;
    }

    public void spend() {
        format.spendDate(day, month, year);
    }
}

这样,通过调用应用场景Date类,就可以赋予其不同的具体日期格式类型,从而得到想要的结果,下面来看看其测试:

package cn.lut.curiezhang.designpattern.strategy;

/**
 * Client
 *
 */
public class Client
{
    public static void main( String[] args )
    {
        Date date = new Date(21, 9, 2019);

        date.setFormat(new EuropeFormat());
        date.spend();

        date.setFormat(new AmericaFormat());
        date.spend();
    }
}

测试结果非常简单,如下图所示:
测试结果
代码实现就是这样的,下面来看看上面设计模式的基本结构,看看其类图:
类图
其基本结构与策略模式完全一致的,只是这里将策略模式的基本结构匹配到了日期格式上来,所以,设计模式的思想需要你去适应要解决的问题。
这些类之间又是如何协作的呢?就来看看其顺序图:
顺序图
类图、顺序图是帮助理解设计模式的基本工具,应该了解。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值