您的位置:首页 > 编程语言 > Java开发

JAVA设计模之外观模式

2016-10-09 09:16 323 查看
Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。

使用facade以前

假设有五个类:propressor, compiler, assembler, linker, ar。分别负责gcc的五个步骤:预编译、编译、汇编、链接、打包(参考《linux g++ 链接》)。

这五个步骤各自分工完成各自的工作,但它们之前又存在耦合。比如预编译、编译、汇编、链接这四个步骤就是有顺序关系的。它们必须被依次执行,才能得到正确的结果。

然而使用者并不关心它们之间是怎么合作的,他们只希望使用一个gcc命令就能得到最终的可执行文件。

public class user {
private target generateTarget(file source)
{
propressor cpp;
compiler cc1;
assembler as;
linker ld;

target i = cpp.propressing(source);
target s = cc1.compilation(i);
target o = as.assembly(s);
target out = ld.linking(o);
return out;
}

public void main(String[] args) {
target exe = generateTarget(args[1]);
}
}


有时候,用户只是想生成静态库和动态库。

public class user {
private target generateStaticLib(file source)
{
propressor cpp;
compiler cc1;
assembler as;
ar ar;

target i = cpp.propressing(source);
target s = cc1.compilation(i);
target o = as.assembly(s);
target a = ar.ar(o);
return a;
}
private target generateDynamicLib(file source)
{
propressor cpp;
compiler cc1;
assembler as;
linker ld;

target i = cpp.propressing(source);
target s = cc1.compilation(i);
target o = as.assembly(s);
target so = ld.linkingWithPic(o);
return so;
}

public void main(String[] args) {
target lib1 = generateStaticLib(args[1]);
target lib2 = generateDynamicLib(args[2]);
}
}


引入facade以后

如果你对gcc编译链接的过程有一定的了解,一定能很容易地读懂这几个函数。

但是并不是每一个写user的人都很清楚这个几步骤的使用方式。

即使知道这些步骤,要求每个user都写一遍也是件烦琐的事情。

想像一下,如果没有gcc命令,你想要 通过源代码生成可执行文件或者库,就不得不依次敲下cpp、cc1、as、ld、ar这几个命令去生成。你一定宁愿花几分钟写个脚本,把这几个命令装到一起,统一执行。

装饰器的作用有点类似于这个脚本。gcc过程中的几个子系统,用法比较复杂,因此把常用的几个种用法封装成接口,以简化用户的使用。而对于特殊情况,也可以直接使用子系统。

public class gcc {
public target generateTarget(file source)
{
propressor cpp;
compiler cc1;
assembler as;
linker ld;

target i = cpp.propressing(source);
target s = cc1.compilation(i);
target o = as.assembly(s);
target out = ld.linking(o);
return out;
}
public target generateStaticLib(file source)
{
propressor cpp;
compiler cc1;
assembler as;
ar ar;

target i = cpp.propressing(source);
target s = cc1.compilation(i);
target o = as.assembly(s);
target a = ar.ar(o);
return a;
}
public target generateDynamicLib(file source)
{
propressor cpp;
compiler cc1;
assembler as;
linker ld;

target i = cpp.propressing(source);
target s = cc1.compilation(i);
target o = as.assembly(s);
target so = ld.linkingWithPic(o);
return so;
}
}

public class user {
public static void main(String[] args) {
gcc g;
target out = g.generateTarget(args[1]);
target lib1 = generateStaticLib(args[2]);
target lib2 = generateDynamicLib(args[3]);
target i = cpp.propressing(source);
}
}


用后感

一个外观模式写完了,现在分析一下它起到的作用。

1.外观gcc为复杂的子系统propressor, compiler, assembler, linker, ar提供了简单的接口。用户不需要理解子系统之间的关系就可以理解gcc提供的功能。

2.这几个子系统的功能相关,耦合性比较高,子系统之间的关系发生变化的可能性比较大,但所提供功能变化的可能性不大。当子系统之间发生了变化,而功能未变时,只需要修改外观gcc即可,用户代码不需要修改。

3.对于特殊情况,也可以直接使用子系统,保持了原来的灵活性。

在有些情况下,它能起到积极的作用,有些情况可能会带来相反的效果。每一种模式都有它的适用场景。

1.多个类为同一个功能服务,它们之间耦合较高,使用复杂。

2.多个类之间的关系经常发生变化。

3.多个类互相配合使用的方法中,有些常用搭配。

4.用户通常不关心几个类之间的配合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息