1. 程式人生 > 實用技巧 >java基礎-----設計模式(3)

java基礎-----設計模式(3)

//1個Observer介面:
public interface Observer {
    public void update();
}

//兩個實現類:
public class Observer1 implements Observer {

    @Override
    public void update() {
        System.out.println("observer1 has received!");
    }
}
public class Observer2 implements Observer {

    @Override
    public void
update() { System.out.println("observer2 has received!"); } } //Subject介面及實現類: public interface Subject { /*增加觀察者*/ public void add(Observer observer); /*刪除觀察者*/ public void del(Observer observer); /*通知所有的觀察者*/ public void notifyObservers(); /*自身的操作
*/ public void operation(); } public abstract class AbstractSubject implements Subject { private Vector<Observer> vector = new Vector<Observer>(); @Override public void add(Observer observer) { vector.add(observer); } @Override public void del(Observer observer) { vector.remove(observer); } @Override
public void notifyObservers() { Enumeration<Observer> enumo = vector.elements(); while(enumo.hasMoreElements()){ enumo.nextElement().update(); } } } public class MySubject extends AbstractSubject { @Override public void operation() { System.out.println("update self!"); notifyObservers(); } } //測試類: public class ObserverTest { public static void main(String[] args) { Subject sub = new MySubject(); sub.add(new Observer1()); sub.add(new Observer2()); sub.operation(); } } /*update self! observer1 has received! observer2 has received!*/

行為型模式

行為型模式包括策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式

模式與模式之間的關係:

    第一類:通過父類與子類的關係進行實現。第二類:兩個類之間。第三類:類的狀態。第四類:通過中間類

一、策略模式

  策略模式定義了一系列演算法,並將每個演算法封裝起來,使他們可以相互替換,且演算法的變化不會影響到使用演算法的客戶,需要設計一個介面為一系列實現類提供統一的方法,多個實現類試下該介面。設計一個抽象類做服裝類,提供輔助函式

//統一介面:
public interface ICalculator {
    public int calculate(String exp);
}

//輔助類:
public abstract class AbstractCalculator {
    
    public int[] split(String exp,String opt){
        String array[] = exp.split(opt);
        int arrayInt[] = new int[2];
        arrayInt[0] = Integer.parseInt(array[0]);
        arrayInt[1] = Integer.parseInt(array[1]);
        return arrayInt;
    }
}

//三個實現類:
public class Plus extends AbstractCalculator implements ICalculator {

    @Override
    public int calculate(String exp) {
        int arrayInt[] = split(exp,"\\+");
        return arrayInt[0]+arrayInt[1];
    }
}
public class Minus extends AbstractCalculator implements ICalculator {

    @Override
    public int calculate(String exp) {
        int arrayInt[] = split(exp,"-");
        return arrayInt[0]-arrayInt[1];
    }

}
public class Multiply extends AbstractCalculator implements ICalculator {

    @Override
    public int calculate(String exp) {
        int arrayInt[] = split(exp,"\\*");
        return arrayInt[0]*arrayInt[1];
    }
}

//簡單的測試類:
public class StrategyTest {

    public static void main(String[] args) {
        String exp = "2+8";
        ICalculator cal = new Plus();
        int result = cal.calculate(exp);
        System.out.println(result); //10

    }
}

  策略模式的決定權在使用者,系統本身提供不同演算法的實現,新增或者刪除演算法,對各種演算法做封裝。因此,策略模式多用在演算法決策系統中,外部使用者只需要決定用哪個演算法即可。

二、模板方法模式

  一個抽象類中,有一個主方法,再定義1...n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過呼叫抽象類,實現對子類的呼叫

public abstract class AbstractCalculator {
    
    /*主方法,實現對本類其它方法的呼叫*/
    public final int calculate(String exp,String opt){
        int array[] = split(exp,opt);
        return calculate(array[0],array[1]);
    }
    
    /*被子類重寫的方法*/
    abstract public int calculate(int num1,int num2);
    
    public int[] split(String exp,String opt){
        String array[] = exp.split(opt);
        int arrayInt[] = new int[2];
        arrayInt[0] = Integer.parseInt(array[0]);
        arrayInt[1] = Integer.parseInt(array[1]);
        return arrayInt;
    }
}
public class Plus extends AbstractCalculator {

