外观模式


23种设计模式

1.什么是外观模式

首先,一个程序有许许多多的功能。举一个最简单的例子:eclipse中有各种各样的功能,我们根据需要不断的切换在不同的窗口工作。在编辑窗口写代码,在包窗口管理文件,在控制台窗口查看输出,在。。。
请想象一下,如果没有窗口区分,那么eclipse的工具菜单有多长,你是否能够一下子找到这些按钮。
对于外观,只是很多的按钮混合在一起,对于这些功能的实现,那么将会是一团乱麻。
比如,在终端窗口,eclipse需要监听键盘消息,需要接受我们的输入;
在编辑窗口同样需要接受输入。。。
难道每需要一个输入的地方,就写一次监听吗?

所以,外观模式无处不在,而且,任何人都会用。
为什么这么说,因为外观模式说简单就是对复杂操作的封装。

2.外观模式

(来自w3cschool,联系删除)
意图:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口。
何时使用: 1、客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。 2、定义系统的入口。
如何解决:客户端不与系统耦合,外观类与系统耦合。
关键代码:在客户端和复杂系统之间再加一层,这一次将调用顺序、依赖关系等处理好。
应用实例: 1、去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。 2、JAVA 的三层开发模式。
优点: 1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。
缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
使用场景: 1、为复杂的模块或子系统提供外界访问的模块。 2、子系统相对独立。 3、预防低水平人员带来的风险。
注意事项:在层次化结构中,可以使用外观模式定义系统中每一层的入口。
(来自w3cschool,联系删除)

3.例子

3.1项目结构:

23种设计模式----外观模式----结构型模式_外观模式

3.2 基本操作的抽象类

package base.Abs;

public class Base {

protected String name;

public Base(String name){
this.name = name;
}

public String getName(){
return name;
}

}

3.3 具体操作的实现类

package base.impl;

import base.Abs.Base;

public class Base1 extends Base{

public Base1() {
super("Base1");
}

}
package base.impl;

import base.Abs.Base;

public class Base2 extends Base{

public Base2() {
super("Base2");
}

}
package base.impl;

import base.Abs.Base;

public class Base3 extends Base{

public Base3() {
super("Base3");
}

}
package base.impl;

import base.Abs.Base;

public class Base4 extends Base{

public Base4() {
super("Base4");
}

}
package base.impl;

import base.Abs.Base;

public class Base5 extends Base{

public Base5() {
super("Base5");
}

}
package base.impl;

import base.Abs.Base;

public class Base6 extends Base{

public Base6() {
super("Base6");
}

}
package base.impl;

import base.Abs.Base;

public class Base7 extends Base{

public Base7() {
super("Base7");
}

}

3.4 外观类(封装类)

package facade;

import base.impl.Base1;
import base.impl.Base2;
import base.impl.Base3;
import base.impl.Base4;
import base.impl.Base5;
import base.impl.Base6;
import base.impl.Base7;

public class Facade {

private Base1 b1 = new Base1();
private Base2 b2 = new Base2();
private Base3 b3 = new Base3();
private Base4 b4 = new Base4();
private Base5 b5 = new Base5();
private Base6 b6 = new Base6();
private Base7 b7 = new Base7();

public void f1324657() {
System.out.println("f1234567:\t" + b1.getName() + " " + b2.getName()
+ " " + b3.getName() + " " + b4.getName() + " " + b5.getName()
+ " " + b6.getName() + " " + b7.getName());
}

public void f7654321(){
System.out.println("f7654321:\t" + b7.getName() + " " + b6.getName()
+ " " + b5.getName() + " " + b4.getName() + " " + b3.getName()
+ " " + b2.getName() + " " + b1.getName());
}

}

3.5 调用者

package client;

import facade.Facade;

public class Main {

public static void main(String[] args) {
Facade facade = new Facade();
facade.f1324657();
facade.f7654321();
}

}

3.6 结果

f1234567: Base1 Base2 Base3 Base4 Base5 Base6 Base7
f7654321: Base7 Base6 Base5 Base4 Base3 Base2 Base1

4.更好玩的例子

我们都知道计算机可以进行一种计算:加法.
或者更简单一些,计算机只会加1.
那么其他的运算是如何实现的呢?
接下来用外观模式来体验(以整形):

4.1 首先模拟计算机加一

package base;

public class Base {

public static int base(int m){
m++;
return m;
}

}

4.2 加法

package add;

import base.Base;

public class Add {

public static int add(int number1,int number2){
while(number1 > 0){
number2 = Base.base(number2);
number1--;
}
return number2;
}


}

说明,本来不应该出现自减的,应该用补码的方式实现减一的,不过我尝试一下,使用了大概2到3种方式,没有成功,所以,只能使用自减了。

4.3 减法

package subtraction;

import add.Add;

public class Subtraction {

public static int subtraction(int number1,int number2){
return Add.add(number1, 0 - number2);
}

}

4.4 取相反数

package opposite;

import subtraction.Subtraction;

public class Opposite {

public static int opposite(int number){
return Subtraction.subtraction(0, number);
}

}

4.5 乘法

package multiplication;

import add.Add;

public class Multiplication {

public static long multiplication(int number1,int number2){
int result = 0;
while(number1 > 0){
result = Add.add(result, number2);
number1--;
}
return result;
}

}

4.6 除法

package division;

import subtraction.Subtraction;

public class Division {

private int remainder;

private int division;

public Division(int number1,int number2){
while(number1 >= number2){
number1 = Subtraction.subtraction(number1, number2);
division++;
}
remainder = number1;
}

public int getRemainder(){
return remainder;
}

public int getDivision(){
return division;
}

}

因为除法涉及到返回2个值,商与余数,所以无法像之前那样写,只能以对象的方式写,而不是静态方法。

5.总结

外观模式没什么难以理解,用一个词就是封装。
但是需要合理运用。。。。。