经典设计模式之门面模式(Python实现)

门面通常是指建筑物的表面,尤其是最有吸引力的那一面。它也可以表示一种容易让人误解某人的真实感受或情况的行为或面貌。当人们从建筑物外面经过时,可以从欣赏其外部面貌,却无需去了解建筑内部构造的复杂性,这就是门面模式的使用方式。门面在隐藏内部系统复杂性的同时,为客户端提供了一个接口,以便它们可以非常轻松的访问系统。

列举一个很浅显的例子,我们去商店买东西,但是我们对这个商店对布局并不清楚,因此我们找到了商店的老板,告诉他我们需要什么东西,然后老板为我们取到这个商品,这个过程是不是比我们自己去寻找要更简单和方便很多呢。在门面模式中,我们可以把自己理解为客户端,老板理解为接口。

门面设计模式实际上完成了下列事项:

  • 它为子系统中的一组接口提供了一个统一的接口,并定义一个高级接口来帮助客户端通过更加简单的方式使用子系统。
  • 门面所解决的问题是,如何使用单个接口对象来表示复杂的子系统。实际上,它并不是封装子系统,而是对底层子系统进行组合。
  • 它促进了实现与多个客户端的解耦。

简单画一个UML图表示如下:

在这里插入图片描述
如UML图所表示,在门面模式中,主要有三个参与者:

  • 门面:门面的主要责任是,将一组复杂系统封装起来,从而为外部世界提供一个舒适的外观。
  • 系统:这代表一组不同的子系统,使整个系统混杂在一起,难以观察或使用。
  • 客户端:客户端与门面进行交互,这样就可以轻松的与子系统进行通信并完成工作了,不必担心系统的复杂性。

我们通过一个生活的场景来实现门面模式:
假设你要策划举办一场婚礼,并且由你来张罗这一切。这是个艰巨的任务,你必须要预定一家酒店或者某个场地,与餐饮人员交代酒菜、布置场景,并安排背景音乐等。

现在,假设我们经过了一系列的操作,已经完成了这个艰巨的任务,例如找相关人员谈话,与他们进行协调、敲定价格等,那么现在我们就很轻松了。这时,我们可以找到会务经理,让他去为我们处理这些事情,会务经理负责与各个服务商进行交涉,并为我们争取最优价格。
现实世界的场景设定好之后,我们再从门面模式的角度来看下整个事情:

  • 客户端:我们需要在婚礼之前准备好所有的工作。
  • 门面:会务经理负责与所有相关人员进行交涉,这些人员负责处理食物,花卉装饰等。
  • 子系统:它们表示提供餐饮、酒店管理和花卉装饰等服务的系统。

现在,我们开始用代码来实现具体的功能:

class EventManager(object):
    def __init__(self):
        print('Event Manager:Let me talk to the folks\n')

    def arrange(self):
        self.hotelier = Hotelier()
        self.hotelier.bookHotel()
        self.florist = Florist()
        self.florist.setFlowerRequirements()
        self.caterer = Caterer()
        self.caterer.setCuisine()
        self.musician = Musician()
        self.musician.setMusicType()

门面类理解起来很容易,我们把需要的子系统的调用接口放到门面类里,在调用arrange方法时会依次对各子系统产生调用。
下面我们来依次开发子系统:

class Hotelier:
    def __init__(self):
        print('Arranging the Hotel for Marriage?')

    def __isaVailable(self):
        print('Is the Hotel free for the Event on given day?')
        return True

    def bookHotel(self):
        if self.__isaVailable():
            print('Registered the Booking\n\n')


class Florist:
    def __init__(self):
        print('Flower Decorations for the Event?')

    def setFlowerRequirements(self):
        print('Carnations, Roses and Lilies would be used for Decorations\n\n')


class Caterer:
    def __init__(self):
        print("Food Arrangements for the Event")

    def setCuisine(self):
        print('Chinese & Continental Cuisine to be served\n\n')


class Musician:
    def __init__(self):
        print('Musician Arrangements for the Marriage')

    def setMusicType(self):
        print('Jazz and classical will be played\n\n')
  • Hotelier类用于预订酒店。它又一个方法,用于检查当天是否还有免费的酒店(__isAvailable)。
  • Fiorist类负责花卉装饰。这个类提供了setFlowerRequirements()方法,用于选定花的种类。
  • Caterer类负责餐饮相关。它提供了一个setCuisine()方法,用来指定菜肴。
  • Musician类负责音乐相关。它提供了setMusicType()方法,用来指定现场音乐类型。

此时,门面和相关子系统设计都已完成,而我们作为总负责人,即客户端,需要做的事情很简单。在需要某些服务时,我们并不需要亲自上手,我们仅仅需要通知会务经理,他会为我们解决所有问题!
客户端类实现(包含了启动方法):

class You(object):
    def __init__(self):
        print('You: whoa! Marriage Arrangements???!!!')

    def askEventManager(self):
        print('You: Lets Contact Event Manager\n\n')
        em = EventManager()
        em.arrange()

    def __del__(self):
        print('You: Thanks to Event Manager, all preparations done! Phew!')


if __name__ == '__main__':
    you = You()
    you.askEventManager()

运行结果如下:

You: whoa! Marriage Arrangements???!!!
You: Lets Contact Event Manager


Event Manager:Let me talk to the folks

Arranging the Hotel for Marriage?
Is the Hotel free for the Event on given day?
Registered the Booking


Flower Decorations for the Event?
Carnations, Roses and Lilies would be used for Decorations


Food Arrangements for the Event
Chinese & Continental Cuisine to be served


Musician Arrangements for the Marriage
Jazz and classical will be played


You: Thanks to Event Manager, all preparations done! Phew!

关于门面模式先介绍道这里。总而言之,门面模式能够创建一个简单的接口来供客户使用,它极大的简化了子系统的复杂性,该模式下,客户端使用体验会大大提高。

猜你喜欢

转载自blog.csdn.net/airenKKK/article/details/96651573
今日推荐