1.模式定义
策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩展。
2.问题起源
新版学习卡登录代码时,为了代码复用使用继承。结果对父类的任何修改会影响到子类,冗余代码过多,难以扩展。
代码实例:
public abstract class AbstractStudyCardLoginBiz {
/**
* 登录
*/
public abstract void login(String studyCardNo) ;
/**
* 登出 删除用户登录信息
*/
public Boolean logout() {
//实现代码略
}
}
这段登出代码完全可以得到复用,使用者只需要继承并实现登录方法。但却引出两个问题:
1.现在如果我需要向抽象类里面添加’检查是否已经登录’方法,则所有实现类都必须实现这个方法,否则会引起编译问题。
2.子类实现的登录方法无法被其他有相同功能的类复用。
解决方案1:
把登录行为和检查登录抽象为接口,让调用者实现。
代码实例:
public interface Login{
/**
* 登录
*/
void login(String studyCardNo) ;
}
public interface CheckLogin{
/**
* 检查是否登录
*/
Boolean checkLogin() ;
}
public abstract class AbstractStudyCardLoginBiz implements Login,CheckLogin{
/**
* 登录
*/
public Boolean login() {
//实现代码略
}
/**
*检查登录
*/
public Boolean checkLogin() {
//实现代码略
}
/**
* 登出 删除用户登录信息
*/
public Boolean logout() {
//实现代码略
}
}
问题:接口没有实现方法,实现代码无法得到复用。
解决方案2:把具体代码需要变化的行为完全分离出来,单独实现。
代码实例:
public interface Login{
public void login(String studyCardNo);
}
public interface CheckLogin{
public void checkLogin();
}
//其他渠道登录也只需实现接口即可
class StudyCardLogin implements Login{
@Override public void login(String studyCardNo) { // 实现代码略 }
}
class StudyCardCheckLogin implements CheckLogin{
@Override public void checkLogin() { // 实现代码略 }
}
public abstract class AbstractStudyCardLoginBiz {
//多态,调用实际子类方法
private Login login ;
private CheckLogin checkLogin;
public void setLogin (Login login ) {
this.login = login ;
}
public void setCheckLogin (CheckLogin checkLogin) {
this.checkLogin= checkLogin;
}
/**
* 登录
*/
public void doLogin(String studyCardNo){
login.login(studyCardNo);
} ;
/**
* 检查登录
*/
public void doCheckLogin(){
checkLogin.checkLogin();
} ;
/**
* 登出 删除用户登录信息
*/
public Boolean logout() {
//实现代码略
}
}
使用者只需要继承抽象类,使用set已有的登录检查登录实现接口类或者单独实现,完全做到了代码复用,解除耦合关系。
总结:
1.继承高度耦合,难以改动和扩展。
2.面向接口编程,将可变的业务抽象成接口并实现,需要添加新的方法时就添加相应的接口和实现类。
3.策略模式会产生很多策略类,所有策略类都需要对外暴露。
参考文档:
1.https://blog.csdn.net/qq_16811177/article/details/75177103
2.https://www.cnblogs.com/liuzhen1995/p/5983642.html
3.https://www.jianshu.com/p/7b7de81cdfbe