设计模式快速的入门

‘每一个模式描述了一个在我们周围不断重复发生的问题’,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。

每一个设计模式系统地命名、解释和评价了面向对象系统中一个重复的和重复出现的设计。

设计模式四个基本要素:模式名称、问题、解决方案、效果。

设计模式六大原则:

1.开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

2.里氏替换原则:所有引用基类的地方必须能透明地使用其子类地对象。

3.依赖倒置原则:高层模块不应该依赖底层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节依赖抽象。换言之,要针对接口编程,而不是针对实现编程。

4.使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些他不需要的接口。

5.迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。

6.单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

前戏介绍:

# coding : utf-8
# create by ztypl on 2017/5/24

from abc import abstractmethod, ABCMeta


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


class Alipay(Payment):
    def  pay(self, money):
        print("支付宝支付%s元" % money)


class ApplePay(Payment):
    def pay(self, money):
        print("苹果支付%s元" % money)


class WechatPay(Payment):
    def pay(self, money):
        print("微信支付%s元" % money)


payment = Alipay()
payment.pay(100)
View Code

 设计模式分类:

      创建型模式:

          工厂方法模式

           抽象工厂模式

           创建者模式

            单利模式

             原型模式

     结构形模式

           适配器模式

           组合模式

            代理模式

            桥接模式

             装饰模式

              外观模式

               享元模式

普通工厂模式:

# coding : utf-8
# create by ztypl on 2017/5/24

from abc import abstractmethod, ABCMeta


class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        raise NotImplementedError


class Alipay(Payment):
    def __init__(self, enable_yuebao=False):
        self.enable_yuebao = enable_yuebao

    def pay(self, money):
        if self.enable_yuebao:
            print("余额宝支付%s元" % money)
        else:
            print("支付宝支付%s元" % money)


class ApplePay(Payment):
    def pay(self, money):
        print("苹果支付%s元" % money)


class PaymentFactory:  # 工厂类 封装了对象创建的细节
    def create_payment(self, method):
        if method == "alipay":
            return Alipay()
        elif method == "applepay":
            return ApplePay()
        elif method == "yuebao":
            return Alipay(True)
        else:
            raise NameError(method)

factory = PaymentFactory()
payment = factory.create_payment("yuebao")
payment.pay(100)
View Code

工厂方法模式:

# coding : utf-8
# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta


class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        raise NotImplementedError


class Alipay(Payment):
    def pay(self, money):
        print("支付宝支付%s元" % money)


class ApplePay(Payment):
    def pay(self, money):
        print("苹果支付%s元"%money)


class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):
        pass


class AlipayFactory(PaymentFactory):
    def create_payment(self):
        return Alipay()

class ApplePayFactory(PaymentFactory):
    def create_payment(self):
        return ApplePay()




# 用户输入
# 支付宝,120

af = AlipayFactory()
ali = af.create_payment()
ali.pay(120)
View Code

抽象工厂模式:

# coding : utf-8
# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta


# ------抽象产品------

class PhoneShell(metaclass=ABCMeta):
    @abstractmethod
    def show_shell(self):
        pass


class CPU(metaclass=ABCMeta):
    @abstractmethod
    def show_cpu(self):
        pass


class OS(metaclass=ABCMeta):
    @abstractmethod
    def show_os(self):
        pass


# ------抽象工厂------

class PhoneFactory(metaclass=ABCMeta):
    @abstractmethod
    def make_shell(self):
        pass

    @abstractmethod
    def make_cpu(self):
        pass

    @abstractmethod
    def make_os(self):
        pass


# ------具体产品------


class SmallShell(PhoneShell):
    def show_shell(self):
        print("普通手机小手机壳")


class BigShell(PhoneShell):
    def show_shell(self):
        print("普通手机大手机壳")


class AppleShell(PhoneShell):
    def show_shell(self):
        print("苹果手机壳")


class SnapDragonCPU(CPU):
    def show_cpu(self):
        print("骁龙CPU")


class MediaTekCPU(CPU):
    def show_cpu(self):
        print("联发科CPU")


class AppleCPU(CPU):
    def show_cpu(self):
        print("苹果CPU")


class Android(OS):
    def show_os(self):
        print("Android系统")


class IOS(OS):
    def show_os(self):
        print("iOS系统")


# ------具体工厂------


class MiFactory(PhoneFactory):
    def make_cpu(self):
        return SnapDragonCPU()

    def make_os(self):
        return Android()

    def make_shell(self):
        return BigShell()


