策略模式
策略模式:
策略模式将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现,并使他们可以相互替换,从而导致客户端程序独立于算法的改变。
Composition:在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用实例的方法从而获得新的功能,这种设计被称作组合(复合)。
注:可以研究下Resource对资源的封装,Resource就运用了策略模式
策略模式设计原则:
1.找出应用中需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混在一起;
2.面向接口编程,而不是面向实现编程;
3.多用组合,少用继承
这个模式涉及到三个角色:
● 环境(Context)角色:持有一个Strategy的引用。
● 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
● 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
举个列子:我们去火车站买火车票,Context就是我们,Strategy就是火车站,Strategy下面的几个具体策略就是有 成人、学生、儿童。火车站会根据这三个策略选一个和你相匹配的,然后收费。我们就取到火车票了。对我们而言,我们的主要目的就是买票,策略不是我们定的,我们都成年了,向买儿童票,人家肯定不卖给你吧。
这样来看,有一个user类,去火车站买票,火车站就是接口,interface TrainStation,接口里有方法getTicket() ,毕竟我们是主体客户端嘛,所以方法命名为得到火车票。接口下面有几个实现类,分别是成人 学生 儿童。
首先定义火车站接口
package com.zhao.service; public interface TrainStation { public void getTicket(); }
其次是我们的策略:
package com.zhao.service.impl; import com.zhao.service.TrainStation; public class Person implements TrainStation{ @Override public void getTicket() { System.out.println("买全价票"); } }
package com.zhao.service.impl; import com.zhao.service.TrainStation; public class Student implements TrainStation{ @Override public void getTicket() { System.out.println("买票75折"); } }
package com.zhao.service.impl; import com.zhao.service.TrainStation; public class Child implements TrainStation{ @Override public void getTicket() { System.out.println("半价票"); } }
买票是一个行为,但是这个行为有好几种情况,接下来看我们的客户端主体,必须持有TrainStation对象
package com.zhao.client; import com.zhao.service.TrainStation; public class User { private TrainStation station; public User() { } public User(TrainStation station) { this.station = station; } public void ticket(){ station.getTicket(); } }
接下来我们测试下
package com.zhao.client; import static org.junit.Assert.*; import org.junit.Test; import com.zhao.service.impl.Student; public class UserTest { @Test public void test() { User user=new User(new Student()); user.ticket(); } }
查看输出结果
这就是策略模式,其实我们平时也在用,不过思路没这么清晰。以后写代码也是,多用组合,少用继承,还要面向接口编程。