某大牛曾经这样描述过设计模式:
设计模式其实就三个准则:一是中意于组合而不是继承 。二是依赖于接口而不是实现。三是高内聚,低耦合。
且不忙讨论这句话是否正确,但从这句话里的口气中我学到一个道理,我其实不应该去畏惧设计模式,以为这是多么难的东西,当以平常心对待设计模式,并将其使用到我们的项目中。
通过继承来封装一个个拥有共同接口的独立的算法
通过继承我们定义了多个算法,而通过java的多台机制我们则可以让这些算法之间进行互换。
通过组合对策略屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
策略模式由三个角色组成:
1) 算法使用环境(Context)角色:它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化
2) 抽象策略(Strategy)角色:策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
3) 具体策略(Concrete Strategy)角色:实现了抽象策略角色定义的接口。策略模式各个角色之间关系的类图表示:
1、多用组合,少用继承
2、针对接口编程,而不是针对实现编程
3、为了交互对象之间的松耦合设计而努力
4、要依赖抽象,不要依赖具体的类
5、最少知识原则:只和你的密友交谈
6、好莱坞原则:别调用(打电话给)我们,我们会调用(打电话给)你
7、一个类应该只有一个引起变化的原因
package com.fengshu.limanman.dao; public interface IFlyDao { public void fly(); }
package com.fengshu.limanman.dao.impl; import com.fengshu.limanman.dao.IFlyDao; public class CanNotFlyDaoImpl implements IFlyDao { public void fly() { System.out.print("sorry i can not fly"); } }
package com.fengshu.limanman.dao.impl; import com.fengshu.limanman.dao.IFlyDao; public class FlyWithWingDaoImpl implements IFlyDao { @Override public void fly() { System.out.println("hello i am flying"); } }
package com.fengshu.limanman.model; import com.fengshu.limanman.dao.IFlyDao; public class FlyContext { private IFlyDao iFlyDao; public FlyContext(IFlyDao iFlyDao) { this.iFlyDao = iFlyDao; } public void tryFly() { iFlyDao.fly(); } }
package com.fengshu.limanman.test; import org.junit.Test; import com.fengshu.limanman.dao.impl.CanNotFlyDaoImpl; import com.fengshu.limanman.dao.impl.FlyWithWingDaoImpl; import com.fengshu.limanman.model.FlyContext; public class TestFly { @Test public void testTryFly() { FlyContext flyContext = new FlyContext(new FlyWithWingDaoImpl()); flyContext.tryFly(); FlyContext flyContext2 = new FlyContext(new CanNotFlyDaoImpl()); flyContext2.tryFly(); } }
hello i am flying sorry i can not fly
希望下次问自己什么事策略模式的时候不要再答不上来,也就是说我不想再写九月的策略模式了。。。。
原文:http://my.oschina.net/fengshuzi/blog/299124