初学设计模式(6)-----适配器模式,外观模式

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除外。。。它本来就设计成那样,还是弱类型的,链式是减少代码量的好方法)

好了,这就是今天的成果。两个很有用而且也不难的模式。明天继续加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值