簡述
- 型別:結構型
- 目的:降低物件創建時大量屬性也隨之被新建而帶來的性能上的消耗
話不多說,我們看一個案例,
優化案例
最初版v0
現在需要采購一批辦公用的電腦,以下是Computer類的定義,
class Computer {
private String sn; // 序列號,電腦的唯一識別碼
private String brand; // 品牌
private String title; // 一個系列的名稱,如Lenovo的Thinkpad
private String cpu;
private String memory;
private String disk;
private String gpu;
private String keyboard;
private String display;
public Computer(String sn, String brand,
String title, String cpu,
String memory, String disk,
String gpu, String keyboard,
String display) {
this.sn = sn;
this.brand = brand;
this.title = title;
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
this.gpu = gpu;
this.keyboard = keyboard;
this.display = display;
}
}
現在公司要采購兩種電腦總計1000臺,以下是模擬采購的代碼,
class Client {
public static void main(String[] args) {
List<Computer> purchase = new ArrayList<>();
for (int i = 0; i < n; i ++) {
purchase.add(new Computer(UUID.randomUUID().toString(),
"華為", "MateBook16", "銳龍7 5800H標壓",
"16GB DDR4 雙通道", "512GB NVMe PCle SSD",
"gpu", "全尺寸背光鍵盤", "16英寸");
}
}
}
回圈中每一次都要生成一個新的Computer物件,并且該物件中有很多String型別的屬性,因為String是一個參考資料型別,所以會隨之生成很多的參考,從而降低系統的性能,實際上,采購的計算機只要型號相同,配置引數也就隨之相同且不會再改變,唯一會改變的其實就只有機器的序列號而已,所以我們沒有每追加一臺電腦就重新設定一遍所有引數的必要,而且如果中途需要對于采購訂單的機器引數進行修改,那就必須迭代清單中的所有物件,對每個物件進行修改,又是一件效率低下的事,
為了解決這個問題,我們引入了享元模式,下面是修改后的代碼,
修改版v1
class Computer {
private String sn; // 序列號,電腦的唯一識別碼
private ComputerSpec spec; // 依賴規格的具體屬性 → 依賴ComputerSpec類,迪米特法則
public Computer(String sn, ComputerSpec spec) {
this.sn = sn;
this.spec = spec;
this.title = title;
this.model = model;
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
this.gpu = gpu;
this.keyboard = keyboard;
this.display = display;
}
}
enum ComputerSpec { // 定義一個計算機規格類
MATEBOOK16("華為", "MateBook16", "銳龍7 5800H標壓",
"16GB DDR4 雙通道", "512GB NVMe PCle SSD",
"gpu", "全尺寸背光鍵盤", "16英寸");
public String brand; // 品牌
public String title; // 一個系列的名稱,如Lenovo的Thinkpad
public String cpu;
public String memory;
public String disk;
public String gpu;
public String keyboard;
public String display;
ComputerSpec(String sn, String brand,
String title, String cpu,
String memory, String disk,
String gpu, String keyboard,
String display) {
this.brand = brand;
this.title = title;
this.model = model;
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
this.gpu = gpu;
this.keyboard = keyboard;
this.display = display;
}
}
來看看修改后的采購如何模擬實作,
class Client {
public static void main(String[] args) {
List<Computer> purchase = new ArrayList<>();
for (int i = 0; i < n; i ++) {
purchase.add(new Computer(UUID.randomUUID().toString(),
ComputerSpec.MATEBOOK16));
}
// 由于訂單錯誤,現在需要批量將MateBook16修改為MateBook16s
ComputerSpec.MATEBOOK16.title = "MateBook16s";
}
}
使用享元模式,將Computer物件創建時不變的屬性封裝到ComputerSpec中,內部狀態與外部狀態分開,內部狀態直接參考相同的資料源,而不是每次都重新生成新的資料,從而大幅提升系統性能,并且,需要對于資料統一修改時,由于資料源參考相同,只需要修改內部狀態的對應屬性即可修改所有資料,
- 內部狀態:不可變物件,被共享的資料,如,案例中的
ComputerSpec, - 外部狀態:隨著業務而改變資料,不被共享的資料,如,案例中的
sn,
總結
優點
- 由于多個物件的屬性參考相同,從而極大程度的降低了系統性能的消耗,
- 由于多個屬性被封裝成新的類,物件與屬性間的依賴減少,從而降低了物件創建的復雜度,
缺點
- 增加了開發人員對于系統業務理解的難度,
適用場景
- 當物件的絕大多數屬性與物件本身不是一對一而是一對多的關系時,換言之,多個物件公用一套屬性時,
本文來自博客園,作者:buzuweiqi,轉載請注明原文鏈接:https://www.cnblogs.com/buzuweiqi/p/16718920.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/509501.html
標籤:其他
