2011-03-09 97 views
145

门面一个包含很多其他类的类?什么是门面设计模式?

是什么使它成为设计模式?对我而言,它就像一个普通的班级。

你能解释一下吗门面图案?

+4

每个设计模式都在其实现一堆类。 – 2011-03-09 07:08:56

+1

为什么我得到-1票?不是一个合适的问题或一个简单的问题? – kevin 2011-03-09 07:09:21

+6

@axarydax - 由于我是新设计模式,我不知道如何提出一个难题。稍后再试! – kevin 2011-03-09 07:48:38

回答

146

设计模式是解决循环问题的常用方法。所有设计模式中的类都只是普通的类。重要的是它们是如何构建的以及它们如何一起工作以最好的方式解决给定的问题。

外观设计模式简化了与复杂系统的接口;因为它通常由组成复杂系统子系统的所有类组成。

Facade将用户从系统的复杂细节中屏蔽出来,并为它们提供simplified view,它是easy to use。它也是decouples从子系统的细节中使用系统的代码,使得以后更容易修改系统。

http://www.dofactory.com/Patterns/PatternFacade.aspx

http://www.blackwasp.co.uk/Facade.aspx

此外,什么是一边学习设计模式重要的是要能够识别哪种模式适合您的特定问题,然后适当地使用它。滥用模式或者仅仅因为知道它而试图使它适应某些问题是非常普遍的事情。在学习\使用设计模式时要注意这些缺陷。

+3

@unmesh - 是的,我仍然不知道何时使用这些设计模式。 – kevin 2011-03-09 07:34:02

+0

@kevin - 你唯一的办法就是多读些关于他们的经验,并与他们建立经验:) – 2011-03-09 07:36:34

+7

@kevin:知道何时使用它们是最困难的部分。理论上,模式可能很容易,但在实践中它们很难。你只能学习这种经验,即。编码,编码,编码。 – 2011-03-09 23:51:17

6

正面图案是结果中许多其他接口的包装,以产生更简单的接口。

设计模式很有用,因为它们可以解决重复发生的问题,并且通常可以简化代码。在一组同意使用相同模式的开发人员团队中,在维护其他代码时可以提高效率和理解。

尝试阅读关于多个模式:

外观模式:http://www.dofactory.com/Patterns/PatternFacade.aspx#_self1

或者更一般地:http://www.dofactory.com/Patterns/Patterns.aspx

+0

http://www.nileshgule.com/2012/07/facade-design-pattern.html我试图用一个住房贷款验证过程的例子来描述Facade设计模式。 – 2012-07-16 14:36:11

10

甲门面不应该被描述为含有大量的其它类的一个类。它实际上是这个类的一个接口,并且应该使类的使用更容易,否则facade类是无用的。

31

正如前面的答案中所解释的,它为消费客户提供了一个简单的界面。 例如:“观看ESPN”是预期的功能。但它涉及以下几个步骤:

  1. 如果需要,打开电视;
  2. 检查卫星/有线功能;
  3. 如果需要切换到ESPN。

但外观将简化这一点,只是向客户提供“观看ESPN”功能。

4

Facade是一个具有位于工具包和完整应用程序之间的功能级别的类,它提供了包或子系统中类的简化使用。 Facade模式的意图是提供一个使子系统易于使用的界面。 - 摘自book C#中的设计模式。

5

正面图案的另外一个用途可能是减少团队的学习曲线。让我举一个例子:

让我们假设你的应用程序需要通过使用Excel提供的COM对象模型与MS Excel进行交互。你的一个团队成员知道所有的Excel API,并在其上创建一个Facade,它满足应用程序的所有基本场景。团队中的其他成员不需要花时间学习Excel API。团队可以使用外观,而无需了解实现方案所涉及的内部组件或所有MS Excel对象。这不是很好吗?

因此,它提供了一个复杂的子系统之上的简化和统一的接口。

3

正面的另一个示例: 表示您的应用程序连接到数据库并在UI上显示结果。您可以使用Facade使应用程序可配置,如使用数据库运行或使用模拟对象。因此,您将对Facade类进行所有数据库调用,并在其中读取应用程序配置并决定触发数据库查询或返回模拟对象。这种方式应用程序成为db独立的情况下数据库不可用。

6

一个外观暴露了大多数被调用的简化函数,并且实现隐藏了客户必须处理的复杂性。一般来说,实现使用多个包,类和函数。写得很好的外观使其他类很少直接访问。例如,当我访问ATM并退出一些金额时。 ATM隐藏它是直接进入所拥有的银行,还是通过协商的外部银行网络进行。自动柜员机的功能就像一个门面,消耗了多个设备和子系统,作为客户我不必直接处理。

67

Wikipedia有一个很好的门面模式的例子。

/* Complex parts */ 

class CPU { 
    public void freeze() { ... } 
    public void jump(long position) { ... } 
    public void execute() { ... } 
} 

class Memory { 
    public void load(long position, byte[] data) { ... } 
} 

class HardDrive { 
    public byte[] read(long lba, int size) { ... } 
} 

/* Facade */ 

class ComputerFacade { 
    private CPU processor; 
    private Memory ram; 
    private HardDrive hd; 

    public ComputerFacade() { 
     this.processor = new CPU(); 
     this.ram = new Memory(); 
     this.hd = new HardDrive(); 
    } 

    public void start() { 
     processor.freeze(); 
     ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE)); 
     processor.jump(BOOT_ADDRESS); 
     processor.execute(); 
    } 
} 

