承接上文,我們繼續講道設計模式六大原則之心法----迪米特法原則。
什麼是迪米特法原則?
定義:一個對象應該對其他對象保持最少的瞭解。
心法要訣:即一個類應該儘量不要知道其他類太多的東西,不要和陌生的類有太多接觸。
核心要訣:低耦合,高內聚。
那麼迪米特法原則應用場景和招式是?
問題由來:類與類之間的關係越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。
解決方案:儘量降低類與類之間的耦合。
舉個栗子,通俗的講自從我們接觸編程開始,就知道了軟件編程的總的原則:低耦合,高內聚。無論是面向過程編程還是面向對象編程,只有使各個模塊之間的耦合儘量的低,才能提高代碼的複用率。低耦合的優點不言而喻,但是怎麼樣編程才能做到低耦合呢?那正是迪米特法則要去完成的。
代碼實現:
需求:有一個拖拉機生產廠,下屬單位有各種拖拉機生產分廠和直屬部門,現在要求打印出所有下屬分廠的拖拉機型號ID。
代碼一:違背迪米特法原則實現的代碼:
public class Function04 {
//測試輸出類
public static void main(String[] arg0){
TractorManager trac = new TractorManager();
trac.printAllSubTractor(new SubTractorManager());
}
}
//拖拉機總廠
class Tractor3{
private String tractorId;
public void setTractorId(String tractorId) {
this.tractorId = tractorId;
}
public String getTractorId() {
return tractorId;
}
}
//總廠拖拉機信息
class TractorManager{
public List<Tractor3> getTractorManager(){
List<Tractor3> list = new ArrayList<Tractor3>();
for (int i = 0 ; i <= 5 ; i++){
Tractor3 tractor3 = new Tractor3();
tractor3.setTractorId("總廠拖拉機型號:AT00X00"+i);
list.add(tractor3);
}
return list;
}
//輸出分廠的拖拉機型號
public void printAllSubTractor(SubTractorManager subTractor){
List<SubTractor> list1=subTractor.getTractorManager();
for (SubTractor sub : list1){
System.out.println(sub.getSubTractorId());
}
List<Tractor3> list2 = this.getTractorManager();
for (Tractor3 tractor : list2) {
System.out.println(tractor.getTractorId());
}
}
}
//分廠拖拉機
class SubTractor{
private String subTractorId;
public void setSubTractorId(String subTractorId) {
this.subTractorId = subTractorId;
}
public String getSubTractorId() {
return subTractorId;
}
}
//分廠拖拉機信息
class SubTractorManager{
public List<SubTractor> getTractorManager(){
List<SubTractor> list = new ArrayList<SubTractor>();
for (int i = 0 ; i <= 5 ; i++){
SubTractor subTractor = new SubTractor();
subTractor.setSubTractorId("分廠拖拉機型號:AT00X00" + i);
list.add(subTractor);
}
return list;
}
}
運行結果:
分廠拖拉機型號:AT00X000
分廠拖拉機型號:AT00X001
分廠拖拉機型號:AT00X002
分廠拖拉機型號:AT00X003
分廠拖拉機型號:AT00X004
分廠拖拉機型號:AT00X005
總廠拖拉機型號:AT00X000
總廠拖拉機型號:AT00X001
總廠拖拉機型號:AT00X002
總廠拖拉機型號:AT00X003
總廠拖拉機型號:AT00X004
總廠拖拉機型號:AT00X005
從邏輯上講總常只與他的分廠耦合就行了,與分廠的型號並沒有任何聯繫,這樣設計顯然是增加了不必要的耦合。按照迪米特法則,應該避免類中出現這樣非直接朋友關係的耦合。
代碼塊二:修改後的代碼如下:
public class Function04 {
//測試輸出類
public static void main(String[] arg0){
TractorManager trac = new TractorManager();
trac.printAllSubTractor(new SubTractorManager());
}
}
//拖拉機總廠
class Tractor3{
private String tractorId;
public void setTractorId(String tractorId) {
this.tractorId = tractorId;
}
public String getTractorId() {
return tractorId;
}
}
//總廠拖拉機信息
class TractorManager{
public List<Tractor3> getTractorManager(){
List<Tractor3> list = new ArrayList<Tractor3>();
for (int i = 0 ; i <= 5 ; i++){
Tractor3 tractor3 = new Tractor3();
tractor3.setTractorId("總廠拖拉機型號:AT00X00"+i);
list.add(tractor3);
}
return list;
}
//輸出分廠的拖拉機型號
public void printAllSubTractor(SubTractorManager subTractor){
subTractor.printAllSubTractor1();
List<Tractor3> list2 = this.getTractorManager();
for (Tractor3 tractor : list2) {
System.out.println(tractor.getTractorId());
}
}
}
//分廠拖拉機
class SubTractor{
private String subTractorId;
public void setSubTractorId(String subTractorId) {
this.subTractorId = subTractorId;
}
public String getSubTractorId() {
return subTractorId;
}
}
//分廠拖拉機信息
class SubTractorManager{
public List<SubTractor> getTractorManager(){
List<SubTractor> list = new ArrayList<SubTractor>();
for (int i = 0 ; i <= 5 ; i++){
SubTractor subTractor = new SubTractor();
subTractor.setSubTractorId("分廠拖拉機型號:AT00X00" + i);
list.add(subTractor);
}
return list;
}
//輸出分廠的拖拉機型號
public void printAllSubTractor1(){
List<SubTractor> list1=this.getTractorManager();
for (SubTractor sub : list1){
System.out.println(sub.getSubTractorId());
}
}
}
迪米特法則的初衷是降低類之間的耦合,由於每個類都減少了不必要的依賴,因此的確可以降低耦合關係。但是凡事都有度,雖然可以避免與非直接的類通信,但是要通信,必然會通過一個“中介”來發生聯繫,過分的使用迪米特原則,會產生大量這樣的中介和傳遞類,導致系統複雜度變大。所以在採用迪米特法則時要反覆權衡,既做到結構清晰,又要高內聚低耦合。