Android中所涉及的常用设计模式
观察者 1:Weather{description='晴转多云'}
观察者 2:Weather{description='晴转多云'}
观察者 1:Weather{description='多云转阴'}
观察者 2:Weather{description='多云转阴'}
观察者 2:Weather{description='台风'}
好,我们来看一下在 Android 中的应用,从最简单的开始,Button 的点击事件Buttonbtn=newButton(this);
btn.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
Log.e("TAG","click");
}
});另外广播机制,本质也是观察者模式
调用 registerReceiver 方法注册广播,调用 unregisterReceiver 方法取消注册,之后使用 sendBroadcast 发送广播,之后注册的广播会受到对应的广播信息,这就是典型的观察者模式
开源框架 EventBus 也是基于观察者模式的,
观察者模式的注册,取消,发送事件三个典型方法都有EventBus.getDefault().register(Objectsubscriber);
EventBus.getDefault().unregister(Objectsubscriber);
EventBus.getDefault().post(Objectevent);
4 、策略模式
定义:策略模式定义了一系列算法,并将每一个算法封装起来,而且使他们可以相互替换,策略模式让算法独立于使用的客户而独立改变
最常见的就是关于出行旅游的策略模式,出行方式有很多种,自行车,汽车,飞机,火车等,如果不使用任何模式,代码是这样子的publicclassTravelStrategy{
enumStrategy{
WALK,
PLANE,
SUBWAY
}
privateStrategystrategy;
publicTravelStrategy(Strategystrategy){
this.strategy=strategy;
}
publicvoidtravel(){
if(strategy==Strategy.WALK){
print("walk");
}elseif(strategy==Strategy.PLANE){
print("plane");
}elseif(strategy==Strategy.SUBWAY){
print("subway");
}
}
publicvoidprint(Stringstr){
System.out.println("出行旅游的方式为:"+str);
}
publicstaticvoidmain(String[]args){
TravelStrategywalk=newTravelStrategy(Strategy.WALK);
walk.travel();
TravelStrategyplane=newTravelStrategy(Strategy.PLANE);
plane.travel();
TravelStrategysubway=newTravelStrategy(Strategy.SUBWAY);
subway.travel();
}
}很明显,如果需要增加出行方式就需要在增加新的 else if 语句,这违反了面向对象的原则之一,对修改封装(开放封闭原则)
题外话:面向对象的三大特征:封装,继承和多态
五大基本原则:单一职责原则(接口隔离原则),开放封闭原则,Liskov 替换原则,依赖倒置原则,良性依赖原则
好,回归主题,如何用策略模式来解决这个问题
首先,定义一个策略的接口publicinterfaceStrategy{
voidtravel();
}然后根据不同的出行方法来实现该接口
publicclassWalkStrategyimplementsStrategy{
@Override
publicvoidtravel(){
System.out.println("walk");
}
}publicclassPlaneStrategyimplementsStrategy{
@Override
publicvoidtravel(){
System.out.println("plane");
}
}publicclassSubwayStrategyimplementsStrategy{
@Override
publicvoidtravel(){
System.out.println("subway");
}
}此外还需要一个包装策略的类,来调用策略中的接口
publicclassTravelContext{
Strategystrategy;
publicStrategygetStrategy(){
returnstrategy;
}
publicvoidsetStrategy(Strategystrategy){
this.strategy=strategy;
}
publicvoidtravel(){
if(strategy!=null){
strategy.travel();
}
}
}测试一下代码:
publicclassMain{
publicstaticvoidmain(String[]args){
TravelContexttravelContext=newTravelContext();
travelContext.setStrategy(newPlaneStrategy());
travelContext.travel();
travelContext.setStrategy(newWalkStrategy());
travelContext.travel();
travelContext.setStrategy(newSubwayStrategy());
travelContext.travel();
}
}以后如果再增加什么别的出行方式,就再继承策略接口即可,完全不需要修改现有的类
策略模式优缺点
定义一系列算法:策略模式的功能就是定义一系列算法,实现让这些算法可以相互替换。所以会为这一系列算法定义公共的接口,以约束一系列算法要实现的功能。如果这一系列算法具有公共功能,可以把策略接口实现成为抽象类,把这些公共功能实现到父类里面,对于这个问题,前面讲了三种处理方法,这里就不罗嗦了。
避免多重条件语句:根据前面的示例会发现,策略模式的一系列策略算法是平等的,可以互换的,写在一起就是通过 if-else 结构来组织,如果此时具体的算法实现里面又有条件语句,就构成了多重条件语句,使用策略模式能避免这样的多重条件语句。
更好的扩展性:在策略模式中扩展新的策略实现非常容易,只要增加新的策略实现类,然后在选择使用策略的地方选择使用这个新的策略实现就好了。
客户必须了解每种策略的不同:策略模式也有缺点,比如让客户端来选择具体使用哪一个策略,这就可能会让客户需要了解所有的策略,还要了解各种策略的功能和不同,这样才能做出正确的选择,而且这样也暴露了策略的具体实现。
增加了对象数目:由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
只适合扁平的算法结构:策略模式的一系列算法地位是平等的,是可以相互替换的,事实上构成了一个扁平的算法结构,也就是在一个策略接口下,有多个平等的策略算法,就相当于兄弟算法。而且在运行时刻只有一个算法被使用,这就限制了算法使用的层级,使用的时候不能嵌套使用。
Android 中的应用
下面说说在 Android 里面的应用。在 Android 里面策略模式的其中一个典型应用就是 Adapter,在我们平时使用的时候,一般情况下我们可能继承 BaseAdapter,然后实现不同的 View 返回,GetView 里面实现不同的算法。外部使用的时候也可以根据不同的数据源,切换不同的 Adapter。
来源: