zoukankan      html  css  js  c++  java
  • 设计模式快速的入门

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

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

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

    设计模式六大原则:

    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
  • 相关阅读:
    程序员职业规划
    SSH框架优缺点
    Servlet的生命周期,并说出Servlet和CGI的区别,Servlet与JSP的区别
    什么是J2EE,包括哪些规范!
    JS中定义类的方法
    audio.js – 随时随地,播放 HTML5 的声音
    jquery面试题里 缓存问题如何解决?
    产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复
    JAVA排序算法
    java面试题中常见的关于String类问题总结
  • 原文地址:https://www.cnblogs.com/1a2a/p/8407034.html
Copyright © 2011-2022 走看看