import java.util.*;
public class TravelFacade{
FlightBooking flightBooking;
TrainBooking trainBooking;
HotelBooking hotelBooking;
enum BookingType {
Flight,Train,Hotel,Flight_And_Hotel,Train_And_Hotel;
};
public TravelFacade(){
flightBooking = new FlightBooking();
trainBooking = new TrainBooking();
hotelBooking = new HotelBooking();
}
public void book(BookingType type, BookingInfo info){
switch(type){
case Flight:
// book flight;
flightBooking.bookFlight(info);
return;
case Hotel:
// book hotel;
hotelBooking.bookHotel(info);
return;
case Train:
// book Train;
trainBooking.bookTrain(info);
return;
case Flight_And_Hotel:
// book Flight and Hotel
flightBooking.bookFlight(info);
hotelBooking.bookHotel(info);
return;
case Train_And_Hotel:
// book Train and Hotel
trainBooking.bookTrain(info);
hotelBooking.bookHotel(info);
return;
}
}
}
class BookingInfo{
String source;
String destination;
Date fromDate;
Date toDate;
List<PersonInfo> list;
}
class PersonInfo{
String name;
int age;
Address address;
}
class Address{
}
class FlightBooking{
public FlightBooking(){
}
public void bookFlight(BookingInfo info){
}
}
class HotelBooking{
public HotelBooking(){
}
public void bookHotel(BookingInfo info){
}
}
class TrainBooking{
public TrainBooking(){
}
public void bookTrain(BookingInfo info){
}
}
说明:
FlightBooking, TrainBooking and HotelBooking 是大型系统的不同子系统: TravelFacade
TravelFacade 提供了一个简单的界面来预订以下选项之一
Flight Booking
Train Booking
Hotel Booking
Flight + Hotel booking
Train + Hotel booking
19 回答
设计模式是解决重复出现问题的常用方法 . 所有设计模式中的类都只是普通类 . 重要的是它们的结构如何以及如何以最佳方式协同解决特定问题 .
Facade设计模式简化了与复杂系统的接口;因为它通常由构成复杂系统子系统的所有类组成 .
Facade保护用户免受系统的复杂细节的影响,并为他们提供
simplified view
的easy to use
. 它也是decouples
从子系统的细节使用系统的代码,使以后更容易修改系统 .http://www.dofactory.com/Patterns/PatternFacade.aspx
http://www.blackwasp.co.uk/Facade.aspx
此外,在学习设计模式时,重要的是能够识别哪种模式适合您给定的问题,然后适当地使用它 . 滥用模式或者仅仅因为你知道它而试图使它适应某些问题是一件非常普遍的事情 . 使用设计模式学习\时要注意这些陷阱 .
Wikipedia有一个很好的Facade模式的例子 .
如前面的答案中所解释的,它为消费客户端提供了一个简单的界面 . 例如:“观看ESPN”是预期的功能 . 但它涉及以下几个步骤:
如果需要,打开电视;
检查卫星/电缆功能;
如果需要,切换到ESPN .
但是外观将简化这一点,并为客户提供“观看ESPN”功能 .
Facade隐藏了系统的复杂性,并为客户端提供了访问系统的接口 .
不应将外观描述为包含许多其他类的类 . 它实际上是这个类的接口,应该使类的使用更容易,否则外观类是无用的 .
一个简短而简单的解释:
Facade模式为子系统中的一组接口提供统一接口 .
Facade定义了一个更高级别的接口,使子系统更易于使用 .
尝试了解使用和不使用Façade的场景:
如果您想将资金从accout1转移到account2,那么要调用的两个子系统将从account1退出并存入account2 .
Facade模式是结果中许多其他接口的包装器,以生成更简单的接口 .
设计模式很有用,因为它们可以解决重复出现的问题并且通常可以简化代码 . 在同意使用相同模式的开发人员团队中,它可以在维护彼此代码时提高效率和理解 .
尝试阅读更多模式:
门面图案:http://www.dofactory.com/Patterns/PatternFacade.aspx#_self1
或更一般地说:http://www.dofactory.com/Patterns/Patterns.aspx
关于你的疑问:
是 . 它是应用程序中许多子系统的包装器 .
所有设计模式也都是普通类 . @Unmesh Kondolikar正确地回答了这个问题 .
根据GoF的说法, Facade 设计模式被定义为:
为子系统中的一组接口提供统一接口 . Facade Pattern定义了一个更高级别的接口,使子系统更易于使用
Facade模式通常在以下情况下使用:
访问复杂系统需要一个简单的界面 .
子系统的抽象和实现是紧密耦合的 .
需要每个级别的分层软件的入口点 .
系统非常复杂或难以理解 .
让我们以cleartrip网站为例 .
本网站提供预订选项
航班
酒店
航班酒店
代码段:
说明:
FlightBooking, TrainBooking and HotelBooking
是大型系统的不同子系统:TravelFacade
TravelFacade
提供了一个简单的界面来预订以下选项之一来自TravelFacade的
TravelFacade
提供了更简单,更简单的API,无需暴露子系统API .关键要点:(来自journaldev Pankaj Kumar的文章)
Facade模式更像是 helper 用于客户端应用程序
外观图案可以应用于任何开发点,通常是 when the number of interfaces grow and system gets comple x .
子系统接口不知道Facade,他们 shouldn’t have any reference of the Facade interface
Facade pattern should be applied for similar kind of interfaces ,其目的是提供单一界面而不是多个界面来完成类似的工作
请看一下sourcemaking文章,以便更好地理解 .
Façade模式的另一个用途可能是减少你的学习曲线球队 . 让我给你举个例子:
让我们假设您的应用程序需要通过使用Excel提供的COM对象模型与MS Excel交互 . 您的一个团队成员了解所有Excel API,并在其上创建了一个Facade,它可以满足应用程序的所有基本方案 . 团队中没有其他成员需要花时间学习Excel API . 团队可以使用外观,而无需了解实现场景所涉及的内部或所有MS Excel对象 . 不是很棒吗?
因此,它在复杂的子系统之上提供简化的统一界面 .
Facade暴露了大多数被调用的简化函数,实现隐藏了客户本来必须处理的复杂性 . 一般来说,实现使用多个包,类和函数 . 编写好的外观使得其他类的直接访问很少见 . 例如,当我访问ATM并取出一些金额时 . ATM隐藏它是直接进入自有银行还是通过协商网络进行外部银行 . ATM就像一个门面消耗多个设备和子系统,作为客户端我不必直接处理 .
资料来源:https://sourcemaking.com/design_patterns/facade
另一个外观示例:假设您的应用程序连接到数据库并在UI上显示结果 . 您可以使用facade来使应用程序可配置,如使用数据库或使用模拟对象运行 . 因此,您将对facade类进行所有数据库调用,它将读取app config并决定触发db查询或返回模拟对象 . 这样,在db不可用的情况下,应用程序变为db独立 .
设计模式是软件设计中给定上下文中常见问题的通用可重用解决方案 .
Facade设计模式是一种结构模式,因为它定义了在类或实体之间创建关系的方式 . 外观设计模式用于定义更复杂子系统的简化界面 .
当使用大量相互依赖的类或需要使用多种方法的类时,外观模式是理想的,特别是当它们使用复杂或难以理解时 . facade类是一个“包装器”,它包含一组易于理解且易于使用的成员 . 这些成员代表Facade用户访问子系统,隐藏实现细节 .
当包装设计不良但由于源代码不可用或现有接口被广泛使用而无法重构的子系统时,外观设计模式特别有用 . 有时您可能决定实现多个外观以提供用于不同目的的功能子集 .
Facade模式的一个示例用途是用于将网站与业务应用程序集成 . 现有软件可能包括必须以特定方式访问的大量业务逻辑 . 该网站可能只需要对此业务逻辑的有限访问权限 . 例如,网站可能需要显示待售商品是否已达到有限的库存水平 . facade类的IsLowStock方法可以返回一个布尔值来表示这一点 . 在幕后,这种方法可能隐藏处理当前实物库存,进货库存,分配物料和每个物料的低库存水平的复杂性 .
这个模式有一个非常好的现实生活例子 - The car starter engine .
作为司机,我们只需打开钥匙即可开始上车 . 尽可能简单 . 在幕后,涉及许多其他汽车系统(如电池,发动机,燃料等),以便汽车成功启动,但它们隐藏在启动器后面 .
如您所见,汽车启动器是Facade . 它为我们提供了易于使用的界面,而无需担心所有其他汽车系统的复杂性 .
让我们总结一下:
Facade模式简化并隐藏了大型代码块或API的复杂性,提供了更清晰,易懂且易于使用的界面 .
所有设计模式都是以某种方式排列的某些类,或者适合特定应用的其他类 . 立面图案的目的是隐藏操作或操作的复杂性 . 您可以看到一个示例并从http://preciselyconcise.com/design_patterns/facade.php学习外观模式
它基本上是单窗口清除系统 . 您将委托任何工作委托给另一个类中的特定方法 .
Facade Design Pattern采用结构设计模式 . 简而言之,Facade意味着外观 . 这意味着在Facade设计模式中我们隐藏某些内容并仅显示客户端实际需要的内容 . 阅读以下博客:http://www.sharepointcafe.net/2017/03/facade-design-pattern-in-aspdotnet.html
Facade模式为子系统接口组提供了统一的接口 . Facade定义了一个高级接口,简化了子系统的工作 .