Adapter Pattern,Facade Pattern。学习设计模式到现在为止10天了,这两个模式,是遇到的所有模式当中,个人觉得最容易理解的模式,无论是从其作用还是实现方式。
心法(6):外观模式
这里就对外观模式做个简单的说明,因为这个模式并不需要复杂的类型结构,它只是提供了一种简单的接口(或者是类),把所有子系统中的方法做一个整合(子系统是复杂的系统结构),然后对于client code来说,最终只需要调用外观模式的简单接口中的方法即可。官方定义----The Facade Pattern provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-leveled interface that makes the subsystem easier to use.(PS:如后学到更多的应用环境的时候,再回来重新思考这个模式)
心法(7):适配器模式
对于适配器模式其实也很好理解,首先,我们知道在coding的时候,会遇到:我们需要class1的对象来作为我们的处理对象或者链接对象,但是呢,由生成器代码生成的对象并不是class1的对象,而是class2的,就好像是国内的插头没法插进国外的插座一样。这时候,我们就需要一个转接器,也就是适配器,于是我们便可以将插头插入插座,即便这两者根本不适合。(怎有种很邪恶的想法。。。。。。。。)
实现这种魔法般效果的正是接口这个神器。
先来给出个定义-----The Adapter Pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
如上图,client code 需要target interface的对象来运行程序,但是我们现在有的只是一个adaptee这个类型的对象,怎么办呢?那就创建一个adapter吧,把adaptee变成target interface.
上代码:
Adapter:
public class IteratorEnumeration implements Enumeration<Object> {
Iterator<Object> iter;
public IteratorEnumeration(Iterator<Object> iter) {
// TODO Auto-generated constructor stub
this.iter=iter;
}
@Override
public boolean hasMoreElements() {
// TODO Auto-generated method stub
return iter.hasNext()?true:false;
}
@Override
public Object nextElement() {
// TODO Auto-generated method stub
return iter.next();
}
}
上述类就是一个adapter,很清楚,Iterator就是我们的adaptee。也就是说,我们的client code需要一个adaptee来处理,但是我们只有enumeration,于是就做了这样一个adapter。
好,接下来是完整的代码,实现一个从arraylist里读取所有偶数的client code。但是,我们不用下标,也不用iterator,我们用enumeration来作为迭代器。什么?ArrayList根本不支持enumeration接口好么?没错,是不支持,那就来个adapter吧。
Decorator:
public abstract class Decorators implements Enumeration<Object> {
public abstract boolean hasMoreElements();
public abstract Object nextElement();
}
public class EvenDecorator extends Decorators {
Enumeration<Object> enu;
int num;
public EvenDecorator(Enumeration<Object> enu){
this.enu=enu;
}
@Override
public boolean hasMoreElements() {
// TODO Auto-generated method stub
if(enu.hasMoreElements()){
num=(int)enu.nextElement();
return num%2==0?true:this.hasMoreElements();
}else{
num=0;
return false;
}
}
@Override
public Object nextElement() {
// TODO Auto-generated method stub
return num;
}
}
Main:
public class Main {
public static void main(String[] args) {
ArrayList<Object> arrs = new ArrayList<>();
for (int i = 0; i < 10; i++) {
arrs.add(i);
}
Enumeration<Object> en=new EvenDecorator(new IteratorEnumeration(arrs.iterator()));
while(en.hasMoreElements()){
System.out.println(en.nextElement());
}
}
}
看,我们通过一个enumeration对象,实现了对ArrayList的迭代。并且我们也活学活用,把之前学到的装饰模式也用于筛选偶数集合。设计模式果然博大精深啊!
最后要提一个设计原则:Principle of Least Knowledge - talk only to your immediate friends. 意思是说,不要调用其他函数返回对象的函数。形如:
state.getThermeter().getTemperature().
将state.getThermeter()变成一个函数,然后再在另一个函数里,调用getTemperature()。
也就是说,避免使用链式函数调用,尤其是他们的返回类型彼此不同又彼此依赖。(这不是javascript......这不是在写JQuery)
虽然我能理解链式调用会在后期代码重构和维护时变得很恶心,但是具体怎么样尚不可知。总之,既然是个设计原则,就尽量不要把代码写成链式的。(jquery除外。。。它本来就设计成那样,还是弱类型的,链式是减少代码量的好方法)
好了,这就是今天的成果。两个很有用而且也不难的模式。明天继续加油!