sugar/ 九月 18, 2019/ python设计模式/ 0 comments

外观(Facade)是在已有复杂系统之上实现的一个抽象层。

下图演示了外观的角色。计算机是一个复杂的机器,全功能运行依赖多个部件。为简化表述,这里所说的计算机是指IBM衍生的那一类,使用冯·诺依曼架构。启动一台计算机是一个相当复杂的过程。CPU、内存以及硬盘都需要加电运行;引导加载程序需要从硬盘加载到内存,CPU则必须启动操作系统内核,等等。我们不会把这些复杂性暴露给客户端,而是创造一个外观来封装整个过程,并保证所有步骤按照正确的次序运行。

从图中展示的类可知,仅Computer类需要暴露给客户端代码。客户端仅执行Computer的start()方法。所有其他复杂部件都由外观类Computer来维护。

使用外观模式的最常见理由是为一个复杂系统提供单个简单的入口点。引入外观之后,客户端代码通过简单地调用一个方法/函数就能使用一个系统。同时,内部系统并不会丢失任何功能,外观只是封装了内部系统。

不把系统的内部功能暴露给客户端代码有一个额外的好处:我们可以改变系统内部,但客户端代码不用关心这个改变,也不会受这个改变的影响。客户端代码不需要进行任何改变。

如果你的系统包含多层,外观模式也能派上用场。你可以为每一层引入一个外观入口点,并让所有层级通过它们的外观相互通信。这提高了层级之间的松耦合性,尽可能保持层级独立。

代码实现:

# coding: utf-8

from enum import Enum
from abc import ABCMeta, abstractmethod

State = Enum('State', 'new running sleeping restart zombie')


class User:
    pass


class Process:
    pass


class File:
    pass


class Server(metaclass=ABCMeta):

    @abstractmethod
    def __init__(self):
        pass

    def __str__(self):
        return self.name

    @abstractmethod
    def boot(self):
        pass

    @abstractmethod
    def kill(self, restart=True):
        pass


class FileServer(Server):

    def __init__(self):
        '''初始化文件服务进程要求的操作'''
        self.name = 'FileServer'
        self.state = State.new

    def boot(self):
        print('booting the {}'.format(self))
        '''启动文件服务进程要求的操作'''
        self.state = State.running

    def kill(self, restart=True):
        print('Killing {}'.format(self))
        '''杀死文件服务进程要求的操作'''
        self.state = State.restart if restart else State.zombie

    def create_file(self, user, name, permissions):
        '''检查访问权限的有效性、用户权限,等等'''

        print("trying to create the file '{}' for user '{}' with permissions {}".format(name, user, permissions))


class ProcessServer(Server):

    def __init__(self):
        '''初始化进程服务进程要求的操作'''
        self.name = 'ProcessServer'
        self.state = State.new

    def boot(self):
        print('booting the {}'.format(self))
        '''启动进程服务进程要求的操作'''
        self.state = State.running

    def kill(self, restart=True):
        print('Killing {}'.format(self))
        '''杀死进程服务进程要求的操作'''
        self.state = State.restart if restart else State.zombie

    def create_process(self, user, name):
        '''检查用户权限、生成PID,等等'''

        print("trying to create the process '{}' for user '{}'".format(name, user))


class WindowServer:
    pass


class NetworkServer:
    pass


class OperatingSystem:

    '''外观'''

    def __init__(self):
        self.fs = FileServer()
        self.ps = ProcessServer()

    def start(self):
        [i.boot() for i in (self.fs, self.ps)]

    def create_file(self, user, name, permissions):
        return self.fs.create_file(user, name, permissions)

    def create_process(self, user, name):
        return self.ps.create_process(user, name)


def main():
    os = OperatingSystem()
    os.start()
    os.create_file('foo', 'hello', '-rw-r-r')
    os.create_process('bar', 'ls /tmp')

if __name__ == '__main__':
    main()

在客户端代码想要使用一个复杂系统但又不关心系统复杂性之时,这种模式是为复杂系统提供一个简单接口的理想方式。

Share this Post

说点什么

avatar
  Subscribe  
提醒