class HuaweiFactory(PhoneFactory):
    def make_cpu(self):
        return MediaTekCPU()

    def make_os(self):
        return Android()

    def make_shell(self):
        return SmallShell()


class IPhoneFactory(PhoneFactory):
    def make_cpu(self):
        return AppleCPU()

    def make_os(self):
        return IOS()

    def make_shell(self):
        return AppleShell()


# ------客户端------


class Phone:
    def __init__(self, cpu, os, shell):
        self.cpu = cpu
        self.os = os
        self.shell = shell

    def show_info(self):
        print("手机信息:")
        self.cpu.show_cpu()
        self.os.show_os()
        self.shell.show_shell()



def make_phone(factory):
    cpu = factory.make_cpu()
    os = factory.make_os()
    shell = factory.make_shell()
    return Phone(cpu, os, shell)


p1 = make_phone(IPhoneFactory())
p1.show_info()
View Code

创建者模式:

# coding : utf-8
# create by ztypl on 2017/5/25

import random
from abc import abstractmethod, ABCMeta

#------产品------

class Player:
    def __init__(self, face=None, body=None, arm=None, leg=None):
        self.face = face
        self.arm = arm
        self.leg = leg
        self.body = body

    def __str__(self):
        return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg)


#------建造者------


class PlayerBuilder(metaclass=ABCMeta):
    @abstractmethod
    def build_face(self):
        pass
    @abstractmethod
    def build_arm(self):
        pass
    @abstractmethod
    def build_leg(self):
        pass
    @abstractmethod
    def build_body(self):
        pass
    @abstractmethod
    def get_player(self):
        pass


class BeautifulWomanBuilder(PlayerBuilder):
    def __init__(self):
        self.player = Player()
    def build_face(self):
        self.player.face = "漂亮脸蛋"
    def build_arm(self):
        self.player.arm="细胳膊"
    def build_body(self):
        self.player.body="细腰"
    def build_leg(self):
        self.player.leg="长腿"
    def get_player(self):
        return self.player

class RandomPlayerBuilder(PlayerBuilder):
    def __init__(self):
        self.player = Player()
    def build_face(self):
        self.player.face = random.choice(["瓜子脸","西瓜子脸"])
    def build_arm(self):
        self.player.arm=random.choice(["长胳膊","短胳膊"])
    def build_body(self):
        self.player.body=random.choice(["苗条",""])
    def build_leg(self):
        self.player.leg=random.choice(["长腿","短腿"])
    def get_player(self):
        return self.player

class PlayerDirector:
    def __init__(self, builder):
        self.builder = builder
    # 控制组装顺序
    def build_player(self):
        self.builder.build_body()
        self.builder.build_face()
        self.builder.build_arm()
        self.builder.build_leg()
        return self.builder.get_player()




pd = PlayerDirector(RandomPlayerBuilder())
p = pd.build_player()
print(p)
View Code

单利模式:

# coding : utf-8
# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta


class Singleton(object):
    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, name=None):
        if name is not None:
            self.name = name


a = MyClass("a")

print(a)
print(a.name)
#
b = MyClass("b")

print(b)
# print(b.name)
#
# print(a)
# print(a.name)
View Code

组合模式:

# coding : utf-8
# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta

class Graphic(metaclass=ABCMeta):
    @abstractmethod
    def draw(self):
        pass

    @abstractmethod
    def add(self, graphic):
        pass

    @abstractmethod
    def getchildren(self):
        pass


class Point(Graphic):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def draw(self):
        print(self)

    def add(self, graphic):
        raise TypeError

    def getchildren(self):
        raise TypeError

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


class Line(Graphic):
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    def draw(self):
        print(self)

    def add(self, graphic):
        raise TypeError

    def getchildren(self):
        raise TypeError

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


class Picture(Graphic):
    def __init__(self):
        self.children = []

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

    def getchildren(self):
        return self.children

    def draw(self):
        print("------复合图形------")
        for g in self.children:
            g.draw()
        print("------END------")


pic1 = Picture()
pic1.add(Point(2,3))
pic1.add(Line(Point(1,2), Point(4,5)))
pic1.add(Line(Point(0,1), Point(2,1)))

pic2 = Picture()
pic2.add(Point(-2,-1))
pic2.add(Line(Point(0,0), Point(1,1)))

pic = Picture()
pic.add(pic1)
pic.add(pic2)

pic.draw()
View Code

 适配器模式:

# coding : utf-8
# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        raise NotImplementedError


class Alipay(Payment):
    def pay(self, money):
        print("支付宝支付%s元"%money)


class ApplePay(Payment):
    def pay(self, money):
        print("苹果支付%s元"%money)

