策略模式-常用设计模式
策略模式-常用设计模式
dapengking 发表于4年前
策略模式-常用设计模式
  • 发表于 4年前
  • 阅读 160
  • 收藏 9
  • 点赞 0
  • 评论 2

移动开发云端新模式探索实践 >>>   

摘要: 闲来无事,打算系统学习下设计模式。每天写点心得吧,也算是敦促。。。

    离毕业还有一段时间。最近闲来无事,打算系统的学习下设计模式。

    专门在博客里面新开了一个分类,主要记录下自己对常用设计模式的理解。同样还是算对自己的一个敦促吧。争取两天一篇吧。

    这次学习设计模式主要是通过看Headfirst系列的设计模式一书。之所以选择这本书,来入门,是因为身边挺多同学,看过这个,并且十分推荐。我之前也大概浏览过,我想大家之所以这么推荐的原因可能是因为,headfirst系列一贯都有深入浅出,语言风趣幽默的特点吧。好了,兴趣是最好的老师。配着插图学技术,感觉也不是什么坏事是吧?~

-----我是分割线------------------------------------------------------------

策略模式

    策略模式,在headfirst设计模式中的定义是这样的:策略模式定义了算法族,分别封装起来,让它们之前可以相互替换。这个模式可以使算法的变化独立于使用算法的客户。

    UML类图:

(上图转自百度图片)

对应书中的定义。strategy接口,定义了策略类的公共接口。也就是书中定义的需要进行单独封装的算法。在代码中,我们可以自行实现任意多个Strategy的实现类,例如:ConcreteStrategyA,ConcreteStrategyB。。。

在这些实现中,我们需要实现接口中AlgorithmInterface()方法,作为具体的算法。

在Context类中,维护了一个Strategy类型的引用。用来引用一个具体的ConcreteAtrategyA等类型的具体算法对象。这里采用父类引用指向子类对象的方式,可以方便利用面向对象的多态的特性。

然后在Context对象的ContextInterface()方法中,通过Strategy类型的引用,调用具体的Strategy实现类对象中的AlgorithmInterface()方法,完成具体的工作。

说道这里,其实用一句话就可以总结:策略模式,其实最核心的地方就是,它是采用组合而非继承,来实现对算法代码的复用的。这也体现出了,我们在代码设计中的一个常用的原则就是--尽量使用组合,而尽量少用继承。

主要区别如下:


  1. 首先,继承是代码的编译期间实现的。
  2. 而,组合则是在程序运行时实现的。

倒不是说,在编译期实现有什么不好。主要是因为当我们采用组合的方式实现时,就可以在程序运行时具有非常的灵活性。试想,你可以在程序运行的过程当中,通过将新的Strategy实现类ConcreteStrategyC的对象实例,赋值给Context成员Strategy引用,这样就可以在ContextInterface()中,通过引用调用全新的算法实现了。而这种动态所带来的灵活性是继承的方式所没有的。(当然,继承也是一种实现代码复用的重要手段。但并不是唯一手段,这是像我这样的新手经常忽略的问题。因为我在写代码的时候,动不动就喜欢采用继承的方式。好像使用了继承,就是使用了OO的设计思路。就能达到比较好的代码复用效果。)

例子代码:

package strategy;

public interface Strategy {

	public void AlgorithmInterface();
}



package strategy;

public class ConcreteStrategyA implements Strategy {

	@Override
	public void AlgorithmInterface() {
		//这里是算法的具体实现
		//
		//
		System.out.println("ConcreteStrategyA");
		
	}

}



package strategy;

public class ConcreteStrategyB implements Strategy {

	@Override
	public void AlgorithmInterface() {
		//这里是算法的具体实现
		//
		//
		System.out.println("ConcreteStrategyB");
		
	}

}



package strategy;

public class Context {

	private Strategy s = null;

	public Strategy getS() {
		return s;
	}

	public void setS(Strategy s) {
		this.s = s;
	}

	public Context(Strategy s) {
		this.s = s;
	}
	
	public void ContextInterface(){
		s.AlgorithmInterface();
	}
	
	public static void main(String[] args) {
		Context c = new Context(new ConcreteStrategyA());
		c.ContextInterface();
		//灵活的动态改变算法的具体实现
		c.setS(new ConcreteStrategyB());
		c.ContextInterface();
	}
}



运行结果:




the end~

(小学语文水平,标点符号用的也比较乱。可能是写少的原因吧。想想上次写作文,也差不多是七八年前的事情了。嗯,慢慢写的多了应该就好了。这对自己应该也算是一个锻炼吧。O(∩_∩)O~)


  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 7
博文 133
码字总数 53553
评论 (2)
lgscofield
策略模式和模板模式有啥区别吗
dapengking

引用来自“lgscofield”的评论

策略模式和模板模式有啥区别吗

呵呵,我刚开始看,实话说,还不知道什么叫模板模式。刚在网上找了篇帖子(http://tianli.blog.51cto.com/190322/45564/)大概读了下。如果理解的没有偏差的话,模板模式主要的概念应该是:算法的框架封装在基类中,将算法中的差异性通过抽象方法接口的形式,留给具体的子类去实现。这样做带来的好处是可以通过继承的方式复用代码。但更重要的优势是,通过基类中对算法框架的封装定义,使算法的用户在实现具体的实现类时,可以不用考虑算法的骨架,而只用专心实现算法在不同适用情况下的差异就行了。
至于,策略模式和模板模式的区别。我也在网上找到了一个帖子(http://blog.csdn.net/klarclm/article/details/7164227),回答了这个问题。

我自己的理解是,这两种模式,还是比较容易区分的。虽然它们的优势都是带来的代码复用的方便。但是采用的确实截然不同的两种方式:”组合和继承“。与其说这两种模式的区别在哪,我感觉主要还是看在什么情况下最适合使用哪种模式来工作。
正像帖子中总结的那样:
Strategy模式的应用场景是:
1. 多个类的分别只是在于行为不同
2. 你需要对行为的算法做很多变动
3. 客户不知道算法要使用的数据



Template Method模式的应用场景是:
1. 你想将相同的算法放在一个类中,将算法变化的部分放在子类中实现
2. 子类公共的算法应该放在一个公共的类中,避免代码重复

还有一点:
有一个说法总结得不错: 到底该倾向于composition还是inheritance,决定于"变化的是什么".如果基类的接口变化得很频繁,那么使用inheritance绝对是个噩梦;如果只是给基类新增方法,那么坚持使用composition的话就得新增很多个delegate.
这么说来,Strategy与Template Method模式之间的区别,也是在"变化的是什么"这个问题上了.

ps:发了这么多帖子,您还是第一个给我留言的。今天挺高兴的~0
×
dapengking
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: