設計模式之——visitor模式


    visitor模式,又叫訪問者模式,把結構和數據分開,編寫一個訪問者,去訪問數據結構中的元素,然后把對各元素的處理全部交給訪問者類。這樣,當需要增加新的處理時候,只需要編寫新的 訪問者類,讓數據結構可以接受訪問者的訪問即可。

    本次,我們以電腦裝機為例。需求是,想組裝一台電腦,有三個硬件,顯卡,CPU和硬盤,想裝進電腦主機箱里面,只能采取接口的方式。首先我們假設使用的是usb接口去連接。

image

    下面是具體的代碼:因為要表現出接口可換的概念,我采用的是將電腦硬件和電腦本身的類以及接口的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());
    }
    
}
  • 控制台輸出結果

image

由此可見,visitor模式以及測試成功。

visitor模式的一大特點就是,結構是固定死的,你是不能改的,但你可以改一些結構的實現方式,即上述實例中的usb接口,你可以換成其他接口比如PCI……只要實現規定好的硬件接口interface類即可,這樣一來,任憑怎么擴展,都不會修改到底層的結構,不會損壞“框架”了。

不過,這也算是最大的缺點。就是不能擴展里面的內容,就上述內容來說,只能擴展接口,而不能擴展里面硬件,或者修改電腦硬件的實現方式!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM