C#23种设计模式理解

本文介绍了C#中的23种设计模式,分为创建型、结构型和行为型。创建型包括工厂方法、抽象工厂、单例、建造者和原型模式,结构型涵盖适配器、装饰器、代理、外观、桥接、组合和享元模式,行为型涉及策略、模板方法、观察者等。每种模式都提供了理解、实现和示例,帮助开发者理解和应用设计模式。

概述

有句话这样说:程序设计中,没有什么问题是包一层不能解决的,如果有,就在包一层!

  • 三大类型:
    • 创建型模式,5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
    • 结构型模式,7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
    • 行为型模式,11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
  • 六大原则
    • 单一职责原则
    • 里氏替换原则(Liskov Substitution Principle)
    • 依赖倒转原则(Dependence Inversion Principle)
    • 接口隔离原则(Interface Segregation Principle)
    • 迪米特法则(最少知道原则)(Demeter Principle)
    • 合成复用原则(Composite Reuse Principle)

关于设计模式的理解

一、创建型

  • 简单工厂模式

    • 理 解:爸爸对儿子说:“要什么就和我说,你只管好好读书,别问老子是咋弄的!”
    • 主要解决:大量创建对象时,依赖细节,创建时各种各样的逻辑干扰
    • 实 现:3种实现:1 通过上端指定类型创建 2.通过配置文件实现可配置创建 3.配置+反射完全解除细节依赖创建,可配置、可扩展
    • 核 心:将创建过程封装,将上端应用和下端逻辑分离
    • 举 例:最常用模式,绝大多框架使用工厂模式
  • 工厂方法模式:

    • 理 解:老板说:“为了各个部门之间互不干扰,你们独立运作,各干各的吧"
    • 主要解决:对象创建时,避免修改创建方法的逻辑,当需要创建新对象时,添加新工厂而不是修改来的代码,对修改关闭、对扩展开发
    • 实 现:提供一个接口工厂,为每个对象创建一个工厂方法类
    • 核 心:每个对象创建一个工厂方法类,对修改关闭、对扩展开发
    • 举 例:略
  • 抽象工厂模式:

    • 理 解:由于工厂太多,先把工厂抽象化了,但是每个工厂中产品型号又很多,所以把产品型号也抽象化了!在使用的时候得确定2点:需要用哪个工厂,造什么型号的车!
    • 主要解决:在一个产品族里面,定义多个产品,提供一个创建一系列相关或相互依赖对象的接口,具体创建由具体实现工厂去完成
    • 实 现:创建抽象工厂,抽象工厂中包含接口类型的抽象方法,每个接口类型包含各自的接口定义,每个接口有对应一个实现类,对象在创建时,需要完成2次抽象
    • 核 心:工厂抽象化,抽象方法类型再次抽象化,
    • 举 例:ado.net对DB的支持
  • 单例模式:

    • 理 解:“本姑娘从不出门见人,要看我就加微信号XXX,我只把照片发个第一加的人,其他人统统去找第一个人!
    • 主要解决:一个全局使用的类频繁地创建与销毁,为保证一个类仅有一个实例,并提供一个访问它的全局访问点,
    • 实 现:私有化构造函数,对外提供一个可控入口用于对象创建(入口可以是一个方法,页可以是属性)
    • 核 心:私有化构造函数 双if+lack并发控制
    • 举 例:略
  • 建造者模式:

    • 理 解:“我是美国的波音公司,专门负责使用来自各个国家生产的零件来组装大型飞机”
    • 主要解决:对象创建时:1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
    • 实 现:多个创建者类:实现公共基类,提供各个功能实例的创建;一个组装者类:管理建造出来的实例的依赖关系
    • 核 心:上端指定具体创建行为、建造者管理组装各个类依赖关系、根据上端要求(注入的对象)分配到下端创建具体对象
    • 举 例:造车、肯德基套餐
  • 原型模式

    • 理 解:产品经理说:“先弄个标准版本产品出来,以后改一改就可以卖钱了!”
    • 主要解决:创建重复的对象,保证性能,利用已有的一个原型对象,快速地生成和原型对象一样的实例
    • 实 现:在单例的基础上,将对象的创建改造为对象克隆,或者系列化克隆
    • 核 心:对象克隆,使用Object的MemberwiseClone克隆或序列化克隆
    • 举 例:创建多个学生对象,但姓名和年龄不同

