软件工程设计模式-Python实现

创建型

工厂方法模式

  • 工厂方法:一个抽象产品类派生出多个具体产品类;一个抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。
  • 即定义一个创建对象的接口(抽象工厂类),让子类具体工厂决定实例化那个产品类(具体产品类)。“一对一”关系

软件工程设计模式-Python实现_第1张图片

class Anamals:
    def jiao(self):
        pass

class Cat(Anamals):
    def jiao(self):
        print('喵喵')

class Dog(Anamals):
    def jiao(self):
        print('汪汪')


class Store:
    def eat(self):
        pass

class Dogstore(Store):
    def eat(self):
        return Dog()

class Catstore(Store):
    def eat(self):
        return Cat()


store = Dogstore()
store.eat().jiao()

抽象工厂模式

  • 抽象工厂模式:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。
  • 即 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他的具体类。“一对多”关系
    软件工程设计模式-Python实现_第2张图片
class Anamals:
    def jiao(self):
        pass

class Cat(Anamals):
    def jiao(self):
        print('喵喵')

class Dog(Anamals):
    def jiao(self):
        print('汪汪')
--------------------------------------------------------------------
class Toy:
    def run(self):
        pass

class DogToy(Toy):
    def run(self):
        print('Dog跑了')

class CatToy(Toy):
    def run(self):
        print('Cat跑了')
--------------------------------------------------------------------
class Store:
    def eat(self):
        pass

    def play(self):
        pass

class Dogstore(Store):
    def eat(self):
        return Dog()

    def play(self):
        return DogToy()

class Catstore(Store):
    def eat(self):
        return Cat()
    def play(self):
        return CatToy()


store = Dogstore()

store.eat().jiao()
store.play().run()

建造者模式

  • 注重于一步一步的构造对象,重点在于控制顺序
  • 建造者和产品之间是多对一
from abc import ABCMeta, abstractmethod
class Play():			# 具体产品
	def __init__(self,face,body,leg):
		self.face = face
		self.body = body
		self.leg = leg
	def __str__(self):
		return (self.face + self.body + self.leg)
--------------------------------------------------------------------
class Build(metaclass = ABCMeta):  # 抽象建造类
	@abstractmethod
    def build_face(self):
        pass

    @abstractmethod
    def build_body(self):
        pass

    @abstractmethod
    def build_legs(self):
        pass  

class GirlBuild(Build):   # 具体建造者
	 def __init__(self):
        self.player = Player()

    def build_face(self):
        self.player.face = '漂亮的脸蛋'

    def build_body(self):
        self.player.body = '苗条的身材'

    def build_legs(self):
        self.player.legs = '大长腿'


class BoyBuild(Build):   # 具体建造者
	 def __init__(self):
        self.player = Player()

    def build_face(self):
        self.player.face = '漂亮的脸蛋'

    def build_body(self):
        self.player.body = '苗条的身材'

    def build_legs(self):
        self.player.legs = '大长腿'

----------------------------------------------------
#  通过指挥者来构造具体产品
class PlayDirectory():
	def build_whole(self,build):
		build.build_face()
		builder.build_body()
        builder.build_legs()
        return builder.player
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dire = PLayDirectory()
girl = GirlBuild()
boy = BoyBuild()

# dire.build_whole(girl)
dire.build_whole(boy)

单例模式

  • 不会重复的创建对象,只产生一个实例
class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

class MyClass(Singleton):
    def __init__(self, a):
        self.a = a

结构性

适配器模式

  • 让原来两个因接口不同而不能一起工作的类一些工作,实现适配器的方式有两种,一种是类继承,一种是组合模式一个类作为另一个类的属性
from abc import ABCMeta, abstractmethod

