设计模式

180 阅读11分钟

什么是设计模式

在特定的场景,用最优的代码书写方式来解决事情,没有最好的代码,只有最好的解决方式

设计模式的意义

让代码结构更好的服务你的问题,解决你的问题,就像乐高不同组装方式能呈现不同的状态,你想要的状态,就要用符合你状态的组装方式

解决你问题的设计模式

本设计模式都是基于Java来的举例,设计模式是属于所有语言,大同小异而已,

会列取常用的设计模式,在你遇到类似的场景,使用你匹配的设计模式,是本篇博客的意义所在

所有的设计模式原则

所有的设计模式都会遵守以下原则的其中一或者更过,所以代码的世界是相对的,全部符合是比较理性的状态,但是放心只要满足其中一部分你就很优秀了

  • 单一职责(Single Responsibility Priniple):高内聚,你把简单事做好

一个人只做相关的一件事,比如你写的封装的函数,就是单一原则因为他就是在做一件事, 单一原则的界限不是很三八线,所以你想抬扛这个模式能帮助到你和别人对峙;

  • 开闭原则(OCP): 实现了功能也要能扩展

你做了一个功能但是无法扩展,新的类似功能来了你又要重新写一个类似的差异不大,做不到可以扩展会,那你的代码是不是会原来越乱,就想被猫扰乱的毛线团一样是不是很头疼

  • 替换原则(LSP): 不想要了可以换掉,低耦合

你是程序员,你35岁了突然老板想换掉你怎么办,在boss 的角度就是要尊属可替换原则,老板不变你可以替换,这就是这个原则的好处

  • 依赖倒置原则(DIP):你按照我的意思来,你怎么做我不管,低耦合

老板是上流,程序员是具体实施,我不管你什么方式,你的细节我不管,我的需求你按照我的来,你换技术实现方式我不care ,我的需求对产品经理来提,产品经理给定向,你来实现细节,对于Java 来说就是面向接口编程,产品就是接口,在方向不变的同试增加新的赋能:(也是替换原则的一种具体实现方式)

  • 接口隔离原则: 老板有多个项目需求,但是我只听我的项目产品的需求,低耦合

从我的产品经理来的需求都有退出功能,那他的产品,我都可以最后使用退出,其他产品的东西我不管,方便同一处理,

  • 最少知识原则:高内聚,你只要关心这件事的结果

你实现的方式是个黑盒,你给我想要的,我不需要你怎么实现的,知道的越少责任越少,关联性越少

常用设计模式

本模块介绍常用设计模式,大家可以根据问题场景,选择合适的设计模式

单例模式

  • 定义:整个系统中只存在一个实例,并自行实例化
  • 使用场景:一个类的创建需要系统资源比较多,或者整个系统只要一个实例防止多实例造成异步数据脏乱差,这个时候就需要这个模式,比如数据库的访问,io 流的使用
  • Andorid 中使用:
LayoutInflater ll=  LayoutInflater.from(context)

// 其内部是用map key 来获取唯一对象,单利是我们平常开发中使用最多的设模式,不是吗

建造者模式

  • 定义:一个复杂的对象和他的表示分离,相同构建函,不同构建顺讯,表示不同
  • 使用场景:产品比较复杂时候,产品的构建顺序不同,功能不一样,比如生活中刷牙和吃饭同样的行为顺讯不同结构不同,或者参数比较多,参数都有默认值,比如定制mac Pro,基础版本的配置比较低,你给商家特定测配置参数,做个一个性能更好的电脑,构建模式的构造细节保存在构建类内部
  • Andorid 中使用:
ALertDialog 的构建,通过设置不同的参数,表示不一样

原型模式(copy)

  • 定义:通过copy 原来数据的对象,来快速构建对象
  • 使用场景:类的初始化需要消费的资源比较多,new 一个对象过程比较复杂,多线程访问同一个同时访问同一个数据有可能修改,原型模式可以避免脏读
  • 在Andorid 中使用:

Inttent intent=(Intent)shareIntetn.clone
inttent 如果构建比较复杂就clone,
(多为继承 Cloneable ,copy 新的数据,创建新的对象地址,这里实现copy 的方式是把原intent 的参数重新赋值一遍)

工厂模式

工厂方法模式

  • 定义:创建一个对象的接口,让子类决定需要实例化哪个对象
  • 使用场景:创建较为复杂对象时使用,可以直接new 的就不用使用了,工厂方法模式使用比较广泛, 一般是定义两了抽象,一个产品抽象,一个工厂生产抽象
  • 在Android 中的使用
Activity 中的onCreate 方法, activity 相当于工厂丑行。布局 相当于继承 View 产品抽象

抽象工厂模式介绍

  • 定义:只要出现抽象两个字就代表了,不决定,具体实现下放,相对工厂方法,抽象方法扩展性更高,他的定义为 创建相同功能的产品,但是具体不指定具体实现

  • 使用场景:相对于具体方法,抽象工厂模式生成的更多,并且生成的产品相关联,更细化,所以叫工厂,一个类似产品有类似相同功能,又有差异化的使用抽象工厂模式。多个产品,多个产品又有关联性

  • Android 中使用:

  Activity 的onCreate 的Activity 相当工程方法,service 也相当于 工厂方法,
  站在framWork 角度的话,他们都继承 ContextWrapper,ContextWrapper 定义了生产serrvice 和
  Activity ,ContextWrapper 为抽象工厂 定义生产Activity 和service 同为四大组件工厂,
  所以抽象比方法工厂,实现上多了工厂的抽象,产品生产更多