二、结构型

  • 桥接模式:
    • 主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展不灵活,而将抽象部分与实现部分分离,使它们都可以独立的变化。
    • 实 现:提供抽象化和实现化之间的桥接结构,来实现二者的解耦,“ 变化封装”
    • 核 心:包3层,通过桥接层将最外层和最内层链接,(1).将上层对象注入桥接层 (2).桥接层到下层通过接口链接,具体实现由上端决定
    • 举 例:造不同操作系统手机,手机都有打电话、发短信功能
  • 策略模式:
    • 主要解决:类或它的行为可以在运行时改变,下端的行为有由上端的选择决定,解决有多个if…else带来的复杂和难以执行
    • 实 现:上端将包含具体对象的全部信息注入Context策略类,Context负责指定具体行为、每个Context为一个解决方案
    • 核 心:抽象一个基类,抽象行为由各子类去具体实现,通过Context策略类在运行时任意地替换实现不同行为
    • 举 例:加减乘除计算器
  • 代理模式
    • 理 解:“需要新增什么技能可以找我,我能在现有的功能上扩充更能多!”
    • 主要解决:对象新增功能时,在访问对象上新加一个对象的访问层,避免对原来对象的修改
    • 实 现:增加中间层 优点 1、职责清晰 2、高扩展性 常见的日志代理、异常代理
    • 核 心:包一层
    • 举 例:日志代理、异常代理
  • 装饰器模式
    • 理 解:Hi,Man!不管你想变得多么强大,都得自个亲自来!我只能给你提供一个超人面具
    • 主要解决:扩展功能的增多,子类会很膨胀,组合型类过多
    • 实 现:动态增加功能 1.调用时注入当前类 2、构造器先调父类在构造自己的类
    • 核 心:1.调用时注入当前类,构造器先调父类在构造自己的类
    • 举 例:装备升级、装扮圣诞树
  • 组合模式
    • 主要解决:树形,父子节点、对象里存在对象,不断包含情况
    • 实 现:树枝内部组合接口,并且含有内部属性 List
    • 核 心:递归
    • 举 例:如树形菜单,文件、文件夹的管理。
  • 外观模式
    • (最简单的模式)
    • 理 解:老铁,面向接口编程呀!
    • 主要解决:为每个类提供一组接口,外层调用都通过接口,隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口
    • 实 现:一类一个接口,在把业务逻辑封装一层,
    • 核 心:面向接口
    • 举 例:略
  • 享元模式
    • 理 解:就是缓存对象,你得注意并发,并发!!
    • 主要解决:在有大量对象时,有可能会造成内存溢出,我们创建的对象缓存起来,下次创建时直接返回在内存中已有的对象,避免重新创建。
    • 实 现:提供一个享元工厂,用于对象的创建、缓存
    • 核 心:对象缓存器、双if+lack并发控制
    • 举 例:“DADADA”字母的创建 *

三、行为型

