最简单的两个模式,同属结构性模式,为啥把他俩放在一起呢?因为他俩实在太像了,并且我也觉得没啥区分的必要。
实际上他俩的实现方式都差不多,通过组合已有类对象来实现。
那么他俩的区别是什么呢?唯一的区别就在于外观模式创建的对象他的接口是供程序员使用的(目的),所以“外观”相较于“被外观的”接口更简单(特征)。而适配器就不一定,他创建的接口不一定会更简单,当时会为了适配已经存在的类使用的接口(目的),接口不一定会被简化,但会适配系统中已有的类所需的接口,所以经常作为其他一些设计模式的基础(例如创建型模式中的抽象工厂模式,桥接模式)。
首先外观模式举例,我们可以看一下py标准库中的ftplib模块,你会发现他的接口实在有些不同寻常(不好用),那么你可能会创建一个FtpManager类,并提供ls, cd, cwd, fget等方法,而实际上他们都是使用的ftplib.Ftp对象。这里就不拿代码举例了。
然后是适配器模式,例如现在有一个Shape类,然后他使用Displayer接口中的drawLine, drawCircle来显示图形,那么现在有一个DP类拥有drawALine, drawACircle。那么我们就可以创建一个DPDisplayer作为一个适配器。
这里使用java和python代码分别举例,实际上外观模式也差不多,只是目的不同(所以特征不同)。
java代码
public interface Displayer {
void drawLine(int x1, int y1, int x2, int y2);
void drawCircle(int o, int r);
}
public abstract class Shape {
private final Displayer d;
public Shape(Displayer d) {
this.d = d;
}
public abstract void draw();
}
public class DP {
public void drawALine(int x1, int y1, int x2, int y2) {
// do something
}
public void drawACircle(int o, int r) {
// do something
}
}
public class DPDisplayer implements Displayer {
private final DP dp;
public DPDisplayer(DP dp) {
this.dp = dp;
}
public void drawLine(int x1, int y1, int x2, int y2) {
this.dp.drawALine(x1, y2, x2, y2);
}
public void drawCircle(int o, int r) {
this.dp.drawACircle(o, r);
}
}
当然可以看到这个例子过于简单,看起来好像使用价值不大,不多Adapter模式最常和其他模式一起搭配使用所以是非常常见以及重要的一个模式(比如这里就用到了另外一种模式)。
python代码
class Displayer(abc.ABC):
@abc.abstractmethod
def drawLine(self, x1, y1, x2, y2):
pass
@abc.abstractmethod
def draeCircle(self, o, r):
pass
class Shape(abc.ABC):
@abc.abstractmethod
def draw(self):
pass
def __init__(self, displayer):
self.displayer = displayer
class DP:
def drawALine(self, x1, y1, x2, y2):
# do something
pass
def drawACircle(self, o, r):
# do something
pass
class DPDisplayer:
def __init__(self, dp):
self.dp = dp
def drawLine(self, x1, y1, x2, y2):
self.dp.drawALine(x1, y1, x2, y2)
def draeCircle(self, o, r):
self.dp.drawACircle(o, r)
之后皆以py代码举例(因为以java举例的太多了)