参考博客:

http://www.cnblogs.com/alex3714/articles/5760582.html

什么是设计模式

  • Christopher Alexander:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。”
  • 每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。
  • GoF(Gang of Four)
  • 设计模式四个基本要素:模式名称、问题、解决方案、效果

讲在设计模式之前

  • 对象/类

    • 封装
    • 继承
    • 多态
  • 接口:一种特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法。
    • 作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现。
    • 接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法

Python中接口的两种写法

设计模式六大原则

  • 开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
  • 里氏(Liskov)替换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
  • 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
  • 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
  • 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。
  • 单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

设计模式分类

简单工厂模式

  • 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
  • 角色: 工厂角色(Creator) 抽象产品角色(Product) 具体产品角色(Concrete Product)
  • 优点: 隐藏了对象创建的实现细节 客户端不需要修改代码
  • 缺点: 违反了单一职责原则,将创建逻辑几种到一个工厂类里 当添加新产品时,需要修改工厂类代码,违反了开闭原则

工厂方法模式

  • 内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
  • 角色:
    • 抽象工厂角色(Creator)
    • 具体工厂角色(Concrete Creator)
    • 抽象产品角色(Product)
    • 具体产品角色(Concrete Product)
  • 工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。

  • 适用场景:

    • 需要生产多种、大量复杂对象的时候
    • 需要降低耦合度的时候
    • 当系统中的产品种类需要经常扩展的时候
  • 优点: 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码 隐藏了对象创建的实现细节
  • 缺点: 每增加一个具体产品类,就必须增加一个相应的具体工厂类

抽象工厂模式

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

  • 适用场景:

    • 系统要独立于产品的创建与组合时
    • 强调一系列相关的产品对象的设计以便进行联合使用时
    • 提供一个产品类库,想隐藏产品的具体实现时
  • 优点:
    • 将客户端与类的具体实现相分离
    • 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
    • 有利于产品的一致性(即产品之间的约束关系)
  • 缺点: 难以支持新种类的(抽象)产品

建造者模式

  • 内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 角色:
    • 抽象建造者(Builder)
    • 具体建造者(Concrete Builder)
    • 指挥者(Director)
    • 产品(Product)
  • 建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。

  • 适用场景:

    • 当创建复杂对象的算法(Director)应该独立于该对象的组成部分(Builder)时
    • 当构造过程允许被构造的对象有不同的表示时(不同Builder)。
  • 优点:
    • 隐藏了一个产品的内部结构和装配过程
    • 将构造代码与表示代码分开
    • 可以对构造过程进行更精细的控制

单例模式

  • 内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
  • 角色:
    • 单例(Singleton)
  • 适用场景
    • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  • 优点:
    • 对唯一实例的受控访问
    • 单例相当于全局变量,但防止了命名空间被污染
  • 与单例模式功能相似的概念:全局变量、静态变量(方法)

创建型模式小结

  • 依赖于继承的创建型模式:工厂方法模式
  • 依赖于组合的创建性模式:抽象工厂模式、创建者模式

