GOF 23种设计模式总结
一、简介
二、详情
三、细节
四、举例
4.1、单例模式
同一个进程只能实例化一次。
private修饰符关闭发现,静态属性,暴露静态方法
a、 多线程会出问题,因为不知道是否已经创建对象,会重复创建导致单例失败。处理方式为加锁,并且是双检锁,好处是可以避免等待锁。
b、当然,多线程如果不想使用锁,也可以用静态构造函数
c、如果不想使用静态构造函数,还可以使用静态字段。静态字段是要比静态构造函数先初始化
小结:双检锁属于懒汉式,静态构造函数/静态字段属于饿汉式。
4.2、原型模式
用于创建重复对象,同时又能保证性能。专门用来批量生产对象。
4.2.1、普通单例模式不是很快嘛,批量创建重复对象有何问题?
因为是单例,进程中只有一个实例,所以操作的是一个对象,导致对象被修改盖。
4.2.2、基于4.2.1的问题,使用类的内存拷贝
这里涉及到一个问题:浅拷贝和深拷贝,堆栈问题,值类型和引用类型问题。
还可以通过序列化和反序列化进行深拷贝。
注意:string是引用类型,单比较特殊,原因在于string类型的不可变,每次赋值都是开辟新空间,替换引用,所以不会覆盖。不可变的原因是为了避免内存的频繁移动,然后又开启了享元模式。
4.3、开闭原则的理解
关键点:对扩展开放,对修改关闭。
场景:需要在旧功能上添加新功能,需要如何做?
思考:不能对旧的代码修改,需要在新的代码实现。
方案:1、使用继承。子类继承父类后override方法中添加新内容。
2、使用组合。用构造函数组合方式,添加新内容。
对比:组合优于继承【前辈们的总结】
为何组合优于继承?一般类与类的关系分为水平关系【非父子类】和垂直关系【父子类】。
水平关系:重点在UML建模中需要区分
- 依赖关系【Dependence】 :A类变化引起了B类的变化,则说明B类依赖于A类。
- 关联关系【Association】:两个类之间语义级别的一种强依赖关系。班级与学生等
- 聚合关注【Aggregation】:表示整体与部分的关系,整体与部分是可以分开的。车和发动机
- 组合关系:组合是关联关系的一种特殊,体现的事包含关系,比聚合更强,也称为强聚合。人与心脏。
垂直关系:【子类】继承和【接口】实现
强弱关系:结构型设计模式常规套路:组合优于继承
继承:最强关联。父类的一切都必须要带着,而且只能有一个父类,只能为一个父类服务。
继承相对简单,只有一个类。
组合:更灵活。OOP的,支持扩展。
会复杂些。会有多个类型。
从扩展性而言,组合更灵活,故而组合优于继承。项目中可以组合+继承来使用。
五、参考资料