设计模式分类

创建型模式(5种):工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式
结构型模式(7种):适配器模式、桥模式、组合模式、装饰模式、外观模式、享元模式、代理模式
行为型模式(11种):解释器模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式、模板方法模式

创建型模式

简单工厂模式

内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
角色:
工厂角色(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 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)

 

优点:

每个具体产品都对应一个具体工厂类,不需要修改工厂类代码

隐藏了对象创建的实现细节

缺点:

每增加一个具体产品类,就必须增加一个相应的具体工厂类(去调用产品)

 

抽象工厂模式

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

角色:
抽象工厂角色(Creator)
具体工厂角色(Concrete Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
客户端(Client)

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

  

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

如要增加手机产品配件,不再是3个一套,而是更多,就需要大改 。用的较少

建造者模式

内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
角色:
抽象建造者(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 MonsterBuilder(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 = MonsterBuilder()
director = PlayerDirector()
p = director.build_player(builder)
print(p)

  

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

单例模式

内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
角色:
单例(Singleton)
优点:
对唯一实例的受控访问
单例相当于全局变量,但防止了命名空间被污染

class Singleton:
def __new__(cls, *args, **kwargs):
_instance = None # 假定没有实列
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)) """
20
20
1319845376968 1319845376968
""" # 日志对象
# 数据库链接池

  

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

sjms-2 创建型模式的更多相关文章

  1. 工厂方法模式——创建型模式02

    1. 简单工厂模式     在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...

  2. 单例模式——创建型模式01

    1. 名称     单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类.单例模式是一种对象创建型模式. 2. 问题    ...

  3. C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)

    一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...

  4. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

  5. 第26章 创建型模式大PK

    26.1 工厂方法模式 VS 建造者模式 26.1.1 按工厂方法建造超人 (1)产品:两类超人,成年超人和未成年超人. (2)工厂:这里选择简单工厂 [编程实验]工厂方法建造超人 //创建型模式大P ...

  6. 创建型模式(前引)简单工厂模式Simple Factory

    一引出的原因(解决下面的问题) 简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式. 在简单工厂模式 ...

  7. 设计模式之美:Creational Patterns(创建型模式)

    创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...

  8. 设计模式学习之建造者模式(Builder,创建型模式)(6)

    假如我们需要建造一个房子,并且我们也不知道如何去建造房子,所以就去找别人帮我们造房子 第一步: 新建一个房子类House,里面有房子该有的属性,我们去找房子建造者接口HouseBuilder,我们要建 ...

  9. 设计模式学习之原型模式(Prototype,创建型模式)(5)

    通过序列化的方式实现深拷贝 [Serializable] public class Person:ICloneable { public string Name { get; set; } publi ...

  10. 设计模式学习之单例模式(Singleton,创建型模式)(4)

    假如程序中有一个Person类,我的需求就是需要在整个应用程序中只能new一个Person,而且这个Person实例在应用程序中进行共享,那么我们该如何实现呢? 第一步: 新建一个Person类,类中 ...

随机推荐

  1. imgtobase64

    # -*- coding: utf-8 -*- import re import base64 from cStringIO import StringIO from PIL import Image ...

  2. <Dare To Dream>第五次作业:团队项目需求改进与系统设计

    任务1完成情况: a.分析<家教服务管理系统需求规格说明书>初稿的不足: uml建模不完整,无类图.流程图,仅有的用例图也不规范. b.功能分析的四个象限: c. 团队项目的WBS: d. ...

  3. 保存chrome书签中链接顺序的小技巧

    长期以来,我的chrome浏览器书签总是不能自主排序,用书签管理器排序之后,不关闭chrome是好的,一旦关闭重开,又会恢复成原先的排序,实在很诧异,手动修改Bookmars文件也不行. 我们知道,如 ...

  4. Vue+DataTables warning:table id=xxxx -Cannot reinitialize DataTable.报错解决方法

    问题描述: 使用DataTables来写列表,用vue来渲染数据,有搜索功能,每次点击搜索就会报错,如下图所示. 问题排查: 找了一系列原因,最后发现是我每次请求完数据之后都会添加分页功能,从而导致了 ...

  5. css第二天

    二丶 1.字体属性font: 字体名称(font-family)字体大小(font-size):pc中通常,字体大小表示为12px,14px.移动设备中通常表示为0.57rem.字体粗细(font-w ...

  6. 微信小程序-数据绑定

    在js页面的data字典内添加绑定数据 data: { "messg":"helloworld " }, 在wxml页面内使用{{}}调用数据

  7. Android 网络编程的陷阱

    陷阱一,不要在主线程或者UI线程中建立网络连接 Androd4.0以后,不允许在主线程中建立网络连接,不然会出现莫名其妙的程序退出情况.正确的做法是在主线程中,创建新的线程来运行网络连接程序. // ...

  8. volatile和synchronized实现内存可见性的区别

    先看看synchronized实现内存可见性 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性.我们不仅希望防止某个线程正在使用对象状态而另一个 ...

  9. 20175314 实验二 Java面向对象程序设计

    20175314 实验二 Java面向对象程序设计 一.实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 二 ...

  10. (1)Linux常用的运维平台和工具

    运维工程师使用的运维平台和工具包括: Web服务器:apache.tomcat.nginx.lighttpd 监控:nagios.ganglia.cacti.zabbix 自动部署:ansible.s ...