1. 程式人生 > 實用技巧 >學習設計模式3--代理模式

學習設計模式3--代理模式

代理模式

結構

  • Subject介面

    package 結構;
    
    /**
     * @Program: 設計模式
     * @Description: Subject類定義了 RealSubject和Proxy的共用介面,
     *               這樣就能在任何能夠使用RealSubject的地方使用Proxy了
     * @Author Mokairui
     * @Date 2020/12/5 11:46
     */
    public interface Subject {
    
        void request();
    
    }
    
    
  • RealSubject具體實現類

    package 結構;
    
    /**
     * @Program: 設計模式
     * @Description: 定義了Proxy所代表的真實實體
     * @Author Mokairui
     * @Date 2020/12/5 11:48
     */
    public class RealSubject implements Subject {
    
        @Override
        public void request() {
            System.out.println("真實的請求");
        }
    }
    
    
  • 代理物件

    package 結構;
    
    /**
     * @Program: 設計模式
     * @Description: 儲存一個引用使得代理可以訪問實體,並提供一個於Subject的介面相同的介面,
     *               這樣代理就可以用來替代實體
     * @Author Mokairui
     * @Date 2020/12/5 11:50
     */
    public class Proxy implements Subject {
    
        private RealSubject realSubject;
    
        @Override
        public void request() {
            if (realSubject == null) {
                realSubject = new RealSubject();
            }
            // 呼叫方法,但是在這裡就可以就可以新增你想要的額外功能等
            realSubject.request();
        }
    }
    
    
  • 測試

    package 結構;
    
    /**
     * @Program: 設計模式
     * @Description: 測試類
     * @Author Mokairui
     * @Date 2020/12/5 12:22
     */
    public class Demo {
    
        public static void main(String[] args) {
            Proxy proxy = new Proxy();
            proxy.request();
        }
    
    }
    
    

