創(chuàng)建型模式 主要是用于產(chǎn)生類(lèi)實(shí)例,也就是new 對(duì)象
共五種:工廠方法模式羡微、抽象工廠模式、單例模式惶我、建造者模式妈倔、原型模式。
一.單例模式
1.一句話(huà)描述
- 確保一個(gè)類(lèi)只會(huì)生成一個(gè)實(shí)例绸贡,并提供一個(gè)全局訪問(wèn)點(diǎn)
2.實(shí)現(xiàn)方式
單例模式可以細(xì)分懶漢模式和餓漢模式兩種模式:
(1).懶漢模式
public class Singleton{
//使用volatile關(guān)鍵字防止重排序盯蝴,因?yàn)?new 實(shí)例是一個(gè)非原子操作
private volatile static Singleton singleton;
//私有構(gòu)造函數(shù)
private Singleton(){}
public static Singleton getSingleton(){
if(singleton==null){
//只對(duì)實(shí)例化代碼塊加鎖,提升性能
synchronized (Singleton.class){
if (singleton == null) { //雙重檢查
singleton = new Singleton();
}
}
}
return singleton;
}
}
在JDK1.4及更早版本的JAVA中,volatile關(guān)鍵字的實(shí)現(xiàn)會(huì)導(dǎo)致雙重檢查加鎖的失效
(2).餓漢模式
public class Singleton{
private static Singleton singleton = new Singleton();
//私有構(gòu)造函數(shù)
private Singleton(){}
public static Singleton getSingleton(){
return singleton;
}
}
利用JVM在加載完這個(gè)類(lèi)時(shí)听怕,馬上實(shí)例化唯一的實(shí)例捧挺,保證線(xiàn)程安全
實(shí)戰(zhàn)場(chǎng)景:
- Spring Bean 管理默認(rèn)就是一種單例模式
二、工廠模式
1.一句話(huà)描述
- 定義一個(gè)創(chuàng)建對(duì)象的接口,由子類(lèi)實(shí)例化具體對(duì)象,一個(gè)具體子類(lèi)對(duì)應(yīng)一種產(chǎn)品類(lèi)對(duì)象
2. 實(shí)現(xiàn)方式
(1) 簡(jiǎn)單工廠
class Juice{ }
class AppleJuice extends Juice{}
class PearJuice extends Juice{}
class JuiceStore{
public static Juice createJuice(String fruit) { //簡(jiǎn)單工廠方法, 新增產(chǎn)品類(lèi),需要修改工廠方法,不符合開(kāi)閉原則
if ("apple".equals(fruit)) {
return new AppleJuice();
} else if ("pear".equals(fruit)) {
return new PearJuice();
} else {
return null;
}
}
}
(2)工廠 方法
class Juice{ } //抽象產(chǎn)品類(lèi)
class AppleJuice extends Juice{} //具體產(chǎn)品類(lèi)
class PearJuice extends Juice{}
abstract class JuiceStore{ //抽象工廠類(lèi)
public abstract Juice createJuice();
}
class AppleStore extends JuiceStore { //具體產(chǎn)品類(lèi)
@Override
public Juice createJuice() {
return new AppleJuice();
}
}
class PearStore extends JuiceStore{//具體產(chǎn)品類(lèi)
@Override
public Juice createJuice() {
return new PearJuice();
}
}
3. 類(lèi)圖
4.總結(jié)
1.工廠模式相比簡(jiǎn)單工廠,加入了"開(kāi)閉原則", 創(chuàng)建工廠和 產(chǎn)品實(shí)現(xiàn)解耦
2.每增加一個(gè)產(chǎn)品實(shí)現(xiàn)類(lèi),要增加一個(gè)工廠創(chuàng)建類(lèi)
3.工廠模式 是抽象工廠的一個(gè)比較常見(jiàn)的情況
三尿瞭、抽象工廠模式
1.一句話(huà)描述
- 提供一個(gè)負(fù)責(zé)創(chuàng)建一組產(chǎn)品的接口松忍,接口內(nèi)每個(gè)方法由子類(lèi)負(fù)責(zé)創(chuàng)建一個(gè)具體產(chǎn)品
2.類(lèi)圖/實(shí)例
class Juice{}
class AppleJuice extends Juice{}
class IceAppleJuice extends AppleJuice { }
class CommonAppleJuice extends AppleJuice{}
class PearJuice extends Juice{}
class IcePearJuice extends PearJuice { }
class CommonPearJuice extends PearJuice{}
//超級(jí)工廠,包含兩個(gè)工廠方法
abstract class Store{
public abstract Juice createAppleJuice();
public abstract Juice createPearJuice();
}
class OneStore extends Store {
@Override
public Juice createAppleJuice() {
return new IceAppleJuice();
}
@Override
public Juice createPearJuice() {
return new IcePearJuice();
}
}
class TwoStore extends Store{
@Override
public Juice createAppleJuice() {
return new CommonAppleJuice();
}
@Override
public Juice createPearJuice() {
return new CommonPearJuice();
}
}
3.實(shí)戰(zhàn)案例
4.總結(jié)
1.在一個(gè)工廠里聚合多個(gè)同類(lèi)產(chǎn)品(同類(lèi)產(chǎn)品的不同系列)
2.簡(jiǎn)化產(chǎn)品族的交換
3.產(chǎn)品族要擴(kuò)展,需要修改所有工廠類(lèi),不易擴(kuò)展產(chǎn)品族
四、原型模式
1. 一句話(huà)描述
- 利用原對(duì)象快速?gòu)?fù)制一個(gè)對(duì)象
2.實(shí)戰(zhàn)案例
- Object 對(duì)象clone方法,本地方法默認(rèn)實(shí)現(xiàn)淺克隆
- Spring中原型bean的創(chuàng)建筷厘,就是原型模式的應(yīng)用
3.實(shí)現(xiàn)方式
分為淺克隆和深克隆
- 淺克旅汀:創(chuàng)建一個(gè)新對(duì)象,新對(duì)象的屬性和原來(lái)對(duì)象完全相同酥艳,對(duì)于非基本類(lèi)型屬性摊溶,仍指向原
有屬性所指向的對(duì)象的內(nèi)存地址, 也就是引用類(lèi)型指向的是同一個(gè)
// 實(shí)現(xiàn)Cloneable接口
public class InstanceClone implements Cloneable{
// ...省略
@Override
protected Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return clone;
}
}
- 深克隆:創(chuàng)建一個(gè)新對(duì)象充石,屬性中引用的其他對(duì)象也會(huì)被克隆莫换,不再指向原有對(duì)象地址。
//通過(guò)對(duì)象的序列化實(shí)現(xiàn)
public Object deepClone() {
//創(chuàng)建流
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis =null;
ObjectInputStream ois = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);//當(dāng)前的對(duì)象以流的方式輸出
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
InstanceClone deepClone = (InstanceClone )ois.readObject();
return deepClone ;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
}
也可以通過(guò)重寫(xiě)clone方法來(lái)實(shí)現(xiàn)深拷貝,但不推薦
4.總結(jié)
1.原型模式可以快速創(chuàng)建復(fù)雜對(duì)象,同時(shí)提高效率
2.需要在類(lèi)中實(shí)現(xiàn)克隆方法, 違背了OCP開(kāi)閉原則
五骤铃、建造者模式
1. 一句話(huà)描述
- 對(duì)復(fù)雜對(duì)象的組件創(chuàng)建以及組合進(jìn)行了抽取和拆分
2.類(lèi)圖
3. 實(shí)戰(zhàn)場(chǎng)景
- JDK中 StringBuilder
- MybatisPlus中的QueryWrapper對(duì)象的構(gòu)建
- Mybatis中用到的建造者模式:SqlSessionFactoryBuilder拉岁、XMLConfigBuilder、XMLMapperBuilder惰爬、XMLStatementBuilder喊暖、CacheBuilder等
4.總結(jié)
1.將復(fù)雜對(duì)象的創(chuàng)建步驟分解在不同的方法中,使得創(chuàng)建過(guò)程更加清晰,對(duì)象創(chuàng)建更加靈活
2.使用方不必知道對(duì)象內(nèi)部組成細(xì)節(jié),對(duì)象本身和對(duì)象創(chuàng)建過(guò)程解耦
3.如果對(duì)象內(nèi)部發(fā)生變化, 建造者都要修改,成本較大,適用于對(duì)象組成部分基本相同