    @Override
    public int calculate(int num1,int num2) {
        return num1 + num2;
    }
}

//測試類:
public class StrategyTest {

    public static void main(String[] args) {
        String exp = "8+8";
        AbstractCalculator cal = new Plus();
        int result = cal.calculate(exp, "\\+");
        System.out.println(result);
    }
}

三、觀察者模式

當一個物件變化時,其它依賴該物件的物件都會收到通知,並且隨著變化,物件之間是一種一對多的關係

  MySubject類就是我們的主物件,Observer1和Observer2是依賴於MySubject的物件,當MySubject變化時,Observer1和Observer2必然變化。AbstractSubject類中定義著需要監控的物件列表,可以對其進行修改:增加或刪除被監控物件,且當MySubject變化時,負責通知在列表記憶體在的物件

四、迭代子模式

  順序訪問聚集中的物件,一是需要遍歷的物件,即聚集物件,二是迭代器物件,用於對聚集物件進行遍歷訪問

//集合介面
public interface Collection {
    
    public Iterator iterator();
    
    /*取得集合元素*/
    public Object get(int i);
    
    /*取得集合大小*/
    public int size();
}
//迭代器介面
public interface Iterator {
    //前移
    public Object previous();
    
    //後移
    public Object next();
    public boolean hasNext();
    
    //取得第一個元素
    public Object first();
}

//兩個實現:
public class MyCollection implements Collection {

    public String string[] = {"A","B","C","D","E"};
    @Override
    public Iterator iterator() {
        return new MyIterator(this);
    }

    @Override
    public Object get(int i) {
        return string[i];
    }

    @Override
    public int size() {
        return string.length;
    }
}

public class MyIterator implements Iterator {

    private Collection collection;
    private int pos = -1;
    
    public MyIterator(Collection collection){
        this.collection = collection;
    }
    
    @Override
    public Object previous() {
        if(pos > 0){
            pos--;
        }
        return collection.get(pos);
    }

    @Override
    public Object next() {
        if(pos<collection.size()-1){
            pos++;
        }
        return collection.get(pos);
    }