靜態代理

  • 禮物介面

    package example.靜態;
    
    /**
     * @Program: 設計模式
     * @Description: 送禮物的介面
     * @Author Mokairui
     * @Date 2020/12/5 13:43
     */
    public interface IGiveGift {
    
        void GiveDolls();
    
        void GiveFlowers();
    
        void GiveChocolate();
    
    }
    
    
  • 被追求者

    package example.靜態;
    
    /**
     * @Program: 設計模式
     * @Description: 被追求者
     * @Author Mokairui
     * @Date 2020/12/5 14:29
     */
    public class SchoolGirl {
    
        private String name;
    
        public SchoolGirl() {
        }
    
        public SchoolGirl(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    
  • 追求者

    package example.靜態;
    
    /**
     * @Program: 設計模式
     * @Description: 追求者
     * @Author Mokairui
     * @Date 2020/12/5 13:44
     */
    public class Pursuit implements IGiveGift {
    
        private SchoolGirl schoolGirl;
    
        public void setSchoolGirl(SchoolGirl schoolGirl) {
            this.schoolGirl = schoolGirl;
        }
    
        @Override
        public void GiveDolls() {
            System.out.println(schoolGirl.getName() + "送你洋娃娃");
        }
    
        @Override
        public void GiveFlowers() {
            System.out.println(schoolGirl.getName() + "送你鮮花");
        }
    
        @Override
        public void GiveChocolate() {
            System.out.println(schoolGirl.getName() + "送你巧克力");
        }
    }
    
    
  • 代理類

    package example.靜態;
    
    /**
     * @Program: 設計模式
     * @Description: 代理類
     * @Author Mokairui
     * @Date 2020/12/5 14:33
     */
    public class Proxy implements IGiveGift {
    
        private Pursuit pursuit;
    
        public void setPursuit(Pursuit pursuit) {
            this.pursuit = pursuit;
        }
    
        @Override
        public void GiveDolls() {
            System.out.println("我是代理了送洋娃娃,我可以在這裡加額外需求");
            pursuit.GiveDolls();
    
        }
    
        @Override
        public void GiveFlowers() {
            System.out.println("我是代理了送鮮花,我可以在這裡加額外需求");
            pursuit.GiveFlowers();
        }
    
        @Override
        public void GiveChocolate() {
            System.out.println("我是代理了送巧克力,我可以再這裡加額外需求");
            pursuit.GiveChocolate();
        }
    }
    
    
  • 測試

    package example.靜態;
    
    /**
     * @Program: 設計模式
     * @Description: 測試類
     * @Author Mokairui
     * @Date 2020/12/5 14:36
     */
    public class Demo {
        public static void main(String[] args) {
            SchoolGirl schoolGirl = new SchoolGirl("yanzi");
            Pursuit pursuit = new Pursuit();
            pursuit.setSchoolGirl(schoolGirl);
    
            Proxy proxy = new Proxy();
            proxy.setPursuit(pursuit);
    
            proxy.GiveDolls();
            System.out.println("-----------------");
            proxy.GiveFlowers();
            System.out.println("------------------");
            proxy.GiveChocolate();
        }
    }
    
    

動態代理

JDK代理

追求者和被追求者,送禮物的介面這裡就不重複寫了

  • DynamicProxyHandler類

    package example.動態.jdk;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    /**
     * @Program: 設計模式
     * @Description: 動態代理物件
     * @Author Mokairui
     * @Date 2020/12/5 13:08
     */
    public class DynamicProxyHandler implements InvocationHandler {
    
        private Pursuit pursuit;
    
        public DynamicProxyHandler(Pursuit pursuit) {
            this.pursuit = pursuit;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = null;
            if ("GiveDolls".equals(method.getName())) {
                // 用來區別增強的不同方法
                System.out.print("最最可愛的");
            }
    
            if ("GiveFlowers".equals(method.getName())) {
                // 針對不同的方法,增強不同的內容
                System.out.println("五顏六色的哦");
            }
            result = method.invoke(this.pursuit, args);
    
            return result;
        }
    
    }
    
    
  • 測試類

    package example.動態.jdk;
    
    import java.lang.reflect.Proxy;
    
    /**
     * @Program: 設計模式
     * @Description: 測試類
     * @Author Mokairui
     * @Date 2020/12/5 13:11
     */
    public class Demo {
        public static void main(String[] args) {
            Pursuit pursuit = new Pursuit();
            pursuit.setSchoolGirl(new SchoolGirl("yanzi"));
    
            IGiveGift proxy = (IGiveGift) Proxy.newProxyInstance(pursuit.getClass().getClassLoader()
                    , pursuit.getClass().getInterfaces()
                    , new DynamicProxyHandler(pursuit));
    
            proxy.GiveDolls();
            System.out.println("---------------------");
            proxy.GiveFlowers();
            System.out.println("---------------------");
            proxy.GiveChocolate();
        }
    }
    
    

CGLIB代理

  • 追求者的類,本來是實現介面,這裡就變成了一個普通的類

    package example.動態.cglib;
    
    /**
     * @Program: 設計模式
     * @Description:
     * @Author Mokairui
     * @Date 2020/12/14 22:15
     */
    public class Pursuit {
    
        private SchoolGift schoolGift;
    
    
        public void setSchoolGift(SchoolGift schoolGift) {
            this.schoolGift = schoolGift;
        }
    
    
        public void giveDolls() {
            System.out.println("追求者送" + schoolGift.getName() + "娃娃");
        }
    
        public void giveFlowers() {
            System.out.println("追求者送" + schoolGift.getName() + "鮮花");
        }
    
        public void giveChocolate() {
            System.out.println("追求者送" + schoolGift.getName() + "巧克力");
        }
    }
    
    
  • 代理類

    package example.動態.cglib;
    
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * @Program: 設計模式
     * @Description:
     * @Author Mokairui
     * @Date 2020/12/14 22:26
     */
    public class DynamicProxyCglibHandler implements MethodInterceptor {
    
        // 需要代理的物件
        private Pursuit pursuit;
    
        public DynamicProxyCglibHandler(Pursuit pursuit) {
            this.pursuit = pursuit;
        }
    
        /**
         * 代理的核心方法
         * @param proxy
         * @param method
         * @param args
         * @param methodProxy
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object obj = null;
            System.out.println("代理方法前");
            method.invoke(pursuit, args);
            System.out.println("代理方法後");
            return obj;
        }
    }
    
    
  • 測試類

    package example.動態.cglib;
    
    
    import net.sf.cglib.proxy.Enhancer;
    
    
    /**
     * @Program: 設計模式
     * @Description:
     * @Author Mokairui
     * @Date 2020/12/14 22:10
     */
    public class Demo {
    
        public static void main(String[] args) {
            SchoolGift schoolGift = new SchoolGift();
            schoolGift.setName("燕子");
            Pursuit pursuit = new Pursuit();
    
            pursuit.setSchoolGift(schoolGift);
    
            Pursuit proxy = (Pursuit) Enhancer.create(pursuit.getClass(),
                    new DynamicProxyCglibHandler(pursuit));
    
            proxy.giveDolls();
            System.out.println("-----------------");
            proxy.giveFlowers();
            System.out.println("----------------");
            proxy.giveChocolate();
    
        }
    
    }