Strategry模式简单理解及应用

来源:互联网 发布:windows7共享网络密码 编辑:程序博客网 时间:2024/05/25 20:00

喜欢设计模式,第一次在实践中主动想到运用设计模式,就记下自己的理解及实现,虽然非常简单。

我的理解,多态是类的泛化,Stategy模式是方法的泛化。这就为替换不同算法提供了方便。替换的可能,就是现在不把语句写死。白猫黑猫,抓住耗子是好猫。我们只需要下命令:“去抓耗子!”具体是白猫抓还是黑猫抓,我们暂时不考虑;因为即使现在定死了,将来也可能变。软件开发的最大问题——变,就迫使我们“下命令”时不能多说一点;只要多说了一点现在确定不了的,将来就很可能错(说话和写程序一个道理。。)。

不把语句写死”的方法就是定义接口,利用多态性,把刚创建对象的对象赋给父接口的引用。以后用这个接口的引用来操作这个对象,就相当于只针对此对象的一方面特性对其进行操作。比如一个对象是一个人叫王二,他如果在打酱油时被临时拉去,演一个1秒钟就死了的一个小喽啰,剧本里不可能写“王二一命呜呼”,只会写“一个小喽啰一命呜呼”。因为他如果2秒钟才死,肯定被踢走,揪来另一个打酱油的替他演。剧本只指定当前情景下的角色,不多定义一点儿。多态性就是这样,用一种特性(即接口)来操作对象。从王二这个例子,可见多态性的应用多么重要。

功能是解析CSV文件,构建EarEntry对象。考虑到CSV文件中的属性可能的变化,需要可扩展算法;针对包含不同属性的CSV文件,构建不同类型的EarEntry(即EarEntry的子类)。

这个GisImpl类中的csvToDB()方法,就是需要构建EarEntry对象的地方。采用Strategry模式的思想,也是很自然的想法,主要就两步:用BuildWay来创建一个Builder,然后此Builder执行build()方法构建出EarEntry对象。

public class GisImpl implements GisFacade{private EarEntryBuildWay earEntryBuildWay;@Overridepublic String csvToDB(byte[] csvBytes) {//......
//......EarEntryBuilder earEntryBuilder = new EarEntryBuilder(this.earEntryBuildWay);EarEntry earEntry = earEntryBuilder.build(attributeStrs); }}

下面来写这两步中的接口和类。首先为了考虑算法的泛化,需要一个接口,其中包含泛化的方法:定义构建EarEntry的方法——EarEntryBuildWay接口,其中包含了buildEarEntry()方法。从命名就可以看出,这个接口和其方法都没有表明一种具体的build的方式(如果是buildWay1、buidlWay2就是两种不同的方式)。

public interface EarEntryBuildWay {public EarEntry buildEarEntry(String[] attributeStrs);} 

有了这个泛化的接口,我们就可以通过继承它来扩展不同的算法了。下面这个类EarEntryBuildWay1就提供了一种具体的算法。


public class EarEntryBuildWay1 implements EarEntryBuildWay{@Overridepublic EarEntry buildEarEntry(String[] attributeStrs) {EarEntry earEntry = new EarEntry();earEntry.setTime(attributeStrs[0]);earEntry.setMs(attributeStrs[1]);earEntry.setMag(attributeStrs[2]);earEntry.setLocation(attributeStrs[3]);earEntry.setLog(attributeStrs[4]);earEntry.setLat(attributeStrs[5]);earEntry.setDepthKm(attributeStrs[6]); earEntry.setDepthMi(attributeStrs[7]);earEntry.setUtc(attributeStrs[8]);return earEntry;}}

如果要使用这种方法来build,这里用了Spring的依赖注入。在配置文件applicationContext.xml中,

ref="earEntryBuildWay1"
只要把ref的值改变,就可以随意替换代表不同build方法的子类。也就是说,除了写新的算法类继承接口外,只需要改这个xml文件中的一个属性,就实现了算法的改变。Java代码不需要任何修改,也就不会影响其他的代码。

<bean id="gis" class="org.springframework.samples.jpetstore.domain.logic.GisImpl"><property name="passageDao" ref="passageDao"/><property name="earEntryDao" ref="earEntryDao"/><property name="earEntryBuildWay" ref="earEntryBuildWay1"/></bean><bean id="earEntryBuildWay1" class="org.springframework.samples.jpetstore.util.EarEntryBuildWay1"></bean>

有了算法(BuildWay),还要有个执行它的主体。下面就是执行算法的主体EarEntryBuilder,它包含私有成员earEntryBuildWay,也就是表示构造者有一个构造的方法。Get/Set方法自不必说,构造子的参数是EarEntryBuildWay类型,可理解为有了算法就有了构造者。build()方法包裹了泛化的构造方法,也就是利用自身算法来完成构建。

public class EarEntryBuilder {private EarEntryBuildWay earEntryBuildWay;public EarEntryBuildWay getEarEntryBuildWay() {return earEntryBuildWay;}public void setEarEntryBuildWay(EarEntryBuildWay earEntryBuildWay) {this.earEntryBuildWay = earEntryBuildWay;}public EarEntryBuilder(EarEntryBuildWay earEntryBuildWay){this.earEntryBuildWay = earEntryBuildWay;}public EarEntry build(String[] attributeStrs){return this.earEntryBuildWay.buildEarEntry(attributeStrs);}}


以上就运用Strategry模式解决了一个非常简单的问题。前两天看到有个牛人说,好的程序员,不封装,也没有重复代码。我觉得对于编程天才来说,也许确实不需要什么设计模式;但是随着项目规模的扩大,先不说设计模式的技术上的必要性,人力规模将会大大增加。这时大多数人不是编程天才,就需要松耦合来进行分工。所以我觉得设计模式是非常有必要学习的,也是很有意思的一种编程方式,很贴近现实生活中的道理。



(参考

http://www.jdon.com/designpatterns/designpattern_Strategy.htm)

原创粉丝点击