类才有设计模式?用方法不行么?
我以为,一定程度限制新手很难应用设计模式到实际中的因素之一便是:设计模式是基于面向对象思想的,书中关于设计模式讲解均以类、接口为实现基础,可在实际使用中,新手对面向对象理解不够透彻,有限的开发经验很难想到需要那么多类的应用场景,由此造成无从下手的现状。
==============
真的必须要依赖于类吗?
不是的,虽然大部分设计模式都需要继承、接口等来实现。但是缩小应用场景,从方法级的角度,也可以实现部分设计模式的应用,毕竟设计模式只是一种思想! 我们学习设计模式,并不是要去套用,而是在将来需要时
而且从方法级的角度讲解,更容易被新手理解,并尽快付诸实践。
但也要说明的是,虽然方法级的设计模式实现很容易,但是也丢失了很多类的特性,比如多态,并且作用域也被限制了。
下面我就开始举例啦。
责任链模式
为什么要从责任链模式开始讲呢?因为它更具代表性,也是它启迪我的。
责任链模式概念:使多个对象都有机会处理请求,从而避免了请求的发送者和请求者的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有人处理为止。
我们替换为方法的概念:是多个处理方法都有机会处理请求,将这些方法连成一条链,并沿着这条链传递请求,直到有人处理为止。(毫无违和感是不是?)
那么开始实践吧。
现在我有一个需求。我有一个Banner,需要根据当前手机的状态显示不同的内容。优先级最高的是网络,就是没有网的时候一定要是没有网络。其次是Gps,然后是登录状态,最后才是用户通知内容。你看,一个明确的优先级顺序,就是一条链嘛。
看代码:
/**
* 刷新Banner
*/
public void refreshBanner() {
this.banner.setText(bannerChainState());
}
/**
* 检查banner状态并返回要显示内容
*/
private String bannerChainState(){
return bannerChainNet();
}
/**
* 检查网络状态并返回要显示内容
*/
private String bannerChainNet(){
if(NetWork.isClose())
return "请打开网络";
else
return bannerChainGps();
}
/**
* 检查Gps状态并返回要显示内容
*/
private String bannerChainGps(){
if(Gps.isClose())
return "请开启GPs";
else
return bannerChainLogin();
}
/**
* 检查登录状态并返回要显示内容
*/
private String bannerChainLogin(){
if(Login.isLogin())
reutrn "请登录";
else
return bannerChainData();
}
/**
* 检查通知信息并返回要显示内容
*/
private String bannerChainData(){
return "你有一条新通知";
}
这不就是一条责任链吗?
责任链模式的方法实现完成啦。
工厂模式/建造者模式
工厂模式的实现更为简单。但方法级的工厂模式作用域被打打缩小了。
方法级的工厂模式,适用于类内部多处大量创建的场景。
举例,如果有一个大量Dialog弹出交互的需求,Dialog一个弹完又一个,且Dialog大部分类似,那么你可以设立三个Dialog工厂方法:
//创建Dialog方法
private Dialog createDialog(int type);
//创建DialogView方法
private View createDialogView(int type);
//创建Dialog监听事件方法
private DialogEvent createDialogEvent(int type);
在createDialog中调用createDialogView,createDialogEvent两个方法。
同理,方法级的工厂是将对象创建封装进一个方法,建造者模式同样可以将对象创建的过程封装进一个方法内。
模板模式
java的多态除了可以通过继承、接口来实现,重载同样是多态的一种,编译时多态。
模板模式的方法级实现,略微偏移原本,但也是你熟悉的,就是方法的重载。
看代码一目了然。
需求:创建一个小汽车
//创建默认汽车
private Car createCar(){
return createCar(“宝马”,“红色”,“SUV”);
}
//自定义品牌
private Car createCar(String brand){
return createCar(brand,"红色",“SUV”)
}
//自定义品牌和颜色
private Car createCar(String brand,String color){
return createCar(brand,color,"SUV");
}
//所有属性自定义
private Car createCar(String brand,String color,String type){
return new Car(brand,color,type);
}
代理模式/装饰模式
代理模式、装饰模式都是委托的一种,在原有对象的基础上进行扩展。只不过代理模式更注重的是对过程的控制,而装饰模式更注重对功能的扩展。
而方法级别的委托,就是在原有方法的基础上对过程或功能进行限制于扩展。
需求:开车
//真正的开车方法
//oil:油量 bat:速度 driverAge:司机年龄
private void drive(int oil ,int bat,int driverAge)
//扩展方法
private void driveCar(int oil ,int bat,int driverAge){
//限制
if(checkOil(oil)){
Log.w("油不够");
return ;
}
//限制
if(checkBat(bat)){
Log.w("超速啦");
}
//扩展
driverAge = checkDriverAge(driverAge);
//汽车启动了真的启动~
drive(oil,bat,driverAge);
}
//检查油箱
private boolean checkOil(int oil){
if(oil<=10){
Log.w("油不够呀");
return false;
} else if(oil >= 200){
Log.w("油加的太多了太危险");
return false;
} else {
return true;
}
}
private boolean checkBat(int bat){
if(bat >= 200){
Log.w("超速了,不能跑!");
return false;
}
return true;
}
private int checkDriverAge(int age){
if(age < 18){
//年龄太小了不能开呀,伪造一下吧
return 18;
}
return age;
}
适配器模式
适配器模式的作用是将本来接口不同,不能依赖的对象转变为接口相同,可以依赖的对象。
方法级的适配器模式也是同样的道理.
本来我只能接受int型参数你却给了我String,本来我要的是User对象,你给了我一个userId.
class MyClass{
int age;
User user;
public void setAge(int age){
this.age = age;
}
public void setAge(String age){
this.age = Integer.valueOf(age);
}
public void setUser(User user){
this.user = user;
}
public void setUser(int userId){
this.user = UserManager.findUser(userId);
}
}