1. 程式人生 > >用最簡單的例子說明設計模式(三)之責任鏈、建造者、適配器、代理模式、享元模式

用最簡單的例子說明設計模式(三)之責任鏈、建造者、適配器、代理模式、享元模式

def dap CA 抽象 創建 tcl cte clas eth

責任鏈模式 一個請求有多個對象來處理,這些對象是一條鏈,但具體由哪個對象來處理,根據條件判斷來確定,如果不能處理會傳遞給該鏈中的下一個對象,直到有對象處理它為止 使用場景 1)有多個對象可以處理同一個請求,具體哪個對象處理該請求待運行時刻再確定 2)在不明確指定接收者的情況下,向多個對象中的一個提交一個請求 3)可動態指定一組對象處理請求,客戶端可以動態創建職責鏈來處理請求 技術分享圖片
public class Chain {

    public abstract class Handler {
        private Handler nextHandler;
        // 當前領導能審批通過的最多天數
        public int maxDay;

        protected Handler(int maxDay) {
            this.maxDay = maxDay;
        }

        //設置責任鏈中下一個處理請求的對象
        public void setNextHandler(Handler handler) {
            nextHandler = handler;
        }

        protected void handleRequest(int day) {
            if (day <= maxDay) {
                reply(day);
            } else {
                if (nextHandler != null) {
                    //審批權限不夠,繼續上報
                    nextHandler.handleRequest(day);
                } else {
                    System.out.println("沒有更高的領導審批了");
                }
            }
        }

        protected abstract void reply(int day);
    }

    class ProjectManager extends Handler {
        public ProjectManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天請假,項目經理直接審批通過");
        }
    }

    class DepartmentManager extends Handler {
        public DepartmentManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天請假,部門經理審批通過");
        }
    }

    class GeneralManager extends Handler {
        public GeneralManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天請假,總經理直接審批通過");
        }
    }

    public static void main(String[] strings) {
        Chain chain = new Chain();
        Handler projectManager = chain.new ProjectManager(3);
        Handler departmentManager = chain.new DepartmentManager(5);
        Handler generalManager = chain.new GeneralManager(15);
        //創建職責鏈
        projectManager.setNextHandler(departmentManager);
        departmentManager.setNextHandler(generalManager);
        //發起請假請求
        projectManager.handleRequest(4);
    }
}

  

Buidler(建造者)模式 一種創建型的設計模式.,通常用來將一個復雜的對象的構造過程分離, 讓使用者可以根據需要選擇創建過程.另外, 當這個復雜的對象的構造包含很多可選參數時, 也可以使用建造者模式
public class AlerDialog {

    private  String title;
    private  String message;

    public AlerDialog(Builder builder) {
//        View.inflate()
        this.title = builder.title;
        this.message = builder.message;
    }

    public static class Builder {
        private  String title;
        private  String message;

        public  Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public   Builder setMessage(String message) {
            this.message = message;
            return this;
        }

        public  AlerDialog build() {
            return new AlerDialog(this);
        }
    }
}
 new AlerDialog.Builder().setTitle("").setMessage("").build();

  

適配器模式 把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起使用的類能夠一起工作。   適配器就是一種適配中間件,它存在於不匹配的二者之間,用於連接二者,將不匹配變得匹配,簡單點理解就是平常所見的轉接頭,轉換器之類的存在。 技術分享圖片

技術分享圖片 技術分享圖片
類適配器 原理:通過繼承來實現適配器功能。 類適配器使用對象繼承的方式,是靜態的定義方式 對於類適配器,適配器可以重定義Adaptee的部分行為,使Adaptee有了sampleOperation2() 對於類適配器,僅僅引入了一個對象,並不需要額外的引用來間接得 到 Adaptee 對於類適配器,由於適配器直接繼承了Adaptee,使得適配器不能和 Adaptee的子類一起工作
public interface Target {

    void sampleOperation1();

    void sampleOperation2();
}
public class Adaptee {

    public void sampleOperation1() {
        System.out.println("sampleOperation1");
    }
}
public class Adapter extends Adaptee implements Target {

    @Override
    public void sampleOperation2() {
        System.out.println("sampleOperation2");
    }

}
public class MyClass {
    public static void main(String[] args) {
        Adapter adapter = new Adapter();
        adapter.sampleOperation1();
        adapter.sampleOperation2();
    }
}

  


對象適配器 與類的適配器模式一樣,對象的適配器模式把被適配的類的API轉換成為目標類的API,與類的適配器模式不同的是,對象的適配器模式不是使用繼承關系連接到Adaptee類,而是使用委派關系連接到Adaptee類。 對象適配器使用對象組合的方式,是動態組合的方式 對於對象適配器,一個適配器(adaptee)可以把多種不同的源適配到同一個目標 對於對象適配器,要重定義Adaptee的行為比較困難 對於對象適配器,需要額外的引用來間接得到Adaptee。
public interface Target {