#------待适配类------

class WechatPay:
    def huaqian(self, a, b):
        print("微信支付%s元"%(a+b))

#------类适配器------

class RealWeChatPay(Payment, WechatPay):
    def pay(self, money):
        return self.huaqian(money, 0)


#------对象适配器------
class PayAdapter(Payment):
    def __init__(self, payment):
        self.payment = payment

    def pay(self, money):
        return self.payment.huaqian(money, 0)


#RealWeChatPay().pay(100)
PayAdapter(WechatPay()).pay(1000)
View Code

代理模式:

# coding : utf-8
# create by ztypl on 2017/5/26

from abc import ABCMeta, abstractmethod

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


class RealSubject(Subject):
    def __init__(self, filename):
        self.filename = filename
        print("读取%s文件内容"%filename)
        f = open(filename)
        self.content = f.read()
        f.close()

    def get_content(self):
        return self.content

    def set_content(self, content):
        f = open(self.filename, 'w')
        f.write(content)
        f.close()



class ProxyA(Subject):
    def __init__(self, filename):
        self.subj = RealSubject(filename)

    def get_content(self):
        return self.subj.get_content()


class ProxyB(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()


class ProxyC(Subject):
    def __init__(self, filename):
        self.subj = RealSubject(filename)

    def get_content(self):
        return self.get_content()

    def set_content(self):
        raise PermissionError

    # 写一个set_content

b = ProxyB("abc.txt")
#print(b.get_content())
View Code

责任链模式:

# coding : utf-8
# create by ztypl on 2017/5/27

from abc import ABCMeta, abstractmethod
#
# class Handler(metaclass=ABCMeta):
#     @abstractmethod
#     def handle_leave(self, day):
#         pass
#
#
# class GeneralManagerHandler(Handler):
#     def handle_leave(self, day):
#         if day < 10:
#             print("总经理批准%d天假"%day)
#         else:
#             print("呵呵")
#
#
# class DepartmentManagerHandler(Handler):
#     def __init__(self):
#         self.successor = GeneralManagerHandler()
#     def handle_leave(self, day):
#         if day < 7:
#             print("部门经理批准%d天假"%day)
#         else:
#             print("部门经理无权准假")
#             self.successor.handle_leave(day)
#
#
# class ProjectDirectorHandler(Handler):
#     def __init__(self):
#         self.successor = DepartmentManagerHandler()
#     def handle_leave(self, day):
#         if day < 3:
#             print("项目主管批准%d天假")
#         else:
#             print("项目主管无权准假")
#             self.successor.handle_leave(day)
#
#
# day = 4
# h = ProjectDirectorHandler()
# h.handle_leave(day)
#


#--高级例子--模仿js事件处理

class Handler(metaclass=ABCMeta):
    @abstractmethod
    def add_event(self, func):
        pass

    @abstractmethod
    def handle(self):
        pass


class BodyHandler(Handler):
    def __init__(self):
        self.func = None

    def add_event(self, func):
        self.func = func

    def handle(self):
        if self.func:
            return self.func()
        else:
            print("已到最后一级,无法处理")


class ElementHandler(Handler):
    def __init__(self, successor):
        self.func = None
        self.successor = successor

    def add_event(self, func):
        self.func = func

    def handle(self):
        if self.func:
            return self.func()
        else:
            return self.successor.handle()


# 客户端

# <body><div><a>

body = {'type': 'body', 'name': 'body', 'children': [], 'father': None}

div = {'type': 'div', 'name': 'div', 'children': [], 'father': body}

a = {'type': 'a', 'name': 'a', 'children': [], 'father': div}

body['children'].append(div)
div['children'].append(a)

body['event_handler'] = BodyHandler()
div['event_handler'] = ElementHandler(div['father']['event_handler'])
a['event_handler'] = ElementHandler(a['father']['event_handler'])


def attach_event(element, func):
    element['event_handler'].add_event(func)

#test

def func_div():
    print("这是给div的函数")

def func_a():
    print("这是给a的函数")

def func_body():
    print("这是给body的函数")

#attach_event(div, func_div)
#attach_event(a, func_a)
#attach_event(body, func_body)





a['event_handler'].handle()
View Code

迭代器模式:

# coding : utf-8
# create by ztypl on 2017/5/27


class LinkList:
    """链表 头结点保存链表的长度"""
    class Node:
        def __init__(self, item=None):
            self.item = item
            self.next = None

    class LinkListIterator:
        def __init__(self, node):
            self.node = node
        def __next__(self):
            if self.node:
                cur_node = self.node
                self.node = cur_node.next
                return cur_node.item
            else:
                raise StopIteration
        def __iter__(self):
            return self

    def __init__(self, iterable=None):
        self.head = LinkList.Node(0)
        self.tail = self.head
        self.extend(iterable)

    def append(self, obj):
        s = LinkList.Node(obj)
        self.tail.next = s
        self.tail = s

    def extend(self, iterable):
        for obj in iterable:
            self.append(obj)
        self.head.item += len(iterable)

    def __iter__(self):
        return self.LinkListIterator(self.head.next)

    def __len__(self):
        return self.head.item

    def __str__(self):
        return "<<"+", ".join(map(str, self))+">>"



li = [i for i in range(100)]
print(li)
lk = LinkList(li)
# for i in lk:
#     print(i)

print(lk)
# print(len(lk))
View Code

观察者模式

# coding : utf-8
# create by ztypl on 2017/5/27

from abc import ABCMeta, abstractmethod


class Observer(metaclass=ABCMeta):
    @abstractmethod
    def update(self, notice):
        pass


class Notice:
    def __init__(self):
        self.observers = [] # 记录该主体的观察者(订阅者)

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

    def detach(self, obs):
        obs.company_info = None
        self.observers.remove(obs)

    def notify(self):
        for obj in self.observers:
            obj.update(self)


class ManagerNotice(Notice):
    def __init__(self, company_info=None):
        super().__init__()
        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 Manager(Observer):
    def __init__(self):
        self.company_info = None

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


notice = ManagerNotice()

alex = Manager()
wusir = Manager()

# print(alex.company_info)
# print(wusir.company_info)

notice.attach(alex)
notice.attach(wusir)
#
notice.company_info="公司运行良好"
#
print(alex.company_info)
print(wusir.company_info)
#
notice.detach(wusir)
#
notice.company_info="公司要破产了"

print(alex.company_info)
print(wusir.company_info)
View Code

策略模式:

# coding : utf-8
# create by ztypl on 2017/5/27

from abc import ABCMeta, abstractmethod
import random

class Sort(metaclass=ABCMeta):
    @abstractmethod
    def sort(self, data):
        pass


class QuickSort(Sort):
    def quick_sort(self, data, left, right):
        if left < right:
            mid = self.partition(data, left, right)
            self.quick_sort(data, left, mid - 1)
            self.quick_sort(data, mid + 1, right)

    def partition(self, data, left, right):
        tmp = data[left]
        while left < right:
            while left < right and data[right] >= tmp:
                right -= 1
            data[left] = data[right]
            while left < right and data[left] <= tmp:
                left += 1
            data[right] = data[left]
        data[left] = tmp
        return left

    def sort(self, data):
        print("快速排序")
        return self.quick_sort(data, 0, len(data) - 1)


class MergeSort(Sort):
    def merge(self, data, low, mid, high):
        i = low
        j = mid + 1
        ltmp = []
        while i <= mid and j <= high:
            if data[i] <= data[j]:
                ltmp.append(data[i])
                i += 1
            else:
                ltmp.append(data[j])
                j += 1

        while i <= mid:
            ltmp.append(data[i])
            i += 1

        while j <= high:
            ltmp.append(data[j])
            j += 1

        data[low:high + 1] = ltmp


    def merge_sort(self, data, low, high):
        if low < high:
            mid = (low + high) // 2
            self.merge_sort(data, low, mid)
            self.merge_sort(data, mid + 1, high)
            self.merge(data, low, mid, high)

    def sort(self, data):
        print("归并排序")
        return self.merge_sort(data, 0, len(data) - 1)


class Context:
    def __init__(self, data, strategy=None):
        self.data = data
        self.strategy = strategy

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

    def do_strategy(self):
        if self.strategy:
            self.strategy.sort(self.data)
        else:
            raise TypeError


li = list(range(100000))
random.shuffle(li)

context = Context(li, MergeSort())
context.do_strategy()
#print(context.data)

random.shuffle(context.data)

context.set_strategy(QuickSort())
context.do_strategy()
View Code

模板方法模式

# coding : utf-8
# create by ztypl on 2017/5/27

from abc import ABCMeta, abstractmethod


class IOHandler(metaclass=ABCMeta):
    @abstractmethod
    def open(self, name):
        pass
    @abstractmethod
    def deal(self, change):
        pass
    @abstractmethod
    def close(self):
        pass
    def process(self, name, change):
        self.open(name)
        self.deal(change)
        self.close()


class FileHandler(IOHandler):
View Code
原文地址:https://www.cnblogs.com/1a2a/p/8407034.html