學習設計模式3--代理模式
阿新 • • 發佈:2020-12-20
代理模式
結構
-
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(); } }