码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式

时间:2019-01-12 23:00:17      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:director   全局   情况下   好处   大众汽车   利用   display   不同的   bsp   

一、设计模式和面向对象介绍

技术分享图片

面向对象:

三大特性:封装(私有,公有)、继承、多态

接口:

技术分享图片

from abc import ABCMeta,abstractmethod
# 接口
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        pass

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

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

p = WechatPay()
p2 = Alipay()
p.pay(10)
p2.pay(10)

----------------------------------------------------------

接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

然后让子类去实现接口中的函数。

这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

归一化的好处在于:

归一化让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。
归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合
就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕
(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。
再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,
这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样

在python中实现抽象类

#一切皆文件
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type=file
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        子类必须定义读功能
        pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        子类必须定义写功能
        pass

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print(文本数据的读取方法)

    def write(self):
        print(文本数据的读取方法)

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计

二、面向对象设计SOLID原则

技术分享图片

----

技术分享图片

from abc import ABCMeta,abstractmethod
class LandAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):
        pass
class WaterAnimal(metaclass=ABCMeta):
    @abstractmethod
    def swim(self):
        pass
class SkyAnimal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):
        pass

class Tiger(LandAnimal):
    def walk(self):
        print(‘‘)
# 青蛙
class Frog(LandAnimal,WaterAnimal):
    pass

设计模式分类

技术分享图片

 

 简单工厂模式:

技术分享图片

 

优点:
隐藏了对象创建的实现细节
客户端不需要修改代码
缺点: 违反了单一职责原则,将创建逻辑几种到一个工厂类里 当添加新产品时,需要修改工厂类代码,违反了开闭原则
from abc import ABCMeta, abstractmethod

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

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

    def pay(self, money):
        if self.use_huaei:
            print("花呗支付%d元." % money)
        else:
            print("支付宝余额支付%d元." % money)


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

# 工厂
class PaymentFactory:
    def create_payment(self, method):
        if method == alipay:
            return Alipay()
        elif method == wechat:
            return WechatPay()
        elif method == huabei:
            return Alipay(use_huabei=True)
        else:
            raise TypeError("No such payment named %s" % method)

# client
pf = PaymentFactory()
p = pf.create_payment(huabei)
p.pay(100)

工厂方法模式

内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
角色:
抽象工厂角色(Creator)
具体工厂角色(Concrete Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
技术分享图片
from abc import ABCMeta, abstractmethod


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


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

    def pay(self, money):
        if self.use_huaei:
            print("花呗支付%d元." % money)
        else:
            print("支付宝余额支付%d元." % money)


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


class BankPay(Payment):
    def pay(self, money):
        print("银行卡支付%d元." % money)


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


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


class WechatPayFactory(PaymentFactory):
    def create_payment(self):
        return WechatPay()


class HuabeiFactory(PaymentFactory):
    def create_payment(self):
        return Alipay(use_huabei=True)


class BankPayFactory(PaymentFactory):
    def create_payment(self):
        return BankPay()


# client

pf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)
View Code
优点:
每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
隐藏了对象创建的实现细节
缺点:
每增加一个具体产品类,就必须增加一个相应的具体工厂类

抽象工厂模式

内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。

 

技术分享图片
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
角色:
抽象工厂角色(Creator)
具体工厂角色(Concrete Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
客户端(Client)

 

优点:
将客户端与类的具体实现相分离
每个工厂创建了一个完整的产品系列,使得易于交换产品系列
有利于产品的一致性(即产品之间的约束关系)
缺点:
难以支持新种类的(抽象)产品 

建造者模式

内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
角色:
抽象建造者(Builder)
具体建造者(Concrete Builder)
指挥者(Director)
产品(Product)

 

技术分享图片
from abc import ABCMeta, abstractmethod

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

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


class PlayerBuilder(metaclass=ABCMeta):
    @abstractmethod
    def build_face(self):
        pass

    @abstractmethod
    def build_body(self):
        pass

    @abstractmethod
    def build_arm(self):
        pass

    @abstractmethod
    def build_leg(self):
        pass


class SexyGirlBuilder(PlayerBuilder):
    def __init__(self):
        self.player = Player()

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

    def build_body(self):
        self.player.body = "苗条"

    def build_arm(self):
        self.player.arm = "漂亮胳膊"

    def build_leg(self):
        self.player.leg = "大长腿"


class Monster(PlayerBuilder):
    def __init__(self):
        self.player = Player()

    def build_face(self):
        self.player.face = "怪兽脸"

    def build_body(self):
        self.player.body = "怪兽身材"

    def build_arm(self):
        self.player.arm = "长毛的胳膊"

    def build_leg(self):
        self.player.leg = "长毛的腿"


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


# client

builder = Monster()
director = PlayerDirector()
p = director.build_player(builder)
print(p)
View Code
建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
优点:
隐藏了一个产品的内部结构和装配过程
将构造代码与表示代码分开
可以对构造过程进行更精细的控制 

单例模式

内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
角色:
单例(Singleton)
优点:
对唯一实例的受控访问
单例相当于全局变量,但防止了命名空间被污染
发现实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法

 

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


a = MyClass(10)
b = MyClass(20)

print(a.a)
print(b.a)
print(id(a), id(b))

创建型模式小节

抽象工厂模式和建造者模式相比于简单工厂模式和工厂方法模式而言更灵活也更复杂。
通常情况下、设计以简单工厂模式或工厂方法模式开始,当你发现设计需要更大的灵活性时,则像更复杂的设计模式演化。

 

设计模式

标签:director   全局   情况下   好处   大众汽车   利用   display   不同的   bsp   

原文地址:https://www.cnblogs.com/foremostxl/p/10261052.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!