美文网首页
python--建造者模式

python--建造者模式

作者: 极光火狐狸 | 来源:发表于2018-09-12 20:07 被阅读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)
    

    相关文章

      网友评论

          本文标题:python--建造者模式

          本文链接:https://www.haomeiwen.com/subject/expbgftx.html