上一篇文章说了 工厂模式 和抽象工厂模式。本章简介java设计模式中的 单例模式 和建造者模式。
1:单例模式
单例模式是java设计模式中最简单模式之一。它只有一个实例对象,并且由该单例类自行创建实例,同时该单例类对外提供一个全局访问点。单例模式应用场景非常多,例如我们的操作系统Windows,任务管理器每次只能打开一个,操作系统中垃圾回收站,操作系统中文件系统、显卡驱动等等。在平时软件系统开发中,有应用程序日志对象、数据库连接池、网站计数器、交易所核心交易引擎等等,这些都常常被设计为单例。单例对象能保证在JVM中只有一个实例存在。可以减少系统内存开销,减少GC(垃圾回收)压力和减少像交易类型系统的混乱。

单例模式简介图
下面我们看一下单例类代码结构及简介:
单例模式有两种实现方式:一种是懒汉式单例,一种是饿汉式单例。
1)懒汉式单例模式设计
该设计模式特点是:类在加载的时候没有生成单例,只有在第一次调用 getlnstance 方法时才创建实例。代码如下:
public class LazySingleton
{
//保证 instance 在所有线程中同步
private static volatile LazySingleton instance=null;
//private 避免类在外部被 实例化
private LazySingleton(){
}
public static synchronized LazySingleton getInstance ()
{
//getInstance 方法前加同步
if(instance==null)
{
instance=new LazySingleton();
}
return instance;
}
}
注意事项 :上面代码一定要把关键字 volatile 和 synchronized 加上,否则会出现线程安全问题。加上同步关键词之后,会影响性能和消耗资源,但是为了系统的稳定性,加上volatile 和 synchronized同步关键词非常有必要。volatile 是稍弱的同步机制,在访问 volatile变量 时不会执行加锁操作,不会使执行线程阻塞,volatile变量是一种比sychronized关键字更轻量级的同步机制。
2)饿汉式单例设计模式
该设计模式特点:类在加载过程中就创建一个单例,在调用getInstance()之前实例就已经存在了。代码如下:
public class HungrySingleton
{
//私有静态,并且无法修改,当做常量使用
private static final HungrySingleton instance=new HungrySingleton();
private HungrySingleton(){}
//静态方法
public static HungrySingleton getInstance()
{
return instance;
}
}
注意事项 :饿汉式单例模式在创建单例时,已经创建好一个静态的对象,并且以后不再改变,所以是线程安全的,可以用于多线程中。
单例模式虽然简单,但是在实际应用当中还是有一定难度的。有些细节还得靠大家自己感悟替换。理解单例模式的特点加以运用。
2:建造者模式
建造者模式是将一个复杂对象的构造与它的表示分离开,使同样的构建过程创建不同的表示。它是将一个复杂的对象分解开,创建一个个简单的对象,然后再实现一个个简单对象。它将变与不变分离开,即产品的组成部分是不变的,但每一部分又可以灵活的选择。建造者模式的优点有:
1)主要优点:
- 各个具体的建造者相互独立,有利于系统的扩展。
- 客户端不必知道产品内部组成的细节,便于控制细节风险。
2)主要缺点:
- 产品的组成部分必须相同,这限制了其使用范围。
- 如果产品的内部变化复杂,该模式会增加很多的建造者类。
建造者模式的主要结构 :
- 产品角色:它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。
- 抽象 建造者:它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者:实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者:它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

结构图
实现代码如下:
(1) 产品角色:包含多个组成部件的复杂对象
public class Product {
/*
* 产品部分A、B、C
*/
private String partA;
private String partB;
private String partC;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
public void method() {
// 产品的特性
}
}
(2) 抽象建造者:包含创建产品各个子部件的抽象方法。
public abstract class Builder {
// 创建产品对象
protected Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
// 返回产品对象
public Product getResult() {
return product;
}
}
(3) 具体建造者:实现了抽象建造者接口。
public class ConcreteBuilder extends Builder {
public void buildPartA() {
product.setPartA(“建造 PartA”);
}
public void buildPartB() {
product.setPartA(“建造 PartB”);
}
public void buildPartC() {
product.setPartA(“建造 PartC”);
}
}
(4) 指挥者:调用建造者中的方法完成复杂对象的创建。
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
// 产品构建与组装方法
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
(5) 客户类。
public class Client {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
product.show();
}
}
建造者模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以通常在以下场合使用:
- 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
- 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
建造者模式将很多功能集成到一个类里,这个类可以创造出比较复杂的东西。应用过程中可以根据需要改变,如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色。
本章完结,下章待续
感谢您的阅读, 下一章节将简介 原型模式 和结构型模式中的 代理模式 等。如果您觉得对您有一丁点的帮助,请关注我,为我点赞,您的认可是我的动力。谢谢!