设计模式

2020-04-04  本文已影响0人  Robin92

课程使用语言 Java

1. Singleton 单例模式

保证在内存中只有一个实例。

1.1 饿汉式

利用:JVM 每个 class 只会 load 到内存一次。
优点:简单实用,推荐使用。
缺点:类装载时就实例化了。(后来的懒加载是使用的时候加载,无此缺点。)

1.2 懒汉式

特点:什么时候用时什么时候初始化。

优点:什么时候用什么时候初始化。
缺点:多线程并发中可能初始化多次。
造成问题测试:多线程中输出实例的哈希值(不同对象的哈希值应该是不同的)。

1.3 加锁

特点:可以保证并发没问题
缺点:加锁程序变重

1.4 静态内部类

利用:jvm 在加载类时只会加载一次;且只在用时加载
特点:实现了懒加载(用时加载)
缺点:无
说明:因为只有 getInstanct 使用了内部类,所以只有调用它时才加载;且 JVM 保证只加载类只加载一次。

1.5 枚举单例

特点:不仅可以防并发,还可以防反序列化。

(需要去找下文档看看)

2. 策略模式(Strategy)

就像 Golang 的 sort.Sort() 功能这样的实现。

type SortBy []Type

func (a SortBy) Len() int           { return len(a) }
func (a SortBy) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a SortBy) Less(i, j int) bool { return a[i] < a[j] }

2.1

3. 工厂模式

任何可以产生对象的方法或类,都可以称之为工厂。

3.1 简单工厂

用一个 Factory 返回需要的类(某一种类),可以在 Factory 生产类的时候做一些事情。

3.2 抽象工厂

抽象的工厂可以生产多种抽象的产品。
具体的工厂生产具体的产品。
(工厂是一层多品类的,产品也是一层多品类的;如现代人/魔法人及他们的衣食住行。)

4. 门面 Facade 和调停者 Mediator

类似于消息中间件。
就是说有一个统一管理的地方,以减少了不同对象之间复杂的调用。

5. 装饰器 Decorater

用聚合。

6. 责任链 Chain Of Responsibility

比如需要各种 filter。
可以用成

for (Filter f : filters) {
    f.doFilter()
}
filterChain = filterChain.add().add()
filterChain.doFilter()

7. 观察者 Observer

常用于处理事件的,常结合 责任链 一起使用。

例子:有观察者们观察婴儿是否哭,比如有 爸爸、妈妈、狗……

则实现一个抽象接口,有 actionOnCry() 方法,用责任链的方式添加在 婴儿 的 Class 中,做一些处理。

8. 组合 Composite

树状结构专用模式。各种 Node 组合。

9. 享元 Flyweight

共享元数据。比如一些字段文件在一个 ttf 文件中。

池就是这个模式。池中有多个已生成的 object,每次用时拿一个,用完了放回去,没可用的重新生成。

10. 代理模式 Proxy

静态代理和动态代理

类似于 继承 和 聚合,想象一下,如果要在 doSomething() 本身上,记录一些事情比如记录此函数的执行时间。那么可以用继承的方法,同样调用父类的 doSomething() 再记录一下别的事情。

代理呢,是另一种方法。这个代理就是代理做某些事情,你把你的方法传过来,我帮你执行,在帮你执行时我也可以做自己的事。
这样的话,就需要你传过来你的类,你的方法,让我(代理)来给你执行。我在代理执行的时候,就可以做自己的一些事。

10.1 静态代理

只代理某 类。如下面的 Go 代码,DurationProxy 只能代理 func() 这样的函数,如果是一个 func(in int) error 这样的函数就不能代理了。

func main() {
    DurationProxy(Move)
}

func DurationProxy(f func()) {
    start := time.Now().Unix()
    f()
    end := time.Now().Unix()
    fmt.Println("this func cost", end-start, "second")
}

func Move() {
    time.Sleep(3 * time.Second)
}

10.2 动态代理

代理任何类。

将类、方法、参数都传入代理中,由代理动态反射到原来的对象,然后来执行。

11. 迭代器 Iterator

hasNext()next()

就你查 Mongodb 的 Iter

12. 访问者 Visitor

在结构不变的前提下,动态改变对内部元素的动作。

内部每一个元素都实现对不同 Visitor 的不同接待动作。

例子,不同人买不同电脑配件有不同折扣,最后组装成电脑。

前提 结构固定

13. 构建器 Builder

分离复杂对象的构建。

用过比如 purchase()createOrder(),一种只传一个商品,一种传多种商品。

14. 接口转换器 Adapter/Wrapper

就是转接头

15. 桥接 Bridge

双维度扩展

分离抽象与具体,用 组合 的方式使用抽象和具体。

16. 封装命令 Command

execute()

17. 原型模式 Prototype

又叫 Clone 模式,就是 Clone

18. 备忘录 Memonto

便于回滚。记录快照(瞬时状态),存盘。
对象的序列化或者叫持久化。

19. 模板方法 TemplateMethod

勾子函数。

20. 状态模式 State

根据状态决定行为。

将 State 抽象出来,每种 State 实现自己对应处理方法。

21. 解释器 Intepreter

用来解释脚本语言的。

基本用不上。


设计模式.png

名称要记下来,类图要能想起来。项目中使用常常是需要结合使用的。

上一篇下一篇

猜你喜欢

热点阅读