走進設計模式的世界9:我們的公司很複雜-迭代器與組合模式
阿新 • • 發佈:2018-11-14
迭代器模式 :
提供一個方法順序訪問一個聚合物件中的各個元素,而又不暴露其內部表示。
組合模式 :
允許你將物件組成樹形結構來表現“整體/部分”的層次結構。組合能讓可以以一致的方式處理個別對象和物件組合。
設計原則:類應該只有一個改變的理由
解釋 : 迭代器允許訪問聚合的元素,而不需要暴露它的內部結構。迭代器將遍歷聚合的工作封裝進一個物件中。當使用迭代器的時候,我們依賴聚合提供遍歷。迭代器提供了一個通用的介面讓我們遍歷聚合的項,當我們編碼使用聚合的項時,就可以使用多型機制。我們應該努力讓一個類只分配一個責任。組合模式允許客戶對個別物件以及組合物件一視同仁。組合結構內的任意物件稱為元件,元件可以是組合,也可以是葉節點。在實現組合模式時,有許多設計上的折衷,你要根據需要平衡透明性和安全性。
迭代器模式樣例演示:我們有很多部門。
/** 我們公司有很多種部門 暫且拿出來行政部門和技術部門作比較 技術部門是拿array儲存的人員資訊,因為要控制人員薪資,控制人員的數量。 行政部門是拿ArrayList儲存的人員資訊,因為可以輕易的擴充套件資訊。 **/ /** 行政部門 **/ public class XingZhengDept{ ArrayList employees; public XingZhengDept{ employees = new ArrayList(); addEmployee("行政1",3500); addEmployee("行政2",3400); addEmployee("行政3",3300); } public void addEmployee(String name,double salary){ Employee e = new Employee(name,salary); employees.add(e); } public ArrayList getEmpItems(){ return employees; } } /** 技術部門 **/ public class JiShuDept{ Employee[] employees; int index = 0; static final int MAX = 3; public JiShuDept{ employees = new Employee[3]; addEmployee("技術1",3500); addEmployee("技術2",3400); addEmployee("技術3",3300); } public void addEmployee(String name,double salary){ Employee e = new Employee(name,salary); if(index<MAX){ employees[index]=e; index++; }else{ System.out.println("技術已經夠多了不能再加人了!!!!"); } } public Employee[] getEmpItems(){ return employees; } } /** 如果我想遍歷兩個部門的所有人員和薪資狀況, 我就分別關注兩個訂單的返回 **/ public class Test{ public static void main(String[]args){ JiShuDept jishu = new JiShuDept(); XingZhengDept xingzheng = new XingZhengDept(); Employee[] jishus = jishu.getEmpItems(); ArrayList xingzhengs = xingzheng.getEmpItems(); for(Employee e:xingzhengs){ System.out.println(e); } for(Employee e:jishus){ System.out.println(e); } } }
這時候負責統計的類就分別依賴了員工list和員工陣列。接下來我們用迭代器改造這兩個部分。
/** 先做一個技術部的迭代器 **/ public class JiShuDeptIterator implements Iterator{ Employee[] employees; int index = 0; public JiShuDeptIterator (Employee[] employees){ this.employees = employees; } public Object next(){ Employee e = employees[index]; index++; return e; } public boolean hasNext(){ if(index>=employees.length||employess[index]==null){ return false; }else{ return true; } } } /** 技術部門 **/ public class JiShuDept{ Employee[] employees; int index = 0; static final int MAX = 3; public JiShuDept{ employees = new Employee[3]; addEmployee("技術1",3500); addEmployee("技術2",3400); addEmployee("技術3",3300); } public void addEmployee(String name,double salary){ Employee e = new Employee(name,salary); if(index<MAX){ employees[index]=e; index++; }else{ System.out.println("技術已經夠多了不能再加人了!!!!"); } } /** 因為需要使用迭代器模式,所以這種遍歷的方法棄用了。 **/ public Employee[] getEmpItems(){ return employees; } /** 返回一個迭代器。 **/ public Iterator createIterator(){ return new JiShuDeptIterator(employees); } } /** 由於行政部門是用list儲存的所以不需要迭代器 **/ public class XingZhengDept{ ArrayList employees; public XingZhengDept{ employees = new ArrayList(); addEmployee("行政1",3500); addEmployee("行政2",3400); addEmployee("行政3",3300); } public void addEmployee(String name,double salary){ Employee e = new Employee(name,salary); employees.add(e); } /** 因為需要使用迭代器模式,所以這種遍歷的方法棄用了。 **/ public ArrayList getEmpItems(){ return employees; } /** 返回一個迭代器。 **/ public Iterator createIterator(){ return employees.iterator(); } } public class Test{ public static void main(String[]agrs){ // 建立行政部門 XingZhengDept xingzheng = new XingZhengDept(); // 建立技術部門 JiShuDept jishu = new JiShuDept(); // 列印行政部門資訊 printEmp(xingzheng.createIterator()); // 列印技術部門資訊 printEmp(jishu.createIterator()); } /** 列印員工資訊 **/ public void printEmp(Iterator iterator){ while(iterator.hasNext()){ Employee e = (Employee)iterator.next(); System.out.println("員工:"+e.getName()); System.out.println("薪資:"+e.getSalary()); } } }
按照如上改造,兩個部門被改造成了迭代器模式。那組合模式又是什麼樣的呢?????
/**
情景如下:
我們公司有三個大的部門
1.營銷部
2.技術部
3.行政部
營銷部直屬一個經理,和兩個營銷部長。
營銷部下轄營銷一部和營銷二部。
接下來我們看如何設計。
**/
//首先我們把部門和員工都抽象成公司成員的一部分
public abstract class Member{
// 定義公有的方法新增員工/部門
public void add(Member m){
throw new Exception("未新增實現");
}
public Member getChild(int i){
throw new Exception("未新增實現");
}
public String getName(){
throw new Exception("未新增實現");
}
public double getSalary(){
throw new Exception("未新增實現");
}
public void print(){
throw new Exception("未新增實現");
}
}
/**
員工類
**/
public class Emp extends Member{
// 名稱
private String name;
// 薪資
private double salary;
// 構造方法
public Emp(String name,double salary){
this.name = name;
this.salary = salary;
}
// 重寫getName方法
public String getName(){
return name;
}
// 重寫getSalary方法
public double getSalary(){
return salary;
}
// 重寫print方法
public void print(){
System.out.println("名字:"+name);
System.out.println("薪水:"+salary);
}
}
/**
部門類
**/
public class Dept extends Members{
ArrayList members;
String deptName;
// 構造方法
public Dept (String deptName){
this.deptName = deptName;
}
// 重寫getChild方法
public Member getChild(int i){
return (Member)members.get(i);
}
// 重寫print方法
public void print(){
System.out.println("部門為:"+deptName);
System.out.println("--------------------------------------");
}
}
把部門和員工都放到一個門類下,這樣便利的時候只需要根據不同的種類去判斷就可以了。