    @Override
    public boolean hasNext() {
        if(pos<collection.size()-1){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Object first() {
        pos = 0;
        return collection.get(pos);
    }

}

//測試類:
public class Test {

    public static void main(String[] args) {
        Collection collection = new MyCollection();
        Iterator it = collection.iterator();
        
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

//A B C D E

五、責任鏈模式

  有多個物件,每個物件持有對下一個物件的引用,這樣就會形成一條鏈,請求在這條鏈上傳遞,直到某一物件決定處理該請求。但是發出者並不清楚到底最終那個物件會處理該請求,所以,責任鏈模式可以實現,在隱瞞客戶端的情況下,對系統進行動態的調整。

public interface Handler {
    public void operator();
}

public abstract class AbstractHandler {
    
    private Handler handler;

    public Handler getHandler() {
        return handler;
    }

    public void setHandler(Handler handler) {
        this.handler = handler;
    }
    
}

public class MyHandler extends AbstractHandler implements Handler {

    private String name;

    public MyHandler(String name) {
        this.name = name;
    }

    @Override
    public void operator() {
        System.out.println(name+"deal!");
        if(getHandler()!=null){
            getHandler().operator();
        }
    }
}
public class Test {

    public static void main(String[] args) {
        MyHandler h1 = new MyHandler("h1");
        MyHandler h2 = new MyHandler("h2");
        MyHandler h3 = new MyHandler("h3");

        h1.setHandler(h2);
        h2.setHandler(h3);

        h1.operator();
    }
}

//h1deal!
//h2deal!
//h3deal!

六、命令模式

  只關注指令執行的結果,不關注底層如何實現執行

public interface Command {
    public void exe();
}
public class MyCommand implements Command {

    private Receiver receiver;
    
    public MyCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void exe() {
        receiver.action();
    }
}
public class Receiver {
    public void action(){
        System.out.println("command received!");
    }
}

public class Invoker {
    
    private Command command;
    
    public Invoker(Command command) {
        this.command = command;
    }

    public void action(){
        command.exe();
    }
}
public class Test {

    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command cmd = new MyCommand(receiver);
        Invoker invoker = new Invoker(cmd);
        invoker.action();  //command received!
    }
}

七、備忘錄模式

  儲存一個物件的某個狀態,以便在適當的時候恢復物件,假設有原始類A,A中有各種屬性,A可以決定需要備份的屬性,備忘錄類B是用來儲存A的一些內部狀態,類C是一個用來儲存備忘錄的,且只能儲存,不能修改等操作。

  Original類是原始類,裡面有需要儲存的屬性value及建立一個備忘錄類,用來儲存value值。Memento類是備忘錄類,Storage類是儲存備忘錄的類,持有Memento類的例項,該模式很好理解

public class Original {
    
    private String value;
    
    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Original(String value) {
        this.value = value;
    }

    public Memento createMemento(){
        return new Memento(value);
    }
    
    public void restoreMemento(Memento memento){
        this.value = memento.getValue();
    }
}
public class Memento {
    
    private String value;

    public Memento(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}
public class Storage {
    
    private Memento memento;
    
    public Storage(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}

//測試類:
public class Test {

    public static void main(String[] args) {
        
        // 建立原始類
        Original origi = new Original("egg");

        // 建立備忘錄
        Storage storage = new Storage(origi.createMemento());

        // 修改原始類的狀態
        System.out.println("初始化狀態為:" + origi.getValue());
        origi.setValue("niu");
        System.out.println("修改後的狀態為:" + origi.getValue());

        // 回覆原始類的狀態
        origi.restoreMemento(storage.getMemento());
        System.out.println("恢復後的狀態為:" + origi.getValue());
    }
}
//初始化狀態為:egg
//修改後的狀態為:niu
//恢復後的狀態為:egg

八、狀態模式

  可以通過改變狀態來獲得不同的行為,你的好友能同時看到你的變化

/**
 * 狀態類的核心類
 *
 */
public class State {
    
    private String value;
    
    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void method1(){
        System.out.println("execute the first opt!");
    }
    
    public void method2(){
        System.out.println("execute the second opt!");
    }
}


/**
 * 狀態模式的切換類 
 * 
 */
public class Context {

    private State state;

    public Context(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public void method() {
        if (state.getValue().equals("state1")) {
            state.method1();
        } else if (state.getValue().equals("state2")) {
            state.method2();
        }
    }
}

//測試類:

public class Test {

    public static void main(String[] args) {
        
        State state = new State();
        Context context = new Context(state);
        
        //設定第一種狀態
        state.setValue("state1");
        context.method();
        
        //設定第二種狀態
        state.setValue("state2");
        context.method();
    }
}
//execute the first opt!
//execute the second opt!

九、訪問模式

  訪問者模式就是一種分離物件資料結構與行為的方法,通過這種分離,可達到為一個被訪問者動態新增新的操作而無需做其它的修改的效果

public interface Visitor {
    public void visit(Subject sub);
}
public class MyVisitor implements Visitor {

    @Override
    public void visit(Subject sub) {
        System.out.println("visit the subject:"+sub.getSubject());
    }
}
//Subject類,accept方法,接受將要訪問它的物件,getSubject()獲取將要被訪問的屬性,
public interface Subject {
    public void accept(Visitor visitor);
    public String getSubject();
}
public class MySubject implements Subject {

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String getSubject() {
        return "love";
    }
}

//測試:
public class Test {

    public static void main(String[] args) {
        
        Visitor visitor = new MyVisitor();
        Subject sub = new MySubject();
        sub.accept(visitor);    
    }
}
//visit the subject:love

十、

十一、

十二、

十三、直譯器模式

public interface Expression {
    public int interpret(Context context);
}

public class Plus implements Expression {

    @Override
    public int interpret(Context context) {
        return context.getNum1()+context.getNum2();
    }
}

public class Minus implements Expression {

    @Override
    public int interpret(Context context) {
        return context.getNum1()-context.getNum2();
    }
}

public class Context {
    
    private int num1;
    private int num2;
    
    public Context(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }
    
    public int getNum1() {
        return num1;
    }
    public void setNum1(int num1) {
        this.num1 = num1;
    }
    public int getNum2() {
        return num2;
    }
    public void setNum2(int num2) {
        this.num2 = num2;
    }
        
}

public class Test {

    public static void main(String[] args) {

        // 計算9+2-8的值
        int result = new Minus().interpret((new Context(new Plus().interpret(new Context(9, 2)), 8)));
        System.out.println(result);
    }
}

//3