visitor模式,又叫訪問者模式,把結構和數據分開,編寫一個訪問者,去訪問數據結構中的元素,然后把對各元素的處理全部交給訪問者類。這樣,當需要增加新的處理時候,只需要編寫新的 訪問者類,讓數據結構可以接受訪問者的訪問即可。
本次,我們以電腦裝機為例。需求是,想組裝一台電腦,有三個硬件,顯卡,CPU和硬盤,想裝進電腦主機箱里面,只能采取接口的方式。首先我們假設使用的是usb接口去連接。
下面是具體的代碼:因為要表現出接口可換的概念,我采用的是將電腦硬件和電腦本身的類以及接口的interface接口類放到一個包里面,設定這個包為框架包,是不允許修改的。
在框架包中
- ComputerPart硬件的父類,抽象類
package site.wangxin520.gof.visitor.framework; /** * 電腦的零配件的父抽象類 * @author wangXgnaw * */ public abstract class ComputerPart { /** * 所有的 零配件,都必須通過一個硬件接口進行連接 * @param hardwareInterface */ protected abstract void link(HardwareInterface hardwareInterface); }
- 硬件的實現類CPU,下同
package site.wangxin520.gof.visitor.framework; /** * 電腦的硬件CPU,用於數據的運算 * * @author wangXgnaw * */ public class CPU extends ComputerPart { @Override protected void link(HardwareInterface hardwareInterface) { // 先得通過接口連接數據 hardwareInterface.visitor(this); // 連接完了之后,就開始使用cpu System.out.println("連接上了之后,利用cpu進行計算數據"); } }
- 顯卡VideoCard
package site.wangxin520.gof.visitor.framework; /** * 電腦硬件之顯卡 通過顯卡可以進行電腦的屏幕圖像的顯示 * * @author wangXgnaw * */ public class VideoCard extends ComputerPart { @Override protected void link(HardwareInterface hardwareInterface) { // 必須先用接口連接上顯卡 hardwareInterface.visitor(this); System.out.println("連接上顯卡之后,顯卡開始工作,提供圖像"); } }
- 硬盤HardDisk
package site.wangxin520.gof.visitor.framework; /** * 電腦硬件之硬盤 * * @author wangXgnaw * */ public class HardDisk extends ComputerPart { @Override protected void link(HardwareInterface hardwareInterface) { // 必須先通過接口,把硬盤先連上,然后才能操作 hardwareInterface.visitor(this); // 硬盤開始干活 System.out.println("硬盤以及連接上了,開始存儲數據"); } }
- Computer,電腦(主機箱)類
package site.wangxin520.gof.visitor.framework; /** * 電腦的類,當需要裝機的話,就先准備好硬件,即new出來,然后插上接口 * @author wangXgnaw * */ public class Computer { /** * 想裝機,先得提供硬件接口才行 * @param hardwareInterface */ public void useComputer(HardwareInterface hardwareInterface){ //通過接口,連接cpu new CPU().link(hardwareInterface); //通過接口,連接顯卡 new VideoCard().link(hardwareInterface); //通過接口連接硬盤 new HardDisk().link(hardwareInterface); } }
- 硬件的接口類
package site.wangxin520.gof.visitor.framework; /** * 硬件的接口 * @author wangXgnaw * */ public interface HardwareInterface { //定義了一些接口,訪問硬件用的 public void visitor(CPU cpu); public void visitor(VideoCard vCard); public void visitor(HardDisk hd); }
把上面的框架包封裝起來,因為訪問者模式要求,結構不能變化,只能變化數據操作上。
下面是可操作的包的內容:
- 自定義的接口類
package site.wangxin520.gof.visitor.use; import site.wangxin520.gof.visitor.framework.CPU; import site.wangxin520.gof.visitor.framework.HardDisk; import site.wangxin520.gof.visitor.framework.HardwareInterface; import site.wangxin520.gof.visitor.framework.VideoCard; /** * 自定義的接口,實現了硬件接口的借口類 * @author wangXgnaw * */ public class USBInterface implements HardwareInterface{ @Override public void visitor(CPU cpu) { System.out.println("usb連接cpu"); } @Override public void visitor(VideoCard vCard) { System.out.println("用usb連接顯卡"); } @Override public void visitor(HardDisk hd) { System.out.println("用usb連接硬盤"); } }
- 測試類
package site.wangxin520.gof.visitor.use; import site.wangxin520.gof.visitor.framework.Computer; /** * 訪問者模式的測試類 * @author wangXgnaw * */ public class Test { public static void main(String[] args) { //想要裝機,先得裝電腦的架子 Computer computer=new Computer(); //有架子后,就想着用什么接口去裝電腦,這里是用usb接口去連接里面的硬件的。當然,也可以去換成其他接口 computer.useComputer(new USBInterface()); } }
- 控制台輸出結果
由此可見,visitor模式以及測試成功。
visitor模式的一大特點就是,結構是固定死的,你是不能改的,但你可以改一些結構的實現方式,即上述實例中的usb接口,你可以換成其他接口比如PCI……只要實現規定好的硬件接口interface類即可,這樣一來,任憑怎么擴展,都不會修改到底層的結構,不會損壞“框架”了。
不過,這也算是最大的缺點。就是不能擴展里面的內容,就上述內容來說,只能擴展接口,而不能擴展里面硬件,或者修改電腦硬件的實現方式!