策略模式
在看了策略模式以后,发现真的自己以前写的代码有好多都很丑,特别是有if-else的时候,策略模式解决了我之前一直不知道怎么优化代码的问题,下面就来看看策略模式的基本实现。
策略模式定义
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们还可以相互转换。策略模式让算法独立于使用它的客户而独立化。
策略模式的使用场景
- 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时
- 需要安全地封装同一类型的操作时
- 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时
策略模式的简单实现
以我们出行选择交通工具为例,选择不同的交通工具花费的价格不同(算法),因此会有多种选择。
这是选择哪种出行方式的if-else代码:
int calculatePrice(int km,int type){
if(type == BUS)
return busPrice(km);
else if(type == SUBWAY)
reutrn subwayPrice(km);
return 0;
}
这种代码风格就是我常用的形式,影响最深的就是在检测判断登录注册的时候,一些输入是否符合规格,有很多if-else,特别繁杂。
策略模式提供了一个策略接口,可以让子类继承,最后在context中实现。
public interface CalculateStrategy{
//按距离计算价格
int calculatePrice(int km);
}
公交车计算价格策略
public class BusStrategy implements CalculateStrategy{
public int calculatePrice(int km){
//具体计算法
}
}
地铁价格计算策略
public class SubwayStrategy implements CalculateStrategy{
public int calculatePrice(int km){
//具体计算法
}
}
公交出行价格计算器
public class TranficCalculator{
public static void main(String[] args){
TranficCalculator calculator = new TranficCalculator();
//设置计算策略
calculator.setStrategy(new BusStrategy());
calculator.calculatePrice(20);
}
CalculateStrategy mStrategy;
public void setStrategy(CalculateStrategy mStrategy){
this.mStrategy = mStrategy;
}
public int calculatePrice(int km){
return mStrategy.calculatePrice(km);
}
}
状态模式
状态模式定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式的使用场景
- 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
- 代码中包含大量与对象状态有关的条件语句。
状态模式的简单示例
代码场景:电视遥控器有两种状态,开机状态和关机状态。开机状态下可以调上一频道、下一频道、调高音量、调低音量。
电视状态方法接口,定义了电视操作的函数
public interface TvState{
public void nextChannel();
public void prevChannel();
public void turnUp();
public void turnDown();
}
关机状态,功能无效
public class PowerOffState implements TvState{
@override
public void nextChannel(){
}
@override
public void prevChannel(){
}
@override
public void turnUp(){
}
@override
public void turnDown(){
}
}
开机状态
public class PowerOnState implements TvState{
@override
public void nextChannel(){
System.out.println("下一频道");
}
@override
public void prevChannel(){
System.out.println("上一频道");
}
@override
public void turnUp(){
System.out.println("调高音量");
}
@override
public void turnDown(){
System.out.println("调低音量");
}
}
电源操作接口
public interface PowerController{
public void powerOn();
public void powerOff();
}
电视遥控器,根据传入的状态执行相应的操作
public class TvController implements PowerController{
TvState mTvState;
public void setTvState(TvState mTvState){
this.mTvState = mTvState;
}
@override
public void powerOn(){
setTvState(new PowerOnState());
System.out.println("开机啦");
}
@override
public void powerOff(){
setTvState(new PowerOffState());
System.out.println("关机啦");
}
public void nextChannel(){
mTvState.nextChannel();
}
public void prevChannel(){
mTvState.prevChannel();
public void turnUp(){
mTvState.turnUp();
}
public void turnDown(){
mTvState.turnDown();
}
}
客户端调用
public class Client{
public static void main(String[] args){
TvController tvController = new TvController();
tvController.powerOn();
tvController.nextChannl();
tvController.turnUp();
tvController.powerOff();
tvController.turnUp();
}
}
状态模式主要是针对有不同状态下的不同表现形式的情况使用。像我们对一个东西进行评论,这时只有登录过账号才可以,这里就有一个登录状态和未登陆转态,若是登录状态就可进行转发,若是不能未登录状态就跳转到登录页面。我们就可以设置一个总的用户状态接口,封装转发、评论的方法,在设置登录状态类和未登录状态类根据各自的需要去执行内部方法,最后一个总context类,去根据需要来调用状态类中的方法。
状态模式和策略模式相比,还是很好区分的,我们要根据不同的情况选择适用的模式。