适配器模式

  • 内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
  • 角色:
    • 目标接口(Target)
    • 待适配的类(Adaptee)
    • 适配器(Adapter)
  • 两种实现方式:
    • 类适配器:使用多继承
    • 对象适配器:使用组合

  • 适用场景:

    • 想使用一个已经存在的类,而它的接口不符合你的要求
    • (对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

组合模式

  • 内容:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
  • 角色:
    • 抽象组件(Component)
    • 叶子组件(Leaf)
    • 复合组件(Composite)
    • 客户端(Client)

  • 适用场景:

    • 表示对象的“部分-整体”层次结构(特别是结构是递归的)
    • 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
  • 优点:
    • 定义了包含基本对象和组合对象的类层次结构
    • 简化客户端代码,即客户端可以一致地使用组合对象和单个对象
    • 更容易增加新类型的组件
  • 缺点:
    • 很难限制组合中的组件

代理模式

  • 内容:为其他对象提供一种代理以控制对这个对象的访问。
  • 角色:
    • 抽象实体(Subject)
    • 实体(RealSubject)
    • 代理(Proxy)
  • 适用场景:
    • 远程代理:为远程的对象提供代理
    • 虚代理:根据需要创建很大的对象
    • 保护代理:控制对原始对象的访问,用于对象有不同访问权限时
  • 优点:
    • 远程代理:可以隐藏对象位于远程地址空间的事实
    • 虚代理:可以进行优化,例如根据要求创建对象
    • 保护代理:允许在访问一个对象时有一些附加的内务处理

责任链模式

  • 内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
  • 角色:
    • 抽象处理者(Handler)
    • 具体处理者(ConcreteHandler)
    • 客户端(Client)
  • 例:
    • 请假部门批准:leader部门经理总经理
    • Javascript事件浮升机制

  • 适用场景:

    • 有多个对象可以处理一个请求,哪个对象处理由运行时决定
    • 在不明确接收者的情况下,向多个对象中的一个提交一个请求
  • 优点:
    • 降低耦合度:一个对象无需知道是其他哪一个对象处理其请求
  • 缺点:
    • 请求不保证被接收:链的末端没有处理或链配置错误

迭代器模式

  • 内容:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
  • 实现方法:__iter__、__next__

观察者模式

  • 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。观察者模式又称“发布-订阅”模式
  • 角色:
    • 抽象主题(Subject)
    • 具体主题(ConcreteSubject)——发布者
    • 抽象观察者(Observer)
    • 具体观察者(ConcreteObserver)——订阅者

策略模式

  • 内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
  • 角色:
    • 抽象策略(Strategy)
    • 具体策略(ConcreteStrategy)
    • 上下文(Context)
  • 适用场景:
    • 许多相关的类仅仅是行为有异
    • 需要使用一个算法的不同变体
    • 算法使用了客户端无需知道的数据
    • 一个类中的多种行为以多个条件语句的形式存在,可以将这些行为封装如不同的策略类中。

  • 优点:

    • 定义了一系列可重用的算法和行为
    • 消除了一些条件语句
    • 可以提供相同行为的不同实现
  • 缺点:
    • 客户必须了解不同的策略
    • 策略与上下文之间的通信开销
    • 增加了对象的数目

模板方法模式

  • 内容:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
  • 角色:
    • 抽象类(AbstractClass):定义抽象的原子操作(钩子操作);实现一个模板方法作为算法的骨架。
    • 具体类(ConcreteClass):实现原子操作
  • 适用场景:
    • 一次性实现一个算法的不变的部分
    • 各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复
    • 控制子类扩展

Day34 设计模式的更多相关文章

  1. S16课件

    Python之路,Day1 - Python基础1 介绍.基本语法.流程控制 Python之路,Day2 - Python基础2 列表.字典.集合 Python之路,Day3 - Python基础3  ...

  2. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  3. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  4. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  5. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  6. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  7. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

  8. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

  9. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

随机推荐

  1. flask—信号(blinker)

    Flask框架中的信号基于blinker,主要是让开发者在flask请求过程中定制一些用户行为. 安装blinker pip3 install blinker 1.内置信号 request_start ...

  2. day5-正则表达式 re

    re模块用于对python的正则表达式的操作. 字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配 ...

  3. 图层的使用要点(CALayer)

    A,图层和路径 基本图层 CALayer 动画的主角 形状图层 CAShapeLayer 绘制不规则图形 渐变图层 CAGradientLayer 颜色渐变.阴影 复制图层 CAReplicatorL ...

  4. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) B. The Meeting Place Cannot Be Changed

    地址:http://codeforces.com/contest/782/problem/B 题目: B. The Meeting Place Cannot Be Changed time limit ...

  5. JavaScript 操作JSON总结

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...

  6. java中元注解

    java中元注解有四个: @Retention @Target @Document @Inherited:  @Retention:注解的保留位置 @Retention(RetentionPolicy ...

  7. Linux CentOS6环境下MySQL5.1升级至MySQL5.5版本过程

    转载地址:http://www.laozuo.org/6145.html 老左今天有在帮朋友的博客搬迁到另外一台VPS主机环境,其环境采用的是LLSMP架构的,原先的服务器采用的是LNMP网站环境,其 ...

  8. RabbitMQ学习之(五)_一个基于PHP的RabbitMQ操作类

    //amqp.php类文件 <?php class Amqp { public $e_name; public $q_name; public $k_route; public $channel ...

  9. 巨坑:jqgrid竟然取不到编辑模式下input的值

    今天遇到最奇葩的问题,竟然取不到input的值,感觉世界观都颠覆了.后来一搜资料,又是jqgrid框架搞的鬼,真搞不明白,开发框架就好好开发框架,留这么多坑有意思吗? jqgrid编辑模式下不要调用g ...

  10. JS类、对象、方法、prototype、_proto_

    案例代码: function People(name) { //对象属性 this.name = name; //对象方法 this.Introduce = function() { alert(&q ...