@w1992wishes
2018-03-13T14:38:29.000000Z
字数 4586
阅读 977
设计模式
结构型模式
本文的结构如下:
话说某天空气质量回到秦汉,月色如水倾泻,温度适宜,微风袭人,我在院子树下架起圆木桌,摆上雕花凳,桌上依次摆放红烧肘子,烧牛肉,剁椒鱼头,烤羊排,炸猛男......美人在怀,饮一口小酒,复又夹起一块牛肉放入口中,这滋味,岂不快哉?
快你个头啊,赶紧起来给我码代码。
恍惚中听到一声怒吼,我从好梦中惊醒。啊,没有酒,没有肉,没有美人,只有汉城4点钟的太阳,油腻的中年组长大叔和屏幕前没有吃完的老坛酸菜面,泪哭。
咳咳,回到正题,我们接着讲美食。美食适合享用,不宜动手操弄,如果自己动手,要做好一道美食,需要的事物很多,碗,锅,水,调味品,食材等等,需要这些东西经过一些列交互才能得到最后的美食。
美食做法实在太过累人,可是还是想吃怎么办呢?
找妈妈啊,一句:“妈,我想吃肉。”然后可以逛知乎,刷微博,打游戏,在手机上进行了一轮复杂操作,就听妈妈喊一声:“吃饭了。”于是乎,一只手握着手机改看小说,一只手夹肉,嘴里嘟囔道:“妈,你做的红烧肉太好吃了。”
咳咳,这次真的回到正题。
刚才“饿了找妈妈”的例子其实就是在说外观模式。在软件开发中,有时候某个客户类(“我”)可能会与多个业务类(“水,调味品,食材”)交互,而这些需要交互的业务类经常会作为一个整体出现,由于涉及到的类比较多,导致使用时代码较为复杂,此时,特别需要一个类似“妈妈”一样的角色,由它来负责和多个业务类进行交互,而客户类只需与该类交互。外观模式通过引入一个新的外观类(Facade)来实现该功能,外观类充当了软件系统中的“妈妈”,它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互。在外观模式中,那些需要交互的业务类被称为子系统(Subsystem)。如果没有外观类,那么每个客户类需要和多个子系统之间进行复杂的交互,系统的耦合度将很大,而引入外观类之后,客户类只需要直接与外观类交互,客户类与子系统之间原有的复杂引用关系由外观类来实现,从而降低了系统的耦合度。
插一句,不得不说,妈妈其实就像个服务员,不停服务自己的丈夫和孩子,还经常受到埋怨,太辛苦了。
为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式又称为门面模式,它是一种对象结构型模式。外观模式是迪米特法则的一种具体实现,通过引入一个新的外观角色可以降低原有系统的复杂度,同时降低客户类与子系统的耦合度。
外观模式包含如下两个角色:
外观模式中所指的子系统是一个广义的概念,它可以是一个类、一个功能模块、系统的一个组成部分或者一个完整的系统。子系统类通常是一些业务类,实现了一些具体的、独立的业务功能,其典型代码:
class SubSystemA
{
public void MethodA()
{
//业务实现代码
}
}
class SubSystemB
{
public void MethodB()
{
//业务实现代码
}
}
class SubSystemC
{
public void MethodC()
{
//业务实现代码
}
}
在引入外观类之后,与子系统业务类之间的交互统一由外观类来完成,在外观类中通常存在如下代码:
class Facade
{
private SubSystemA obj1 = new SubSystemA();
private SubSystemB obj2 = new SubSystemB();
private SubSystemC obj3 = new SubSystemC();
public void Method()
{
obj1.MethodA();
obj2.MethodB();
obj3.MethodC();
}
}
由于在外观类中维持了对子系统对象的引用,客户端可以通过外观类来间接调用子系统对象的业务方法,而无须与子系统对象直接交互。引入外观类后,客户端代码变得非常简单,典型代码:
class Program
{
static void Main(string[] args)
{
Facade facade = new Facade();
facade.Method();
}
}
/**
* Created by w1992wishes on 2017/11/9.
*/
public class Material {
public void prepare(){
System.out.println("从菜市场买回食材,并清洗");
}
}
/**
* Created by w1992wishes on 2017/11/9.
*/
public class Pan {
public void wash(){
System.out.println("炒菜前要先洗锅");
}
}
/**
* Created by w1992wishes on 2017/11/9.
*/
public class Flavouring {
public void add(){
System.out.println("依次放入各种调味品");
}
}
我进行制作美食:
/**
* Created by w1992wishes on 2017/11/9.
*/
public class Client {
public static void main(String[] args) {
Material material = new Material();
Pan pan = new Pan();
Flavouring flavouring = new Flavouring();
System.out.println("肚子饿了");
material.prepare();
pan.wash();
flavouring.add();
System.out.println("出锅,可以吃饭了");
}
}
结果:
肚子饿了
从菜市场买回食材,并清洗
炒菜前要先洗锅
依次放入各种调味品
出锅,可以吃饭了
/**
* Created by w1992wishes on 2017/11/9.
*/
public class Mom {
Material material;
Pan pan;
Flavouring flavouring;
public Mom(){
this.material = new Material();
this.pan = pan = new Pan();
this.flavouring = new Flavouring();
}
public void makeDish(){
material.prepare();
pan.wash();
flavouring.add();
}
}
妈妈制作美食:
public class Client {
public static void main(String[] args) {
Mom mom = new Mom();
System.out.println("肚子饿了");
mom.makeDish();
System.out.println("出锅,可以吃饭了");
}
}
在以下情况下可以使用外观模式: