python--建造者模式

2018-09-12  本文已影响14人  极光火狐狸

源码: builder.py

# -.- coding:utf-8 -.-

"""
Builder模式, 解耦复杂条件组合的场景.
例如Subprocess运行外部程序文件, 要满足几种条件,
程序文件名、程序完整路径、程序工作目录、程序参数等等.
这种情况下, 如果要组合这些条件, 需要挨个判断, 所有逻辑都揉在一起.
使用builder模式, 可以不用写判断条件.
备注; 虽然不用写判断条件, 但要提供默认参数.
      对于python而言, 要不要Builder模式其实并不重要!
      因为python的函数可以再参数上提供默认值!
"""


# Director
class Subprocess(object):

    @classmethod
    def get_subdir(cls, dir):
        return (LsCommand()
                .add_argument("-l")
                .add_argument(dir)
                .spawn())


class LS(object):

    def __init__(self):
        self.command = "/bin/ls"
        self.args = []
        self.result = None
        self.args.append(self.command)


# Builder
class LsCommand(object):

    def __init__(self):
        self.ls = LS()

    def add_argument(self, argument):
        self.ls.args.append(argument)
        return self

    def remove_argument(self, argument):
        if argument in self.ls.args:
            index = self.ls.args.index(argument)
            self.ls.args.pop(index)
        return self

    def spawn(self):
        import subprocess
        stdout, stderr = (subprocess
                          .Popen(args=self.ls.args, stdout=subprocess.PIPE)
                          .communicate())
        self.ls.result = stdout.decode("utf-8")
        return self.ls


# Client
def main():
    ls = Subprocess.get_subdir("/")
    assert "lost+found" in ls.result
    assert "/" in ls.args
    assert "/bin/ls" in ls.args
    assert "-l" in ls.args


if __name__ == '__main__':
    main()

 
 

源码: builder2.py

# -.- coding:utf-8 -.-

"""
Builder模式, 解耦复杂条件组合的场景.
"""

from __future__ import print_function


class Car(object):
    def __init__(self, wheels=4, seats=4, color="Black"):
        self.wheels = wheels
        self.seats = seats
        self.color = color

    def __str__(self):
        msg = "This is a {0} car with {1} wheels and {2} seats."
        return msg.format(self.color, self.wheels, self.seats)


class Builder:

    def __init__(self):
        self.car = Car()

    def set_wheels(self, value):
        raise NotImplementedError

    def set_seats(self, value):
        raise NotImplementedError

    def set_color(self, value):
        raise NotImplementedError

    def get_result(self):
        raise NotImplementedError


class CarBuilder(Builder):

    def set_wheels(self, value):
        self.car.wheels = value
        return self

    def set_seats(self, value):
        self.car.seats = value
        return self

    def set_color(self, value):
        self.car.color = value
        return self

    def get_result(self):
        return self.car


# Director
class CarBuilderDirector(object):
    @staticmethod
    def construct():
        return (
            CarBuilder()
            .set_wheels(8)
            .set_seats(4)
            .set_color("Red")
            .get_result()
        )


# Client
def main():
    car = CarBuilderDirector.construct()
    print(car)


if __name__ == '__main__':
    main()

 
 

测试: tests/builder.py

# -.- coding:utf-8 -.-
import sys
import unittest
from design_patterns.creational import builder2
from design_patterns.creational import builder


class Builder(unittest.TestCase):

    def test_car_builder(self):
        car = builder2.CarBuilderDirector().construct()
        self.assertEquals([car.color, car.seats, car.wheels],
                          ["Red", 4, 8])

    @unittest.skipIf(sys.platform == "win32", u"windows下无法运行linux命令")
    def test_command_builder(self):
        ls = builder.Subprocess.get_subdir("/")
        self.assertTrue("lost+found" in ls.result)
        self.assertTrue("/" in ls.args)
        self.assertTrue("/bin/ls" in ls.args)
        self.assertTrue("-l" in ls.args)
上一篇下一篇

猜你喜欢

热点阅读