万物之中, 希望至美.

设计模式之外观模式

2018.10.18

一个系统会随着演进而变得非常复杂,最终形成大量的(并且有时是令人迷惑的)类和交互,这种情况并不少见。

但许多情况下,我们并不想把这种复杂性暴露给客户端。而外观设计模式有助于隐藏系统的内部复杂性,并通过一个简化的接口向客户端暴露必要的部分。本质上,外观模式是在已有的系统上实现的一个抽象层。

这里以一个简单的操作系统示例来说明外观模式:

from enum import Enum
from abc import ABCMeta, abstractmethod

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


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.value

    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(f"trying to create the file '{name}'"
              f" for user '{user}' with permissions {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(f"trying to create the process '{name}' for user '{user}'")


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

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

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

    def create_process(self, user, name):
        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()
comments powered by Disqus