Apapter适配器和Facade外观模式
- 格式:ppt
- 大小:6.16 MB
- 文档页数:34
C#设计模式——外观模式(FacadePattern)⼀、概述在系统设计中,某⼀个系统可能⾮常庞⼤,⽤户要使⽤该系统就不得不掌握⼤量的接⼝,造成使⽤的不便。
这时可以考虑将该系统细分成⼀系列⼦系统并使⼦系统间的耦合降到最低,利⽤外观模式提供⼀个外观对象,为这⼀系列⼦系统提供⼀个简单的使⽤接⼝,这样⽤户只需要掌握外观对象上的少量接⼝即可使⽤该系统。
就以汽车为例,⼀辆汽车由引擎、车轮、刹车等⽆数⼦系统构成,⼤多数⽤户在实际使⽤过程中并不关⼼这些⼦系统之间的⼯作细节,他们只希望能简单的启动、刹车即可。
⼆、外观模式外观模式为系统中的⼀组接⼝定义了⼀个⾼层接⼝,这个接⼝使得这⼀系统更加容易使⽤。
外观模式能有效简化外部程序和系统间的交互接⼝,将外部程序的演化和内部⼦系统的变化之间的依赖解耦。
其结构图如下:Facade知道哪些⼦系统类负责处理请求,并将客户请求代理给适当的⼦系统对象。
Subsystem classes实现了⼦系统的功能,处理由Facade对象指派的任务,但并不包含Facade对象的任何信息。
三、⽰例我们就拿汽车为例。
⾸先定义引擎、车轮、刹车等⼦系统。
1 class Engine2 {3 public void Start()4 {5 Console.WriteLine("Engine Start");6 }7 }89 class Wheel10 {11 public void TurnOn()12 {13 Console.WriteLine("Wheel is turned");14 }15 public void Stop()16 {17 Console.WriteLine("Wheel is stopped");18 }19 }2021 class Braker22 {23 public void Brake()24 {25 Console.WriteLine("Brake!");26 }27 }接着定义汽车的Facade对象。
设计模式之外观模式(FacadePattern)⼀.什么是外观模式?简单的说,外观模式是⽤来简化接⼝的。
通常,我们觉得⼀个⼦系统不好⽤,可能是因为它提供的外部接⼝太接近低层组件,让我们⽤起来感到很⿇烦。
因为我们不需要知道内部细节,我们只想要⼀个“⼀键完成”功能,调⽤⼦系统的某个⽅法,它可能替我们完成了图⽚预处理,⽽不是靠我们⾃⼰来调⽤灰度化⽅法、图像增强算法、噪声处理⽅法等等来⼀步步实现预处理。
如果⼦系统提供的接⼝太接近低层组件,不仅不易⽤,⽽且破坏了⼦系统的封装(想调⽤⼦系统就必须了解其各个低层组件,我们被迫知道了太多不应该知道的细节。
)⼆.举个例⼦假设有⼀个封装好的⽼式洗⾐机,它提供了这些对外接⼝:package FacadePattern;/*** @author ayqy* 定义洗⾐机接⼝*/public interface Washer {/** 公共部分* *///连接电源public abstract boolean connectToPower();/** 洗涤部分* *///打开左侧的洗涤舱public abstract void openLeftSide();//打开注⽔⼝public abstract void openWaterHole();//开始注⽔public abstract void startWaterInjection();//停⽌注⽔public abstract void stopWaterInjection();//开始旋转左侧洗涤舱public abstract void startWashing();//停⽌旋转左侧洗涤舱public abstract void stopWashing();/** 脱⽔部分* *///打开右侧的脱⽔舱public abstract void openRightSide();//开始旋转右侧脱⽔舱public abstract void startDewatering();//停⽌旋转右侧脱⽔舱public abstract void stopDewatering();/** 排⽔部分省略。
设计模式中的facade外观模式在JavaScript开发中的运用概念外观模式(门面模式),是一种相对简单而又无处不在的模式。
外观模式提供一个高层接口,这个接口使得客户端或子系统更加方便调用。
外观模式并不是适配器模式,适配器模式是一种包装器,用来对接口进行适配以便在不兼容系统中使用它。
而创建外观元素则是图个方便。
它并不用于达到需要特定接口的客户系统打交道这个目的,而是用于提供一个简化的接口。
JavaScript代码示例用一段再简单不过的代码来表示var getName = function {return ''svenzeng"}var getSex = function {return 'man'}如果你需要分别调用getName和getSex函数. 那可以用一个更高层的接口getUserInfo来调用.var getUserInfo = function {var info = a + b ;return info;}也许你会问为什么一开始不把getName和getSex的代码写到一起, 比如这样var getNameAndSex = function {return 'svenzeng" + "man";}答案是显而易见的,饭堂的炒菜师傅不会因为你预定了一份烧鸭和一份白菜就把这两样菜炒在一个锅里。
他更愿意给你提供一个烧鸭饭套餐。
同样在程序设计中,我们需要保证函数或者对象尽可能的处在一个合理粒度,毕竟不是每个人喜欢吃烧鸭的同时又刚好喜欢吃白菜。
外观模式还有一个好处是可以对用户隐藏真正的实现细节,用户只关心最高层的接口。
比如在烧鸭饭套餐的故事中,你并不关心师傅是先做烧鸭还是先炒白菜,你也不关心那只鸭子是在哪里成长的。
最后写个我们都用过的外观模式例子var stopEvent = function( e ){ //同时阻止事件默认行为和冒泡e.stopPropagation ;e.preventDefault ;}我知道外观模式的概念很容易掌握,你都不一定需要一个JavaScript代码的例子,但是总有些人更在乎代码,会觉得那样才更容易理解。
facade例子FACADE模式是一种结构型设计模式,它提供了一个简单的接口,隐藏了系统的复杂性,并将其与客户端代码隔离开来。
该模式通过创建一个外观类,该类封装了与多个子系统交互的复杂逻辑,从而简化了客户端代码的使用方式。
在本文中,我们将介绍FACADE模式,并提供一些实际的例子来说明其用途和优势。
一、什么是FACADE模式?FACADE模式是一种通过创建一个简单的接口来隐藏系统复杂性的设计模式。
它通过将复杂的子系统封装在一个外观类中,为客户端提供一个简单的接口。
这样,客户端就不需要了解和处理子系统的复杂逻辑,只需要通过外观类来进行交互。
二、FACADE模式的使用场景1. 当一个系统的复杂性导致难以理解和使用时,可以考虑使用FACADE模式来简化接口。
2. 当一个系统中的多个类需要协同工作,而客户端不需要知道这些细节时,可以使用FACADE模式来隐藏这些细节。
3. 当需要对一个复杂的子系统进行重构时,可以考虑使用FACADE 模式来逐步替换原有的接口。
三、FACADE模式的实现FACADE模式的实现通常包括以下几个步骤:1. 首先,需要确定哪些类和方法需要被封装在外观类中,以及如何设计外观类的接口。
2. 其次,需要编写外观类,并在其中封装子系统的复杂逻辑。
3. 最后,需要修改客户端代码,使其使用外观类来进行交互。
四、FACADE模式的例子下面是一些使用FACADE模式的实际例子:1. 电子商务平台假设我们正在开发一个电子商务平台,其中包括用户管理、商品管理、订单管理等多个子系统。
为了简化客户端的使用,我们可以创建一个外观类,封装这些子系统的复杂逻辑,并提供一个简单的接口供客户端使用。
2. 社交媒体平台在一个社交媒体平台中,用户可以进行注册、登录、发布动态、添加好友等操作。
为了简化客户端的使用,我们可以创建一个外观类,封装这些操作的复杂逻辑,并提供一个简单的接口供客户端使用。
3. 银行系统在一个银行系统中,用户可以进行存款、取款、转账等操作。
设计模式之外观模式(门面模式)门面模式(Facade Pattern)也叫做外观模式这种类型的设计模式属于结构性模式。
定义:Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higher-level interface that makes the subsystem easier to use.要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。
门面模式提供一个高层次的接口,使得子系统更易于使用。
理解外观模式(Facade)他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。
为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用应用场景为一个复杂的模块或子系统提供一个供外界访问的接口子系统相对独立——外界对子系统的访问只要黑箱操作即可预防低水平人员带来的风险扩散举例:Android 的 Context使用一个Context对象来发送广播—使用门面对象Context的sendBroadcast方法来实现对ActivityManagerNative类的访问使用一个Context对象来启动服务—使用门面对象Context的startService方法来实现对ActivityManagerNative类的访问。
使用一个Context对象来启动activity—使用门面对象Context的startActivity方法来实现对mMainThread.getInstrumentation()的访问。
使用一个Context对象来获取PackageManager信息—使用门面对象Context的getPackageManager()方法来实现的ApplicationPackageManager类的访问。
现实中的房东(subsystem classes)和中介(Facade)租户(client)uml图示例代码示例:子系统1 2 3 /** *法师*4 5 6 7 8 9101112 * @author Administrator**/public class Master {public void CreateMaster() { System.out.println("法师型小怪!"); }}1 2 3 4 5 6 7 8 9101112 /*** 战士** @author Administrator**/public class Warrior {public void CreateWarrior() { System.out.println("战士型小怪!"); }}1 2 3 4 5 6 7 8 9101112 /*** 弓箭手** @author Administrator**/public class Archer {public void CreateArcher() { System.out.println("弓手型小怪!"); }}Facade–门面对象:1 2 3 4 5 6 7 8 9 10 /*** 门面* @author Administrator**/public class Facade {private Master master = new Master(); private Warrior warrior = new Warrior(); private Archer archer = new Archer(); public void CreateMaster() {111213141516171819202122232425 this.master.CreateMaster(); }public void CreateWarrior() { this.warrior.CreateWarrior(); }public void CreateArcher() { this.archer.CreateArcher(); }}客户端:1 23 4 5 6 7 8 910111213141516171819 /*** 客户端* @author Administrator**/public class Client {public static void main(String[] args) { // TODO Auto-generated method stub Facade facade = new Facade();facade.CreateMaster();facade.CreateWarrior();facade.CreateArcher();}}输出结果:2 3 4 法师型小怪!战士型小怪!弓手型小怪!门面模式的优点松散耦合简单易用提高安全性更好的的划分访问的层次提高了灵活性依赖减少了,灵活性自然提高了。
c#设计模式之:外观模式(Facade)在软件开发过程中,客户端程序经常会与复杂系统的内部⼦系统进⾏耦合,从⽽导致客户端程序随着⼦系统的变化⽽变化,然⽽为了将复杂系统的内部⼦系统与客户端之间的依赖解耦,从⽽就有了外观模式,也称作 ”门⾯“模式。
下⾯就具体介绍下外观模式。
2.1定义外观模式提供了⼀个统⼀的接⼝,⽤来访问⼦系统中的⼀群接⼝。
外观定义了⼀个⾼层接⼝,让⼦系统更容易使⽤。
使⽤外观模式时,我们创建了⼀个统⼀的类,⽤来包装⼦系统中⼀个或多个复杂的类,客户端可以直接通过外观类来调⽤内部⼦系统中⽅法,从⽽外观模式让客户和⼦系统之间避免了紧耦合。
2.2 外观模式的结构图介绍了外观模式的定义之后,让我们具体看看外观模式的由来以及实现,下⾯与学校中⼀个选课系统为例来解释外观模式,例如在选课系统中,有注册课程⼦系统和通知⼦系统,在不使⽤外观模式的情况下,客户端必须同时保存注册课程⼦系统和通知⼦系统两个引⽤,如果后期这两个⼦系统发⽣改变时,此时客户端的调⽤代码也要随之改变,这样就没有很好的可扩展性,下⾯看看不使⽤外观模式下选课系统的实现⽅式和客户端调⽤代码:/// <summary>/// 不使⽤外观模式的情况/// 此时客户端与三个⼦系统都发送了耦合,使得客户端程序依赖与⼦系统/// 为了解决这样的问题,我们可以使⽤外观模式来为所有⼦系统设计⼀个统⼀的接⼝/// 客户端只需要调⽤外观类中的⽅法就可以了,简化了客户端的操作/// 从⽽让客户和⼦系统之间避免了紧耦合/// </summary>class Client{static void Main(string[] args){SubSystemA a = new SubSystemA();SubSystemB b = new SubSystemB();SubSystemC c = new SubSystemC();a.MethodA();b.MethodB();c.MethodC();Console.Read();}}// ⼦系统Apublic class SubSystemA{public void MethodA(){Console.WriteLine("执⾏⼦系统A中的⽅法A");}}// ⼦系统Bpublic class SubSystemB{public void MethodB(){Console.WriteLine("执⾏⼦系统B中的⽅法B");}}// ⼦系统Cpublic class SubSystemC{public void MethodC(){Console.WriteLine("执⾏⼦系统C中的⽅法C");}}View Code然⽽外观模式可以解决我们上⾯所说的问题,下⾯具体看看使⽤外观模式的实现:234567891011/// <summary>/// 以学⽣选课系统为例⼦演⽰外观模式的使⽤/// 学⽣选课模块包括功能有:/// 验证选课的⼈数是否已满/// 通知⽤户课程选择成功与否/// 客户端代码/// </summary>class Student{private static RegistrationFacade facade = new RegistrationFacade();static void Main(string[] args){if (facade.RegisterCourse("设计模式", "Learning Hard")){Console.WriteLine("选课成功");}else{Console.WriteLine("选课失败");}Console.Read();}}// 外观类public class RegistrationFacade{private RegisterCourse registerCourse;private NotifyStudent notifyStu;public RegistrationFacade(){registerCourse = new RegisterCourse();notifyStu = new NotifyStudent();}public bool RegisterCourse(string courseName, string studentName){if (!registerCourse.CheckAvailable(courseName)){return false;}return notifyStu.Notify(studentName);}}#region ⼦系统// 相当于⼦系统Apublic class RegisterCourse{public bool CheckAvailable(string courseName){Console.WriteLine("正在验证课程 {0}是否⼈数已满", courseName);return true;}}// 相当于⼦系统B// 相当于⼦系统Bpublic class NotifyStudent{public bool Notify(string studentName){Console.WriteLine("正在向{0}发⽣通知", studentName);return true;}}#endregionView Code使⽤了外观模式之后,客户端只依赖与外观类,从⽽将客户端与⼦系统的依赖解耦了,如果⼦系统发⽣改变,此时客户端的代码并不需要去改变。
PHP设计模式(九)外观模式Facade实例详解【结构型】本⽂实例讲述了PHP设计模式:外观模式Facade。
分享给⼤家供⼤家参考,具体如下:1. 概述外观模式,我们通过外观的包装,使应⽤程序只能看到外观对象,⽽不会看到具体的细节对象,这样⽆疑会降低应⽤程序的复杂度,并且提⾼了程序的可维护性。
例⼦1:⼀个电源总开关可以控制四盏灯、⼀个风扇、⼀台空调和⼀台电视机的启动和关闭。
该电源总开关可以同时控制上述所有电器设备,电源总开关即为该系统的外观模式设计。
2. 问题为了降低复杂性,常常将系统划分为若⼲个⼦系统。
但是如何做到各个系统之间的通信和相互依赖关系达到最⼩呢?3. 解决⽅案外观模式:为⼦系统中的⼀组接⼝提供⼀个⼀致的界⾯, Facade模式定义了⼀个⾼层接⼝,这个接⼝使得这⼀⼦系统更加容易使⽤。
引⼊外观⾓⾊之后,⽤户只需要直接与外观⾓⾊交互,⽤户与⼦系统之间的复杂关系由外观⾓⾊来实现,从⽽降低了系统的耦合度。
4. 适⽤性在遇到以下情况使⽤facade模式:1) 当你要为⼀个复杂⼦系统提供⼀个简单接⼝时。
⼦系统往往因为不断演化⽽变得越来越复杂。
⼤多数模式使⽤时都会产⽣更多更⼩的类。
这使得⼦系统更具可重⽤性,也更容易对⼦系统进⾏定制,但这也给那些不需要定制⼦系统的⽤户带来⼀些使⽤上的困难。
facade可以提供⼀个简单的缺省视图,这⼀视图对⼤多数⽤户来说已经⾜够,⽽那些需要更多的可定制性的⽤户可以越过facade层。
2) 客户程序与抽象类的实现部分之间存在着很⼤的依赖性。
引⼊ facade将这个⼦系统与客户以及其他的⼦系统分离,可以提⾼⼦系统的独⽴性和可移植性。
3) 当你需要构建⼀个层次结构的⼦系统时,使⽤ facade模式定义⼦系统中每层的⼊⼝点。
如果⼦系统之间是相互依赖的,你可以让它们仅通过facade进⾏通讯,从⽽简化了它们之间的依赖关系。
5. 结构6.构建模式的组成外观⾓⾊(Facade):是模式的核⼼,他被客户client⾓⾊调⽤,知道各个⼦系统的功能。
设计模式之适配器模式与外观模式(二)好了,通过上次的学习,我们已经知道适配器模式是如何将一个类的接口转换成另一个符合客户期望的接口。
同时也知道在Java中要做到这一点,必须将一个不兼容接口的对象包装起来,变成兼容的对象。
我们现在要看一个改变接口的新模式,但是它改变接口的原因是为了简化接口。
这个模式被巧妙地命名为外观模式(Facade-Pattern),之所以这么称呼,是因为它将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观。
繁琐的看电影步骤还记得我们之前说过的命令模式中,一个遥控器能控制很多家电的过程吧。
简单的开关我们都会,复杂的模式,就比较麻烦,比如看电影的步骤:1.打开爆米花机2.开始爆米花3.将灯光调暗4.放下屏幕5.打开投影机6.将投影机的输入切换到DVD7.将投影机设置在宽屏模式8.打开功放9.将功放的输入设置为DVD10.将攻放设置为环绕立体声11.将攻放音量调到中12.打开DVD播放器13.开始播放DVD看一个电影,真的是如此繁琐。
而且看完电影之后,还得过去把这些步骤都关闭。
是用你的家庭影院竟然变得如此复杂!让我们看看外观模式如何解决这团混乱,好让你轻松享受。
灯光、相机、外观!你需要的正是一个外观:有了外观模式,通过实现一个提供更合理的接口的外观类,你可以将一个复杂的子系统变得容易使用。
1.我们为家庭影院系统创建一个外观,命名为HomeTheaterFacade,它对外暴露出几个简单的方法,例如watchMovie()2.这个外观类将家庭影院诸多组件视为一个子系统,通过调用这个子系统,来实现watchMovie()方法3.现在,你的客户代码可以调用此家庭影院外观所提供的方法,而不必再调用这个子系统的方法。
4.外观只是提供你更直接的操作,并未将原来的子系统阻隔起来。
如果你需要子系统类的更高层的功能呢,还是可以使用原来的子系统的构造家庭影院外观好了,那接下来就到实战阶段啦。