[设计模式] Python设计模式

一、设计模式介绍

1.设计模式分类

23种设计模式,分类三类:

创建型、结构性、行为型。

2.设计模式的六大原则

1)开闭原则(Open Close Principle)

开闭原则是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。

2)里氏代换原则(Liskov Substitution Principle,LSP)

里氏代换原则是面向对象设计的基本原则之一。任何基类可以出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

理解:里氏代换即某个基类的子类,放到基类所处的位置,不会影响软件的运行。简单的理解为一个软件实体如果使用的是一个父类,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,软件里面,把父类都替换成它的子类,程序的行为没有变化。所以我们认为,基类中的所有方法应该是所有子类所共有的方法,而不应该出现需要子类重写的方法。这样才能使用子类替代基类。在设计的时候,尽量从抽象类继承,而不是从具体类。

参考博客:https://blog.csdn.net/king123456man/article/details/81626110

3)依赖倒转原则(Dependence Inversion Principle,DIP)

主要包含以下三层含义:

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象
  • 抽象不应该依赖细节
  • 细节应该依赖抽象

参考博客:https://blog.csdn.net/king123456man/article/details/81626127

4)接口隔离原则(Interface Segregation Principle,ISP)

其实通俗来理解就是,不要在一个接口里面放很多的方法,这样会显得这个类很臃肿不堪。接口应该尽量细化,一个接口对应一个功能模块,同时接口里面的方法应该尽可能的少,使接口更加轻便灵活。

参考博客:https://blog.csdn.net/king123456man/article/details/81626059

5)迪米特法则(最少知道原则)(Demeter Principle)

一个实体应该尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

6)合成复用原则(Composite Reuse Principle)

原则是尽量使用合成/聚合的方式,而不是使用继承。

参考博客:https://blog.csdn.net/u012361379/article/details/88605867

二、创建型设计模式

对象的创建会消耗系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,分别是:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)
  • 创建者模式(Builder)
  • 原型模式(Prototype)
  • 单例模式(Singleton)

严格来说,简单工厂模式不是23个设计模式之一。

1.简单工厂模式

最简单的设计模式。

######### 简单工厂设计模式 ##########

# 形状抽象类
class Shape(object):
    def draw(self):
        raise NotImplementedError


# 圆形类
class Circle(Shape):
    def draw(self):
        print('画圆形')


# 四边形类
class Rectangle(Shape):
    def draw(self):
        print('画四边形')


# 简单工厂类
class ShapeFactory(object):
    def create(self, shape):
        if shape == 'Circle':
            return Circle()
        elif shape == 'Rectangle':
            return Rectangle()
        else:
            return None


if __name__ == '__main__':
    # 创建一个简单工厂实例
    fac = ShapeFactory()
    # 使用工厂实例创建Circle对象
    obj = fac.create('Circle')
    # 调用对象中的draw方法
    obj.draw()

用一个简单的工厂类,来统一的提供给用户调用,根据用户提供的信息返回创建的实例。

2.工厂方法模式

在简单工厂模式中,我们只有一个工厂类,其中通过if else来判断需要创建什么对象,然后返回。

但我们想添加一个形状时,除了要实现相应的形状子类以外,还要修改这个唯一的工厂类。在if else判断语句中加一个分支。

此时,我们就可以将工厂类也抽象出一个基类,并为每个形状都创建一个工厂子类。

UML图如下所示:

######### 工厂方法设计模式 ##########

# 形状基类,所有形状子类继承于该类
class Shape(object):
    '''形状工厂类'''

    def getShape(self):
        return self.shape_name

    def draw(self):
        raise NotImplementedError


# 圆形类
class Circle(Shape):

    def __init__(self):
        self.shape_name = "Circle"

    def draw(self):
        print('draw circle')


# 四边形类
class Rectangle(Shape):
    def __init__(self):
        self.shape_name = "Retangle"

    def draw(self):
        print('draw Rectangle')


# 形状工厂的基类
class ShapeFactory(object):
    '''接口基类'''

    def create(self):
        '''把要创建的工厂对象装配进来'''
        raise NotImplementedError


# 圆形工厂类
class CircleFactory(ShapeFactory):
    def create(self):
        return Circle()


# 四边形工厂类
class RectangleFactory(ShapeFactory):
    def create(self):
        return Rectangle()


# 创建一个圆形工厂实例
cf = CircleFactory()
# 使用圆形工厂产生圆形对象
obj = cf.create()
# 调用圆形对象的shape_name
obj.getShape()
# 调用圆形对象的draw方法
obj.draw()

# 同理
rf = RectangleFactory()
obj2 = rf.create()
obj2.getShape()
obj2.draw()

3.抽象工厂模式

以装电脑为例,产品族代表着各种配置,而产品等级代表着不同的配件。

当装机工程师要配置一台电脑,需要与配置工厂(AbstractFactory)与各类产品的基类关联。

 

代码如下:

######### 抽象工厂设计模式 ##########

# 抽象工厂类(配置类)
class AbstractFactory(object):
    computer_name = ''

    def createCpu(self):
        pass

    def createMainboard(self):
        pass


# Intel配置类(CPU和主板都使用Intel的配置)
class IntelFactory(AbstractFactory):
    computer_name = 'Intel I7-series computer '

    def createCpu(self):
        return IntelCpu('I7-6500')

    def createMainboard(self):
        return IntelMainBoard('Intel-6000')


# Amd配置类(CPU和主板都使用Amd的配置)
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 = ''


# Intel的CPU
class IntelCpu(AbstractCpu):
    def __init__(self, series):
        self.series_name = series


# Amd的CPU
class AmdCpu(AbstractCpu):
    def __init__(self, series):
        self.series_name = series


# 主板基类
class AbstractMainboard(object):
    series_name = ''


# Intel的主板
class IntelMainBoard(AbstractMainboard):
    def __init__(self, series):
        self.series_name = series


# Amd的主板
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):
        # 创建配置清单中的CPU
        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()

    # Intel配置对象
    computer_factory = IntelFactory()
    # 按Intel配置配一台电脑
    engineer.makeComputer(computer_factory)

    # AMD配置对象
    computer_factory2 = AmdFactory()
    # 按AMD配置配一台电脑
    engineer.makeComputer(computer_factory2)

4.创建者模式

####

猜你喜欢

转载自www.cnblogs.com/leokale-zz/p/12336503.html