万物之中, 希望至美.

设计模式之构造模式

2018.10.14

当出现以下几种情况时,可以考虑使用构造模式:

  1. 当想要创建一个复杂对象(对象由多个部分构成,且对象的创建要经过多个不同的步骤,这些步骤也许还遵从特定的顺序)
  2. 要求一个对象能有不同的表现,并希望将对象的构造与表现解耦
  3. 想要在某个时间点创建对象,但在稍后的时间点再访问

可以这么理解,你要买电脑,工厂模式直接返回一个你需要型号的电脑,但是构造模式允许你自定义电脑各种配置类型,组装完成后给你。这个过程你可以传入builder从而自定义创建的方式。

方式一

class Computer:
    def __init__(self, serial_number):
        self.serial_number = serial_number
        self.memory = None
        self.hdd = None
        self.gpu = None

    def __str__(self):
        info = ('Memory: {}GB'.format(self.memory),
                'Hard Disk: {}GB'.format(self.hdd),
                'Graphics Card: {}'.format(self.gpu))
        return '\n'.join(info)


class ComputerBuilder:
    def __init__(self):
        self.computer = Computer('AG23385193')

    def configure_memory(self, memory):
        self.computer.memory = memory

    def configure_hdd(self, amount):
        self.computer.hdd = amount

    def configure_gpu(self, gpu_model):
        self.computer.gpu = gpu_model


class HardwareEngineer:
    def __init__(self):
        self.builder = None

    def construct_computer(self, memory, hdd, gpu):
        self.builder = ComputerBuilder()
        [step for step in (self.builder.configure_memory(memory),
                           self.builder.configure_hdd(hdd),
                           self.builder.configure_gpu(gpu))]

    @property
    def computer(self):
        return self.builder.computer


def main():
    # 使用buidler,可以创建多个builder类实现不同的组装方式
    engineer = HardwareEngineer()
    engineer.construct_computer(hdd=500, memory=8, gpu='GeForce GTX 650 Ti')
    computer = engineer.computer
    print(computer)


if __name__ == '__main__':
    main()

方式二

这种方式以前在 Android 开发使用 Retrofit 库时使用过,这是一种链式调用。

class Computer:
    def __init__(self, builder):
        self.serial_number = builder.serial_number
        self.memory = builder.memory
        self.hdd = builder.hdd
        self.gpu = builder.gpu

    def __str__(self):
        info = ('Memory: {}GB'.format(self.memory),
                'Hard Disk: {}GB'.format(self.hdd),
                'Graphics Card: {}'.format(self.gpu))
        return '\n'.join(info)

    class ComputerBuilder:
        def __init__(self):
            self.serial_number = None
            self.memory = None
            self.hdd = None
            self.gpu = None

        def configure_serial_number(self, serial_number):
            self.serial_number = serial_number
            return self

        def configure_memory(self, memory):
            self.memory = memory
            return self

        def configure_hdd(self, amount):
            self.hdd = amount
            return self

        def configure_gpu(self, gpu_model):
            self.gpu = gpu_model
            return self

        def build(self):
            return Computer(self)


def main():
    computer = (Computer.ComputerBuilder()
                .configure_serial_number('AG23385193')
                .configure_memory(8)
                .configure_hdd(500)
                .configure_gpu('GeForce GTX 650 Ti')
                .build())
    print(computer)


if __name__ == '__main__':
    main()
comments powered by Disqus