对在不同的对象之间划分责任和算法的抽象化

  • 观察者模式

    • 理 解:太监总管:“你们就别一直候在这了,有什么话尽快和我说,我会一一转告皇上!”皇上一出来,太监就把所有人的话转述了
    • 主要解决:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,且保证高度的协作、低耦合
    • 实 现:在被观察者中设置一个接口类型的集合(或者一个多播委托(事件)),存储上端指定的关系对象集,上端完事件触发和关系指定后,在完成调用
    • 核 心:观察者对象的管理(存储)及他们内部方法的调用(唤醒)
    • 举 例:太监和大臣、猫叫引起的连锁反应、鸿门宴
  • 适配器模式

    • 理 解:世界那么大,你只差一个万能转接头
    • 主要解决:接口不能被修改
    • 实 现:加一层 继承或组合实现
    • 核 心:不同数据库访问
    • 举 例:数据库访问 NoSql访问
  • 命令模式

    • 主要解决:高耦合业务,需要对行为进行记录、撤销和重做业务
    • 实 现:松耦合 通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
    • 核 心: action 核心控制器,反射+配置,实现根据业务实际动态创建类
    • 举 例:输入r 打印Read!
  • 模板方法模式

    • 理 解:见过各种各样的文档模板吧,给你提一个供具有标准结构、标准格式的模板,你要做的就是往里添肉
    • 主要解决:子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
    • 实 现:将公共代码放在父类、特殊方法写成抽象、可变方法写成virtual
    • 核 心:abstract、virtual的使用 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现
    • 举 例:T平台CostModel和各具体业务实现、MVC控制器的实现
  • 迭代子模式

    • 主要解决:不同聚合对象的遍历
    • 实 现:每个对象对外提供一个相同遍历方法,方法的实现逻辑各不相同,但对于上端而言遍历每个对象的方法都相同
    • 核 心:定义接口IIterator,实现遍历3个基本方法MoveNext、Reset、Current
    • 举 例:数值、集合的Foreach循环遍历实现
  • 责任链模式

    • 理 解:生病要请假,不管公司如何规定上级审批权限,你只需要找你的直属上级说:你要请N天假,然后等结果就OK
    • 主要解决:请求的发送者和接收者进行解耦,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,
    • 实 现:将业务具体逻辑封装,关系对象提取抽象,
    • 核 心:关系责任链由下端指定
    • 举 例:请假审批权限
  • 备忘录模式

    • 理 解:原理还是对象缓存,SNV版本控制都知道吧!和享元模式对比明显:一个是SVN,一个是单例
    • 主要解决:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
    • 实 现:上端提供对象状态,备忘录管理层负责存取对象管理,对象缓存类提供对象存储,上端和缓存类解耦
    • 核 心:缓存类
    • 举 例:LOL游戏升级、回滚、“后悔药”
    • 其 他:(1).和命令模式的比较 (2).为提高性能可结合原型模式:备忘录+原型 (3).和享元模式的对象缓存原理相似
  • 状态模式

    • 理 解:QQ中的漂流瓶玩过吧,一个瓶子可以扔来扔去,每个人可以加备注,可以指定扔给谁
    • 主要解决:对象的行为依赖于它的状态属性,并且可以根据它的状态改变而改变它的相关行为
    • 实 现:抽象基类用于提供上端状态注入,Context数据上下文做为中间层用于存取状态及相关行为、具体子类指定行为的关系、实现自己部分逻辑
    • 核 心:创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象
    • 举 例:红绿灯交替变化
  • 访问者模式

    • 主要解决:稳定的数据结构和易变的操作耦合问题
    • 实 现:使用一个访问者类,用它改变元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变
    • 核 心:在数据基础类里面有一个方法接受访问者,将自身引用传入访问者
    • 举 例:不同阶段、不同角色获取资源权限
  • 中介者模式

    • 理 解:一个贴心秘书,专干各种会议通知,消息转发的事
    • 主要解决:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散
    • 实 现:中介类提供对象的缓存和对象消息转发到下端的每个对象,具体的对象关系由上端指定
    • 核 心:中介类提供对象缓存,对象遍历,每个关系对象面向抽象编程
    • 举 例:消息由中介群发
  • 解释器模式

    • 主要解决:给定一个语言,定义它的文法表示,定义一个解释器,这个解释器使用该标识来解释语言中的句子
    • 实 现:抽象一个解析器基类,添加Context上下文作为中间层存取信息,上端通过Context将信息注入到各个解析器,最后再从Context中获取数据
    • 核 心:每个解析器通过静态构造器+缓存+解析方法构成,上端和解析器之间通过Context上下文做数据桥接,上端通过组合各个解析器完成具体逻辑
    • 举 例:SQL 解析、符号处理引擎、字符转换
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值