• 设计模式-工厂模式


    工厂模式是最常用的设计模式之一,属于创造型模式,提供了创建对象的最佳方式。

    工厂模式分为简单工厂模式,工厂模式,抽象工厂模式,什么意思,先上代码

    简单工厂模式

    class ShapeFactory(object):
        '''工厂类'''
    
        def getShape(self):
          return self.shape_name
    
    class Circle(ShapeFactory):
      def __init__(self):
        self.shape_name = "Circle"
      def draw(self):
        print('draw circle')
    
    class Rectangle(ShapeFactory):
      def __init__(self):
        self.shape_name = "Retangle"
      def draw(self):
        print('draw Rectangle')
    
    class Shape(object):
      '''接口类,负责决定创建哪个ShapeFactory的子类'''
      def create(self, shape):
        if shape == 'Circle':
          return Circle()
        elif shape == 'Rectangle':
          return Rectangle()
        else:
          return None
    
    
    fac = Shape()
    obj = fac.create('Circle')
    obj.draw()
    print obj.getShape()

    图形解释

    工厂模式

    class AbstractSchool(object):
        def enroll(self,name,course):
            pass
    
        def info(self):
            pass
    
    class AbstractCourse(object):
        def __init__(self,name,time_range,study_type,fee):
          pass
    
        def enroll_test(self):
            print("课程[%s]测试中..." % self.name)
    
        def print_course_outline(self):
            pass
    
    
    class LinuxOPSCourse(AbstractCourse):
        def print_course_outline(self):
            pass
    
        def enroll_test(self):
            print("不用测试,是个人就能学...")
    
    
    class PythonCourse(AbstractCourse):
        def print_course_outline(self):
            pass
    
        def enroll_test(self):
            print("-------python入学测试-------")
    
    class BJSchool(AbstractSchool):
        name = "老男孩北京校区"
        def create_course(self,course_type):
            if course_type == 'py_ops':
                course = PythonCourse("Python自动化开发",
                             7,'面授',11000)
            elif course_type == 'linux':
                course = LinuxOPSCourse("Linux运维课程",
                             5,'面授',12800)
            return course
    
        def enroll(self,name,course):
            course.enroll_test()
    
        def info(self):
            print("------[%s]-----"%self.name)
    
    class SHSchool(AbstractSchool):
        name = "老男孩上海分校"
        def create_course(self,course_type):
            if course_type == 'py_ops':
                course = PythonCourse("Python自动化开发",
                             8,'在线',6500)
            elif course_type == 'linux':
                course = LinuxOPSCourse("Linux运维课程",
                             6,'在线',8000)
            return course
    
        def enroll(self,name,course):
            pass
    
        def info(self):
            print("--------[%s]-----" % self.name )
    
    
    school1 = BJSchool()
    school2 = SHSchool()
    
    school1.info()
    c1=school1.create_course("py_ops")
    school1.enroll("张三",c1)
    
    school2.info()
    c2=school1.create_course("py_ops")
    school2.enroll("李四",c2)

    图形解释

    抽象工厂模式

    class AbstractFactory(object):
        computer_name = ''
        def createCpu(self):
            pass
        def createMainboard(self):
            pass
    
    class IntelFactory(AbstractFactory):
        computer_name = 'Intel I7-series computer '
        def createCpu(self):
            return IntelCpu('I7-6500')
        def createMainboard(self):
            return IntelMainBoard('Intel-6000')
    
    class AmdFactory(AbstractFactory):
        computer_name = 'Amd 4 computer '
        def createCpu(self):
            return AmdCpu('amd444')
        def createMainboard(self):
            return AmdMainBoard('AMD-4000')
    
    
    ############# cpu工厂
    class AbstractCpu(object):
        series_name = ''
        instructions = ''
        arch=''
    
    class IntelCpu(AbstractCpu):
        def __init__(self,series):
            self.series_name = series
    
    class AmdCpu(AbstractCpu):
        def __init__(self,series):
            self.series_name = series
    
    
    ############# 主板工厂
    class AbstractMainboard(object):
        series_name = ''
    
    class IntelMainBoard(AbstractMainboard):
        def __init__(self,series):
            self.series_name = series
    
    class AmdMainBoard(AbstractMainboard):
        def __init__(self,series):
            self.series_name = series
    
    
    ############# 客户端
    class ComputerEngineer(object):
    
        def makeComputer(self,computer_obj):
            self.prepareHardwares(computer_obj)
    
        def prepareHardwares(self,computer_obj):
            self.cpu = computer_obj.createCpu()
            self.mainboard = computer_obj.createMainboard()
    
            info = '''------- computer [%s] info:
                    cpu: %s
                    mainboard: %s
    
                 -------- End --------
            '''% (computer_obj.computer_name,self.cpu.series_name,self.mainboard.series_name)
            print(info)
    
    
    if __name__ == "__main__":
        engineer = ComputerEngineer()
    
        computer_factory = IntelFactory()
        engineer.makeComputer(computer_factory)
    
        computer_factory2 = AmdFactory()
        engineer.makeComputer(computer_factory2)

    图形解释

    是不是觉得越来越复杂,但是还是云里雾里?往下看。

    对比分析传统方法

    首先我们来思考一下,如果传统方法实现上面这张图(就近,方便看),是不是这样,写个函数,函数里一堆参数,函数里一堆if ,是的,完全可以实现,而且可能更简单,

    但是我们思考一下,如果有其他cpu呢?传统方法在一堆代码里,找if,然后加个if,而上图,只需改变cpu车间,再加个工厂,

    继续,如果cpu生产要求输出生产报告,传统方法又开始找了,在每个cpu出加代码,这里是2个cpu,那如果是几万个呢?你要找几万次,改几万次,还没累死吗?而这里只需改一处,就是cpu工厂父类里加上输出报告的方法,几万个cpu瞬间搞定。

    是不是觉得很方便?

    总结

    1. 在工厂模式中,对象的创建逻辑被封装,客户端只需要接口即可。

    2. 创建对象采用继承方式,公共属性被统一定义,子类决定产品特色。

    3. 代码可读性强,可维护性高

    网上还有各种说法,鄙人觉得没什么鸟用,只是炫技,记住上面3点即可。

    那为什么还分3种工厂模式呢?当然各自有优缺点了

    简单工厂模式

    优点:客户端不需要修改代码

    缺点:如果增加产品,不仅需要新建车间,还需要修改接口,当然如果你把接口写在工厂类里,就是要修改工厂类。产品工厂都得改,大动作

    一个工厂,多个产品,一个接口

    工厂模式

    优点:如果增加产品,只需修改产品类和相应工厂类

    缺点:增加产品时,需要修改客户端代码

    抽象工厂模式

    优点
    1.分离接口和实现
    客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
    2.使切换产品族变得容易
    因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。

    缺点
    不太容易扩展新的产品如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。

    以上的优缺点分析部分是有说服力的,也有一部分是为了迎合网上的说法,说的天花乱坠,云里雾里的,很有炫技嫌疑,

    鄙人觉得,设计模式只是一种设计思路,具体执行过程中,可以天马行空,自己设定,无招胜有招,创新,柔和才是真正的应用,

    记住一条即可:让所有人都方便,而且最好别让客户麻烦

    参考资料:

    http://www.cnblogs.com/yangxiaolan/p/5977465.html

  • 相关阅读:
    HDU 4864 Task(经典贪心)
    51Nod
    POJ 3122 Pie(二分+贪心)
    HDU 1053 Entropy(哈夫曼编码 贪心+优先队列)
    POJ 1328 Radar Installation(很新颖的贪心,区间贪心)
    11572
    HDU 1789 Doing Homework again(非常经典的贪心)
    合并果子(贪心+优先队列)
    CSU-ACM2018暑假集训6—BFS
    HDU 2102 A计划(两层地图加时间限制加传送门的bfs)
  • 原文地址:https://www.cnblogs.com/yanshw/p/10699765.html
Copyright © 2020-2023  润新知