美文网首页
设计模式

设计模式

作者: Robin92 | 来源:发表于2020-04-04 23:29 被阅读0次

    课程使用语言 Java

    1. Singleton 单例模式

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

    1.1 饿汉式

    • 类中定义出来此实例类型变量,并且设置为 私有 静态final 的。(new 出实例。也可以用静态语句块方式定义)
    • 类中将构造方法重写为 private 的,且不做任何事情。(其他人 New 不出来)
    • 提供 public 方法返回此实例。

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

    1.2 懒汉式

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

    • 先声明一个实例(private static),但不初始化。
    • 重写构造方法为 private 的。
    • 在 getInstance 中判断实例不存在时初始化,存在则返回。

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

    1.3 加锁

    • 判断实例为 null 则加个锁,让线程抢锁(锁的执行是单人次的);若非 null 则返回实例
    • 抢到锁后,再次判断这个实例是否被初始化,若有则返回实例,若无则初始化

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

    1.4 静态内部类

    • 在类中定义一个 私有静态 的类,作为此实例的持有者
    • 在静态内部类中初始化此实例为 私有的 成员变量
    • 用外层类中公有的方法 getInstance,返回静态内部类的私有成员变量

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

    1.5 枚举单例

    • 定义一个枚举类,只给它一个取值,就是 Instance

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

    (需要去找下文档看看)

    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

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

    相关文章

      网友评论

          本文标题:设计模式

          本文链接:https://www.haomeiwen.com/subject/slqjyhtx.html