/* Client */ 

class You { 
    public static void main(String[] args) { 
     ComputerFacade computer = new ComputerFacade(); 
     computer.start(); 
    } 
} 
+4

这是一个很好的例子。如果客户选择了,则客户需要能够将门面中的所有步骤拼凑在一起,私人方法不应隐藏任何内容。 – Rob 2014-11-20 23:29:35

+1

Imho这不是一个好例子,因为它没有强调用例。正如TO所说,这个例子只是一个普通的课程。与硬件的关联是一个组合。也许矫枉过正维基上的例子,但使用依赖注入而不是实例化子模块会强调意图并可能避免TO的困惑。 – ManuelSchneid3r 2016-10-05 21:29:56

27

门面隐藏了系统的复杂性,并提供从其中客户机可以访问系统到客户端的接口。

public class Inventory { 
public String checkInventory(String OrderId) { 
    return "Inventory checked"; 
} 
} 

public class Payment { 
public String deductPayment(String orderID) { 
    return "Payment deducted successfully"; 
} 
} 


public class OrderFacade { 
private Payment pymt = new Payment(); 
private Inventory inventry = new Inventory(); 

public void placeOrder(String orderId) { 
    String step1 = inventry.checkInventory(orderId); 
    String step2 = pymt.deductPayment(orderId); 
    System.out 
      .println("Following steps completed:" + step1 
        + " & " + step2); 
    } 
} 

public class Client { 
     public static void main(String args[]){ 
     OrderFacade orderFacade = new OrderFacade(); 
     orderFacade.placeOrder("OR123456"); 
     System.out.println("Order processing completed"); 
     } 
    } 
+0

是否允许子系统在不通过'OrderFacade'的情况下彼此通信?在你的例子中,在“付款”和“库存”之间? – Isuru 2016-02-08 06:43:23

1

它基本上是单窗口清除系统。

3

设计模式是软件设计中给定上下文中常见问题的通用可重用解决方案。

Facade设计模式是一种结构模式,因为它定义了在类或实体之间创建关系的方式。门面设计模式用于定义到更复杂子系统的简化界面。

当使用大量相互依赖的类或需要使用多种方法的类时,尤其是使用起来复杂或难以理解的类时,外观模式非常理想。 Facade类是一个“包装器”,它包含一组容易理解且易于使用的成员。这些成员代表Facade用户访问子系统,隐藏实现细节。

当包装设计不佳的子系统时,外观设计模式特别有用,但由于源代码不可用或现有接口被广泛使用而无法重构。有时您可能决定实施多个门面以提供用于不同目的的功能子集。

门面模式的一个示例用途是将网站与业务应用程序集成。现有软件可能包含大量必须以特定方式访问的业务逻辑。该网站可能只需要有限的访问此业务逻辑。例如,网站可能需要显示出售物品是否达到了有限的库存水平。 Facade类的IsLowStock方法可以返回一个布尔值来指示这一点。在幕后,这种方法可能会隐藏处理当前实物库存,传入库存,分配物料和每个物料的低库存水平的复杂性。

2

关于你查询的最好的解释:

是门面里面包含了很多其他类的一类?

是的。它是应用程序中许多子系统的包装器。

是什么让它成为设计模式?对我来说,它就像一个普通的类

所有的设计模式也是正常的类。 @Unmesh Kondolikar正确回答了这个问题。

你能解释一下这个门面,我是新设计模式。

根据GoF的,门面设计模式是如defind:

提供一个统一的接口子系统中的一组接口。外观模式定义了一个更高层次的接口,使子系统更容易使用

Facade模式通常适用于:需要

  1. 一个简单的接口来访问一个复杂的系统。
  2. 子系统的抽象和实现紧密耦合。
  3. 需要一个分层软件的每个级别的入口点。
  4. 系统非常复杂或难以理解。

让我们以cleartrip网站为例说一个真实的例子。

本网站提供的选项预订

  1. 机票
  2. 酒店
  3. 机票+酒店

代码片段:

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){ 

    } 
} 

说明:

  1. FlightBooking, TrainBooking and HotelBooking大系统的不同子系统:TravelFacade

  2. TravelFacade提供了一个简单的界面,预定以下选项之一

    Flight Booking 
    Train Booking 
    Hotel Booking 
    Flight + Hotel booking 
    Train + Hotel booking 
    
  3. 书TravelFacade的API内部调用子系统的以下API

    flightBooking.bookFlight 
    trainBooking.bookTrain(info); 
    hotelBooking.bookHotel(info); 
    
  4. 通过这种方式,TravelFacade提供了更简单,更简单的API,无需公开子系统API。

关键要点:(从journaldev文章的Pankaj库马尔

  1. 外观模式更像是辅助客户端应用程序
  2. 外观模式可以在任何适用开发点通常为当接口数量增长并且系统完成时 x
  3. 子系统接口不知道正面和它们不应该有门面接口的任何参考
  4. 外观模式应适用于类似种接口,其目的是提供一种单个接口而不是多个接口,可以执行类似的作业

看看sourcemaking文章,以便更好地理解。

3

Facade讨论在单个接口对象中封装复杂子系统。这减少了成功利用子系统所需的学习曲线。它还促进了子系统与潜在的许多客户的解耦。另一方面,如果Facade是子系统的唯一访问点,则会限制“强大用户”可能需要的功能和灵活性。

1

门面模式为子系统接口组提供统一接口。 Facade定义了一个高级界面,它简化了子系统的工作。