    void sampleOperation1();

    void sampleOperation2();
}

public class Adaptee {
    public void sampleOperation1() {
        System.out.println("sampleOperation1");
    }
}

public class Adapter implements Target {

    private Adaptee mAdaptee;

    public Adapter(Adaptee adaptee) {
        mAdaptee = adaptee;
    }

    @Override
    public void sampleOperation1() {
        mAdaptee.sampleOperation1();
    }

    @Override
    public void sampleOperation2() {
        System.out.println("sampleOperation2");
    }

}

public class MyClass {

    public static void main(String[] args) {
        Adapter adapter =new Adapter(new Adaptee());
        adapter.sampleOperation1();
        adapter.sampleOperation2();
    }
}

  

代理模式 通過代理對象訪問目標對象.這樣做的好處是:可以在目標對象實現的基礎上,擴展目標對象的功能。在調用這個方法前作的前置處理(統一的流程代碼放到代理中處理)。調用這個方法後做後置處理。
這裏使用到編程中的一個思想:不要隨意去修改別人已經寫好的代碼或者方法,如果需改修改,可以通過代理的方式來擴展該方法。 動態代理的用途與裝飾模式很相似,就是為了對某個對象進行增強。所有使用裝飾者模式的案例都可以使用動態代理來替換。 技術分享圖片 技術分享圖片技術分享圖片技術分享圖片
/**
 * subject(抽象主題角色):
 * 真實主題與代理主題的共同接口。
 */
interface Subject {
    void sellBook();
}

/**
 * ReaISubject(真實主題角色):
 * 定義了代理角色所代表的真實對象。
 */
public class RealSubject implements Subject {
    @Override
    public void sellBook() {
        System.out.println("出版社賣書");
    }
}

/**
 * Proxy(代理主題角色):
 * 含有對真實主題角色的引用,代理角色通常在將客
 * 戶端調用傳遞給真實主題對象之前或者之後執行某些
 * 操作,而不是單純返回真實的對象。
 */
public class ProxySubject implements Subject {

    private RealSubject realSubject;

    @Override
    public void sellBook() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        sale();
        realSubject.sellBook();
        give();
    }

    public void sale() {
        System.out.println("打折");
    }

    public void give() {
        System.out.println("送優惠券");
    }
}

public class Main {
    public static void main(String[] args) {
        //靜態代理(我們自己靜態定義的代理類)
        ProxySubject proxySubject = new ProxySubject();
        proxySubject.sellBook();

        //動態代理(通過程序動態生成代理類,該代理類不是我們自己定義的。而是由程序自動生成)
        RealSubject realSubject = new RealSubject();
        MyHandler myHandler = new MyHandler();
        myHandler.setProxySubject(realSubject);
        Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
                realSubject.getClass().getInterfaces(), myHandler);
        subject.sellBook();

    }
}

public class MyHandler implements InvocationHandler {
    private RealSubject realSubject;

    public void setProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    /**
     * @param proxy   指代我們所代理的那個真實對象
     * @param method   指代的是我們所要調用真實對象的某個方法的Method對象
     * @param args    指代的是調用真實對象某個方法時接受的參數
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        sale();
        proxy = method.invoke(realSubject, args);
        give();
        return proxy;
    }

    public void sale() {
        System.out.println("打折");
    }

    public void give() {
        System.out.println("送優惠券");
    }
}

  

享元模式 享元的目的是為了減少不會要額內存消耗,將多個對同一對象的訪問集中起來,不必為每個訪問者創建一個單獨的對象,以此來降低內存的消耗。
public class FlyWeight {

    static class MyString {
        private String myChar;

        public MyString(String myChar) {
            this.myChar = myChar;
        }


        public void display() {
            System.out.println(myChar);
        }
    }

    static class MyCharacterFactory {

        private Map<String, MyString> pool;

        public MyCharacterFactory() {
            pool = new HashMap<>();
        }

        public MyString getMyCharacte(String strig) {
            MyString myString = pool.get(strig);
            if (myString == null) {
                myString = new MyString(strig);
                pool.put(strig, myString);
            }
            return myString;
        }
    }

    public static void main(String[] args) {
        MyCharacterFactory myCharacterFactory = new MyCharacterFactory();
        MyString a = myCharacterFactory.getMyCharacte("a");
        MyString b = myCharacterFactory.getMyCharacte("b");
        MyString a1 = myCharacterFactory.getMyCharacte("a");
        MyString d = myCharacterFactory.getMyCharacte("d");

        if (a == a1) {
            System.out.println("true");
        }

    }
}

  

相關源碼:https://github.com/peiniwan/DesignPattern.git

用最簡單的例子說明設計模式(三)之責任鏈、建造者、適配器、代理模式、享元模式