- 和对象的创建有关。
- 一般就是单例模式、工厂方法模式、 抽象工厂模式、建造者模式、原型模式。
- 下面分别介绍单例模式、简单工厂模式、工厂方法模式和建造者模式
6.3.1 单例模式
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 单例模式的六种写法
1. 饿汉模式
- 这种方法在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。
- 这种方法基于类加载机制,避免了多线程的同步问题。在类加载时就完成实例化,没有达到懒加载的效果。
- 没有使用过这个实例,则会造成内存的浪费。
package com.example.mode;
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
2. 懒汉模式(线程不安全)
- 第一次加载时需要通过静态方法进行实例化,所以反应稍慢,而且在多线程情况下不能正常工作。
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
3. 懒汉模式(线程安全)
- 每次调用getInstance方法的时候需要同步,这会造成同步开销
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
4. 双重检查模式(DCL)
- 这种写法在getInstance方法进行了两次判空
- 第一次是为了不必要的同步,第二次是在Singleton为null的情况下才创建实例。
package com.example.mode;
public class Singleton {
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
5. 静态内部类单例模式
package com.example.mode;
public class Singleton {
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder{
private static final Singleton sInstance = new Singleton();
}
}
6. 枚举单例
6.3.2 简单工厂模式
- 简单工厂模式又叫做静态工厂方法模式,其属于创建型设计模式,但不属于GoF设计模式。
- 定义:简单工厂模式属于创建型模式,由一个工厂对象决定创建出哪一种产品类的实例。
1. 简单工厂模式的简单实现
- 抽象产品类
package com.example.mode;
public abstract class Computer {
//产品的抽象方法,由具体的产品类来实现
public abstract void start();
}
- 具体产品类
- 接着我们创建各个品牌的计算机,都继承父类Computer,并实现start方法
public class LenovoComputer extends Computer{
@Override
public void start() {
System.out.println("联想计算机启动");
}
}
public class HpComputer extends Computer{
@Override
public void start() {
System.out.println("惠普计算机启动");
}
}
public class AsusComputer extends Computer{
@Override
public void start() {
System.out.println("华硕计算机启动");
}
}
- 工厂类
- 创建一个工厂类,他提供了一个静态方法createComputer来生产计算机
package com.example.mode;
public class ComputerFactory {
public static Computer createComputer(String type){
Computer mComputer = null;
switch (type){
case "lenovo":
mComputer = new LenovoComputer();
break;
case "hp":
mComputer = new HpComputer();
break;
case "asus":
mComputer = new AsusComputer();
break;
}
return mComputer;
}
}
- 客户端调用工厂类
- 调用工厂类
package com.example.mode;
public class Client {
public static void main(String[] args) {
ComputerFactory.createComputer("hp").start();
}
}
6.3.3 工厂方法模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
1. 创建抽象工厂
- 想生产哪个品牌的计算机就生产哪个品牌的
package com.example.mode;
public abstract class ComputerFactory2 {
public abstract <T extends Computer> T createComputer(Class<T> clz);
}
2. 具体工厂
- 广迭代工场是一个具体的工厂,其继承抽象工厂,通过反射来生产不同厂家的计算机
package com.example.mode;
public class GDComputerFactor extends ComputerFactory2{
@Override
public <T extends Computer> T createComputer(Class<T> clz) {
Computer computer = null;
String className = clz.getName();
try{
//通过反射机制来生产不同厂家的计算机
computer = (Computer) Class.forName(className).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return (T) computer;
}
}
3. 客户端调用
- 客户端创建了GDComputerFactory分别生产计算机
package com.example.mode;
public class Client2 {
public static void main(String[] args) {
ComputerFactory2 computerFactory2 = new GDComputerFactor();
LenovoComputer mLenovoComputer = computerFactory2.createComputer(LenovoComputer.class);
mLenovoComputer.start();
HpComputer mHpComputer = computerFactory2.createComputer(HpComputer.class);
mHpComputer.start();
AsusComputer mAsusComputer = computerFactory2.createComputer(AsusComputer.class);
mAsusComputer.start();
}
}
6.3.4 建造者模式
- 定义:将一个复杂的对象构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 建造者模式的简单实现
- 这里我们用DIY组装计算机的例子来实现一下建造者模式。
1. 创建产品类
package com.example.mode2;
public class Computer {
private String mCPU;
private String mMainBoard;
private String mRAM;
public String getmCPU() {
return mCPU;
}
public String getmMainBoard() {
return mMainBoard;
}
public String getmRAM() {
return mRAM;
}
public void setmCPU(String mCPU) {
this.mCPU = mCPU;
}
public void setmMainBoard(String mMainBoard) {
this.mMainBoard = mMainBoard;
}
public void setmRAM(String mRAM) {
this.mRAM = mRAM;
}
}
2. 创建Builder类规范产品的组建
- 商家组装计算机有一套组长方法的模版,这就是抽象的Builder类。
- 里面通了安装CPU、主板和内存的方法,以及组装成计算机的create方法
package com.example.mode2;
public abstract class Builder {
public abstract void buildCPU(String cpu);
public abstract void buildMainBoard(String mainboard);
public abstract void buildRAM(String ram);
public abstract Computer create();
}
3. 商家实现了Builder类
package com.example.mode2;
public class MoonComputerBuilder extends Builder{
private Computer mComputer = new Computer();
@Override
public void buildCPU(String cpu) {
mComputer.setmCPU(cpu);
}
@Override
public void buildMainBoard(String mainboard) {
mComputer.setmMainBoard(mainboard);
}
@Override
public void buildRAM(String ram) {
mComputer.setmRAM(ram);
}
@Override
public Computer create() {
return mComputer;
}
}
4. 用导演类统一组装过程
- 商家的导演类用来规范组装计算机的流程规范,先安装主板,再安装CPU,最后安装内存并组成计算机。
package com.example.mode2;
public class Director {
Builder mBuilder = null;
public Director(Builder builder){
this.mBuilder = builder;
}
public Computer createComputer(String cpu , String mainboard , String ram){
//规范建造流程
this.mBuilder.buildMainBoard(mainboard);
this.mBuilder.buildCPU(cpu);
this.mBuilder.buildRAM(ram);
return mBuilder.create();
}
}
5. 客户端调用导演类
- 最后商家用导演类来组装计算机,我们只需要提供自己想要的CPU、主板和内存就可以了,至于商家怎么组装计算机我们无需知道。
package com.example.mode2;
public class CreateComputer {
public static void main(String[] args) {
Builder mBuilder = new MoonComputerBuilder();
Director mDirector = new Director(mBuilder);
mDirector.createComputer("i7-6700" , "华擎玩家至尊","三星DDR4");
}
}