面向对象OOP的七大原则:
设计模式参考网站:[http://c.biancheng.net/view/1317.html**](http://c.biancheng.net/view/1317.html)
1.单例模式
核心作用:保证一个类只有一个实例,并且提供一个访问该实例的 全局访问点
核心思想:构造器私有。
注意:反射可破解单例模式
优点:
- 单例模式可以保证内存里只有一个实例,减少了内存的开销。
- 可以避免对资源的多重占用。
- 单例模式设置全局访问点,可以优化和共享资源的访问。
缺点:
- 单例模式一般没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。
- 在并发测试中,单例模式不利于代码调试。在调试过程中,如果单例中的代码没有执行完,也不能模拟生成一个新的对象。
- 单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。
1.1 懒汉式
```java //非线程安全 public class Singleton { private static Singleton instance; private Singleton (){ } public static Singleton getInstance() {
} } //线程安全 public class Singleton { private static Singleton instance; private Singleton (){ } public static synchronized Singleton getInstance() {if (instance == null) {
instance = new Singleton();
}
return instance;
} }if (instance == null) {
instance = new Singleton();
}
return instance;
// 多线程安全的最终解决: volation+synchronized 双端检锁机制 public class Singleton { private static volatile Singleton instance = null;
private Singleton(){
System.out.pritln("构造方法执行一次");
}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
<a name="kceRU"></a>
## 1.2 饿汉式
注意:可能会造成空间浪费
```java
public class Singleton{
//类加载时就初始化
private static final Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
2.工厂模式
作用:实现了创建者和调用者分离
详细分类:
- 简单工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要扩展已有代码)
- 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂模式:围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
小结:
- 简单工厂模式:虽然某种程度上不符合设计原则,但实际使用最多
- 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展
- 抽象工厂模式:不可以增加产品,可以增加产品族
应用场景:
- jdk中calendar的getInstance方法
- JDBC中的Connection对象的获取
- Spring中的IOC容器创建管理bean对象
- 反射中Class对象的newInstance方法
3.建造者模型
它提供了一种创建对象的最佳方式
定义:将一个复杂对象的构建与它的使用分离,使得同样的构建过程可以创建不同的表示
主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
用户只需要给出指定复杂对象的类型和内容,建造者负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
优点:
- 产品的建造和表示分离,实现了解耦。使用建造者模式可以使客户端不必知道产品内部组成的细节
- 将复杂产品的创建步骤分解在不同的方法中,是得创建过程更加清晰
- 具体的建造者之间是相互独立的,这有利于系统的扩展。增加新的具体建造者无需修改原有类库代码,符合“开闭原则”
缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;
- 如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变的很庞大
4.原型模式
概述:通过拷贝原型创建新的对象
应用场景:
- 对象之间相同或相似,即只是个别的几个属性不同的时候。
- 创建对象成本较大,例如初始化时间长,占用CPU太多,或者占用网络资源太多等,需要优化资源。
- 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性。
- 系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值。
优点:
- Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:
- 需要为每一个类都配置一个 clone 方法
- clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
- 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。
原型模式的克隆分为浅克隆和深克隆:
- 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
- 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
原型模式包含以下主要角色:
- 抽象原型类:规定了具体原型对象必须实现的接口
- 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象
- 访问类:使用具体原型类中的 clone() 方法来复制新的对象
结构图:
//具体原型类
class Realizetype implements Cloneable {
Realizetype() {
System.out.println("具体原型创建成功!");
}
public Object clone() throws CloneNotSupportedException {
System.out.println("具体原型复制成功!");
return (Realizetype) super.clone();
}
}
//原型模式的测试类
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Realizetype obj1 = new Realizetype();
Realizetype obj2 = (Realizetype) obj1.clone();
System.out.println("obj1==obj2?" + (obj1 == obj2));
}
}
5.设配器模式
概述:将原来不兼容的两个类融合在一起
作用:从程序的结构上实现松耦合, 从而可以扩大整体的类结构,用来解决更大的问题
6.桥接模式
定义:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。