話不多說,我們看一個案例。
現在需要採購一批辦公用的電腦,以下是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是一個參照資料型別,所以會隨之生成很多的參照,從而降低系統的效能。實際上,採購的計算機只要型號相同,設定引數也就隨之相同且不會再改變,唯一會改變的其實就只有機器的序列號而已,所以我們沒有每追加一臺電腦就重新設定一遍所有引數的必要。而且如果中途需要對於採購訂單的機器引數進行修改,那就必須迭代清單中的所有物件,對每個物件進行修改,又是一件效率低下的事。
為了解決這個問題,我們引入了享元模式。下面是修改後的程式碼。
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