设计模式的艺术读书笔记
设计模式的艺术
面向对象设计原则概述
单一职责原则
单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。单一职责原则定义如下:
单一职责原则(Single Responsibility Principle,SRP):一个类只负责一个功能领域中的相应职责。或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。
单一职责原则的核心思想是:一个类不能太“累”!在软件系统中,一个类(大到模块,小到方法)承担的职责越多,它被复用的可能性就越小,而且一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。因此要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中;如果多个职责总是同时发生改变,则可将它们封装在同一类中。
开闭原则
开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。开闭原则由Bertrand Meyer于1988年提出,其定义如下:
开闭原则(Open-Closed Principle,OCP):一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
里氏代换原则
其严格表述如下:如果对每个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换o2时,程序P的行为没有变化,那么类型S是类型T的子类型。这个定义比较拗口且难以理解,因此一般使用它的另一个通俗版定义:
里氏代换原则(Liskov Substitution Principle,LSP):所有引用基类(父类)的地方必须能透明地使用其子类的对象。
在运用里氏代换原则时,应该将父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法。程序运行时,子类实例替换父类实例,可以很方便地扩展系统的功能,无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。
依赖倒转原则
依赖倒转原则(Dependency Inversion Principle,DIP):抽象不应该依赖于细节,细节应该依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。
接口隔离原则
接口隔离原则(Interface Segregation Principle,ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
合成复用原则
合成复用原则(Composite Reuse Principle,CRP):尽量使用对象组合,而不是继承来达到复用的目的。(继承更容易引起来复杂性,而且Java单继承的也有限制)
迪米特法则
迪米特法则(Law of Demeter,LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。
如果一个系统符合迪米特法则,那么当其中某一个模块发生修改时,就会尽量少地影响其他模块,扩展会相对容易。这是对软件实体之间通信的限制。迪米特法则要求限制软件实体之间通信的宽度和深度。迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系。
创建的艺术
创建型模式
创建型模式(Creational Pattern)关注对象的创建过程,是一类最常用的设计模式,在软件开发中应用非常广泛。创建型模式将对象的创建和使用分离,在使用对象时无须关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修改和扩展。每个创建型模式都通过采用不同的解决方案来回答3个问题:创建什么(What),由谁创建(Who)和何时创建(When)。
单例模式
单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
饿汉式单例与懒汉式单例的讨论
饿汉式单例就是类加载的时候直接创建,由类加载的机制确保线程安全性。
懒汉式单例是用到的时候再去创建,不过要确保线程安全性:
假如某一瞬间线程A和线程B都在调用getInstance()方法,此时instance对象为null值,均能通过“instance==null”的判断。由于实现了synchronized加锁机制,线程A进入synchronized锁定的代码中执行实例创建代码,线程B处于排队等待状态,必须等待线程A执行完毕后才可以进入synchronized锁定代码。但当A执行完毕时,线程B并不知道实例已经创建,将继续创建新的实例,导致产生多个单例对象,违背单例模式的设计思想。因此需要进行进一步改进,在synchronized锁定代码中再进行一次“instance==null”判断,这种方式称为双重检查锁定(Double-Check Locking),代码示例如下:
通过静态内部类实现的更好办法
饿汉式单例类不能实现延迟加载,不管将来用不用,它始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题。有没有一种方法,能够将两种单例的缺点都克服,而将两者的优点合二为一呢?答案是肯定的。下面来学习这种更好的被称为**Initialization on Demand Holder(IoDH)**的技术。
实现IoDH时,需在单例类中增加一个静态(static)内部类,在该内部类中创建单例对象,再将该单例对象通过getInstance()方法返回给外部使用,实现代码如下:
简单工厂模式
原文地址:https://blog.csdn.net/qq_39084776/article/details/144333032
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!