策略模式

  • 定义: 定义一算法,具体的算法封装在具体的实现类中,算法可以根据具体使用场景。可以替换
  • 使用场景:同个问题可以有多种实现方式,只是具体的算法有行为差别,需要过多的if else 的使用的时候
  • Android 中使用场景:
android 动画里的时间差值器

状态模式

  • 定义:一个对象状态改变时,可以影响其他行为
  • 使用场景: 对象的行为取决于其他状态的行为(和策略模式的最大的区别),if else 过多
  • 在Android 的使用场景:
Android wifi 管理器,wifi 列表取决于有多少可用wifi

责任连模式

  • 定义 :多个对象都有可能处理同一事件,这些对象有顺序的链接成一条连,顺序传递,直到有对象处理这个事件
  • 使用场景:多个对象处理处理同一个事件,具体使用哪个事件,由具体运行时的状态决定
  • Android 中使用场景:
 点击事件的处理

解释器模式

  • 定义:遵守一定的文法,某个具体的字符表达的意思,通过解释器来生成最终的行为生成
  • 使用场景:需要解释执行的文法
  • Android 中使用:
java 的虚拟机,android 中的清单文件

命令模式

  • 定义:将一个请求封装成一个对象,把客户的请求客户端参数化,并且支持回调,撤销和回调
  • 使用场景: 对于同一事件,不同的接受参数对应不同的执行命令对象
  • Android 的使用场景:
Android 中,事件点击,会转化为Notiargs 抽象对象,比如按键点击事件,会实现Notiargs 的命令对象,并通过回调的形式反应给用户

观察者模式

  • 定义:一对多的行为,一改变多相应
  • 使用场景: 关联行为,事件触发行为,跨系统的消息交互场景
  • Android 中使用的场景:
点击事件,evenbus使用等

备忘录模式;

  • 定义: 一个对象容易被修改,在这个对象外复制到另一个对象,方便日后恢复状态
  • 使用场景:需要保存一个对象的一些状态到另一个状态 ,或者 本对象不希望被直接访问,可以使用备忘录,生成一个备忘录录对象,此对象和保护对象有同样的同样的状态(和原型模式最对大的区别是,原型是为了快速创建对象,备忘是为了保护对象,和恢复对象)
  • 在Android 的使用:
  onSaveInstanceState 和 OnRestorenstanceState

迭代器模式

  • 定义: 提供一个一种方法顺序访问容器内的各个元素
  • 使用场景:访问容器的内的元素
  • Android使用:
遍历每map

模板模式

  • 定义: 抽象用户行为,某些具体行为下放到子类,或者 方便子类不改变原抽象对象的行为增加自己的行为
  • 使用场景:* 多个子类有公有的方法*核心心算法在抽象类,算法细节下放到子类
  • Android中使用:
重构中的BaseActivity 和AsyncTask

访问者模式

  • 定义 封装一些作用于某种数据结构的各种元素的操作,在不改变数据结构的前提写,访问数据和增加数据处理
  • 使用场景:* 对象比较稳定,单需要经常多对象结构对象进定义新的操作和访问 *在原数据的基础上增加行为避免污染对象
  • Android 总使用:
Android APT 给于访问者权限,可以在获取到的对象后增加新的行为

中介者模式

-定义:添加第三者通过第三者来解耦 -使用场景:防止两个相互关联的对象,一个对象发生改变防止其他对象 也发生改变 -Android中使用:

Android 锁屏功能,Keyguard

代理模式

  • 定义: 为其他对象提供一个代理,以控制这个对象的访问
  • 使用场景: 不想直接访问一个对象,或者对一个对象存在访问困难的时候使用代理
  • Android 中使用:
Android 中 ActivityMAngerNAtive ,是被ActivityMAngerProxy 所代理
iBinder 机制也可以当做一个代理类来使用

组合模式

  • 定义:将多个有关联的队形以树形结构形式组合,使得用户对组合对象和单个对象使用具有一致性
  • 使用场景:具有层次的对象,能都独立出部分模块和功能,比如文件夹操作,可以删除整个,也个删除子文件夹的某个文件,可以遍历所有的文件,也可以遍历具体文件夹的某个文件
  • Android中的使用:
Android 中view ——》viewGroup 的层级和使用

适配器模式

  • 定义: 让一个类的接口变化成客户端所期待另一个接口,让两个原本因接口不一样导致无法一起工作的两个类一起工作
  • 使用场景:* 接口不兼容 *需要同一的输出接口
  • Android 中的使用:
recycleView 的Adapter

装饰者模式

-定义: 动态的对一个对象添加新的功能,相比较继承更加灵活 -使用场景:需要动态的扩展对象

  • Android 使用场景:
 Aop 的使用,代理到对队后在前后加逻辑,
 
 Android中Context 的ContextWrapter 装饰ConTextImpl

享原模式

  • 定义:分享大量力度的细粒度对象
  • 使用场景:系统中需要大量的细粒度对象,需要缓冲池的对象
  • Android 的使用:
线程池

外观模式

-定义:要求一个子系统外部和内部通信必须通过一个同一的对象进行 -使用场景:子系统的变化不影响外部的使用方式,如相机的使用和电话使用,都是通过手机来使用,操作两个子系统

  • Android 中的使用:
sdk 的封装,和contextImpl 内对多个子系统的调用,startActivity sendBroadCast()等

桥接模式

  • 定义 :将抽象部分和实现部分分离,灵活多维度使用
  • 使用场景:多维度的上下级都可以使用。什么样的车汽车是一个维度,加几号的油水是一个维度
  • 在Android 中的使用:
比如view 和button 的细节实现,自定义view的实现,View 和buttoncanvas 的使用