设计模式

Robin92 · · 641 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

课程使用语言 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] }

11 代理模式

静态代理和动态代理

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

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

11.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)
}

11.2 动态代理

代理任何类。

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


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:Robin92

查看原文:设计模式

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

641 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传