class Payment(object, metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass

class Alipay(Payment):
    def pay(self, money):
        print(f'苹果pay {money}')

# 另一个系统的支付类
class BankPay():
    def cost(self, money):
        print(f'银联pay {money}')

# 类适配器
class PaymentAdapter(Payment, BankPay):
    """
    把不兼容cost转换成pay
    """
    def pay(self, money):
        self.cost(money)

桥模式

将一个事物的两个维度分离,使器可以都可以独立的变化

  • 假设现在有红色正方形,黄色圆形,那么需要新建一个类才能得到红色圆形,想要绿色的也需要新建,所以可以把颜色和形状两个维度分离,使其可以独立的变化扩展。
from abc import ABCMeta,abstractmethod
class Shape(metaclass=ABCMeta):
   def __init__(self,color):
   	self.color = color
   @abstractmethod
   def draw(self):
   	pass

class Color(metaclass=ABCMeta):
   @abstractmethod
   def paint(self):
   	pass


class Rectangle(Shape):
   def draw(self):
   	self.color.paint(self)
   def __str__(self):
   	return '方形'

class Red(Color):
   def paint(self,shape):
   	print (f'红色的{shape}')

red = Red()
q = Rectangle(red)

组合模式

  • 类似word中的图形,每个图形都有一些属性,多个图形结合在一起也有这些属性
  • 客户端可以统一的使用组合对象和单个对象
  • 多用于表示结构式递归的,图是由线构成,线是由点构成。
from abc import ABCMeta, abstractmethod

# 抽象组件
class Graphic(metaclass=ABCMeta):
    @abstractmethod
    def draw(self):
        pass

# 叶子组件
class Point(Graphic):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return '点(%s,%s)' % (self.x, self.y)

    def draw(self):
        print(self)

# 叶子组件
class Line(Graphic):
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    def __str__(self):
        return '线段[(%s,%s)]' % (self.p1, self.p2)

    def draw(self):
        print(self)

# 复合组件
class Picture(Graphic):
    def __init__(self, iterable):
        self.children = []
        for g in iterable:
            self.add(g)

    def add(self, graphic):
        self.children.append(graphic)

    def draw(self):
        for g in self.children:
            g.draw()

外观模式

  • 外观模式定义了一个高层的接口,使某项功能的使用更加简单,例如基本的有q,w,e,r,可以封装一个外观类,提供一些接口,其中接口一使用qw得到的功能,接口二使用we得到的功能,这里的说和学就是高层接口,客户端不需要去使用qw来使用,只调用方法就可以
# 子系统类
class CPU:
    def run(self):
        print('CPU start to run...')

    def stop(self):
        print('CPU stop to run...')

# 子系统类
class Disk:
    def run(self):
        print('Disk start to run...')

    def stop(self):
        print('Disk stop to run...')

# 子系统类
class Memory:
    def run(self):
        print('Memory start to run...')

    def stop(self):
        print('Memory stop to run...')

# 外观
class Computer():
    def __init__(self):
        self.CPU = CPU()
        self.Disc = Disk()
        self.Member = Memory()

    def run(self):
        self.CPU.run()
        self.Disc.run()
        self.Member.run()

    def stop(self):
        self.CPU.stop()
        self.Disc.stop()
        self.Member.stop()

# 客户端,高层代码
c = Computer()
c.run()
c.stop()

代理模式

  • 代理模式可以对被代理对象起到保护的作用

一般模式

from abc import ABCMeta, abstractmethod

class Subject(metaclass=ABCMeta):
    @abstractmethod
    def get_content(self):
        pass

    @abstractmethod
    def set_content(self, content):
        pass

class RealSubject(Subject):
    def __init__(self, filename):
        self.filename = filename
        print('读取文件内容!')
        with open(self.filename, 'r', encoding='utf-8') as f:
            self.content = f.read()

    def get_content(self):
        return self.content

    def set_content(self, content):
        with open(self.filename, 'w', encoding='utf-8') as f:
            f.write(content)

subj = RealSubject('test.txt')
  • 此时,仅实例化对象的时候就会读取文件占用内存,可以使用虚代理,仅在需要的时候实例化RealSubject对象尽在需要的时候读取文件

代理模式

from abc import ABCMeta, abstractmethod

class Subject(metaclass=ABCMeta):
    @abstractmethod
    def get_content(self):
        pass

    @abstractmethod
    def set_content(self, content):
        pass

class RealSubject(Subject):
    def __init__(self, filename):
        self.filename = filename
        print('读取文件内容!')
        with open(self.filename, 'r', encoding='utf-8') as f:
            self.content = f.read()

    def get_content(self):
        return self.content

    def set_content(self, content):
        with open(self.filename, 'w', encoding='utf-8') as f:
            f.write(content)

class VirtualProxy(Subject):
    def __init__(self, filename):
        self.filename = filename
        self.subj = None

    def get_content(self):
        if not self.subj:
            self.subj = RealSubject(self.filename)
        return self.subj.get_content()

    def set_content(self, content):
        if not self.subj:
            self.subj = RealSubject(self.filename)

        return self.subj.set_content(content)

subj = VirtualProxy('test.txt')
print(subj.get_content())

保护代理:再get_content()中进行判断,选择返回内容或者提示信息。

行为型

责任链模式

  • 责任链模式就是将多个类通过链表连接起来,自己不能处理,就去找上级的类处理
from abc import ABCMeta, abstractmethod

# 抽象的处理者
class Handler(metaclass=ABCMeta):
    @abstractmethod
    def handle_leave(self, day):
        pass

# 具体的处理者
class GeneralManager(Handler):
    def handle_leave(self, day):
        if day <= 30:
            print('总经理准假%d' % day)
        else:
            print('你还是辞职把!')

# 具体的处理者
class DepartmentManager(Handler):
    def __init__(self):
        self.next = GeneralManager()

    def handle_leave(self, day):
        if day <= 7:
            print('项目主管准假%d' % day)
        else:
            print('部门经理职权不足,问我上级')
            self.next.handle_leave(day)

# 具体的处理者
class ProjectDirector(Handler):
    def __init__(self):
        self.next = DepartmentManager()

    def handle_leave(self, day):
        if day <= 3:
            print('项目主管准假%d' % day)
        else:
            print('项目主管职权,我这是小官')
            self.next.handle_leave(day)

day = 20
p = ProjectDirector()
p.handle_leave(day)

观察者模式

  • 又称为发布订阅模式,在类的属性发生变化的时候,通知订阅人更新信息。
  • 利用了property.setter
from abc import ABCMeta, abstractmethod

# 抽象的订阅者
class Observer(metaclass=ABCMeta):
    @abstractmethod
    def update(self, notice):
        """
        :param notice: Notice类的对象
        :return:
        """
        pass

# 抽象的发布者:可以是接口,子类不需要实现,所以不需要定义抽象方法!
class Notice:
    def __init__(self):
        self.observers = []

    def attach(self, obs):
        self.observers.append(obs)

    def detach(self, obs):
        self.observers.remove(obs)

    def notify(self):
        """
        推送
        :return:
        """
        for obs in self.observers:
            obs.update(self)

# 具体的发布者
class StaffNotice(Notice):
    def __init__(self, company_info=None):
        super().__init__()  # 调用父类对象声明observers属性
        self.__company_info = company_info

    @property
    def company_info(self):
        return self.__company_info

    @company_info.setter
    def company_info(self, info):
        self.__company_info = info
        self.notify()

# 具体的订阅者
class Staff(Observer):
    def __init__(self):
        self.company_info = None

    def update(self, notice):
        self.company_info = notice.company_info

staff_notice = StaffNotice()
staff1 = Staff()
staff2 = Staff()
staff_notice.attach(staff1)
staff_notice.attach(staff2)
# print(staff1.company_info) None
# print(staff2.company_info) None
staff_notice.company_info = '放假'
print(staff1.company_info)
print(staff2.company_info)
staff_notice.detach(staff2)
staff_notice.company_info = '开会'
print(staff1.company_info)
print(staff2.company_info)
'''
>>>放假
>>>放假
>>>开会
>>>放假
'''

策略模式

  • 将两种策略作为Context类属性封装起来,使用户可以选择策略来处理数据
from abc import abstractmethod, ABCMeta
from datetime import datetime

# 抽象策略
class Strategy(metaclass=ABCMeta):
    @abstractmethod
    def execute(self, data):
        pass

# 具体策略
class FastStrategy(Strategy):
    def execute(self, data):
        print("使用较快的策略处理%s" % data)

# 具体策略
class SlowStrategy(Strategy):
    def execute(self, data):
        print("使用较慢的策略处理%s" % data)

# 上下文
class Context:
    def __init__(self, strategy, data):
        self.data = data
        self.strategy = strategy
        # 可以定义用户不知道的东西
        self.date = datetime.now()

    def set_strategy(self, strategy):
        self.strategy = strategy

    def do_strategy(self):
        self.strategy.execute(self.data)

data = "Hello!"
# 使用较快的策略处理
fast_strategy = FastStrategy()
context = Context(fast_strategy, data)
context.do_strategy()
# 使用较慢的策略处理
slow_strategy = SlowStrategy()
context = Context(slow_strategy, data)
context.do_strategy()

模板方法模式

  • 定义类的主要方法,而细节由类实现,所以相同的骨架会出现不同的结果
from abc import ABCMeta, abstractmethod
import time
# 抽象类
class Window(metaclass=ABCMeta):
    @abstractmethod
    def start(self):  # 原子操作/钩子操作
        pass

    @abstractmethod
    def repaint(self):  # 原子操作/钩子操作
        pass

    @abstractmethod
    def stop(self):  # 原子操作/钩子操作
        pass

    def run(self):
        """
        模板方法(具体方法)定义大逻辑,具体细节由子类完成
        :return:
        """
        self.start()
        while True:
            try:
                self.repaint()
                sleep(1)
            except KeyboardInterrupt:
                break
        self.stop()

# 具体类
class MyWindow(Window):
    def __init__(self, msg):
        self.msg = msg

    def start(self):
        print('窗口开始运行!')

    def stop(self):
        print('窗口停止运行!')

    def repaint(self):
        print(self.msg)

你可能感兴趣的:(计算机网络,软件工程)