一、繼承 使用場景:能夠控制這個類的構造的時候,才可以使用繼承。 優點:簡單容易使用, 缺點:耦合性大大的增強,不利於後期的維護,所以對於繼承這種方法,謹慎使用。 代碼實現:二、裝飾者模式 使用場景:1、包裝對象和被包裝對象實現相同的介面 2、包裝的對象中需要獲得到被包裝對象的引用。 缺點:如果介面 ...
一、繼承
使用場景:能夠控制這個類的構造的時候,才可以使用繼承。
優點:簡單容易使用,
缺點:耦合性大大的增強,不利於後期的維護,所以對於繼承這種方法,謹慎使用。
代碼實現:
二、裝飾者模式
使用場景:1、包裝對象和被包裝對象實現相同的介面
2、包裝的對象中需要獲得到被包裝對象的引用。
缺點:如果介面的方法比較多,增強其中某個方法,其他的功能的方法需要原有的調用;
代碼實現:
/**
* 裝飾者模式:
* 增強request的getParameter方法,使其編碼格式為utf-8
*/
public class MyServletRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyServletRequest (HttpServletRequest request) {
super(request);
this.request=request;
}
@Override //重寫getParameter方法
public String getParameter(String name) {
String value = request.getParameter(name);
try {
value=new String(value.getBytes("iso-8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return value;
}
三、動態代理
使用場景:被增強的對象必須實現介面。
需求:(1)定義一個服務員介面
// 服務員
public interface Waiter {
// 服務
public void serve();
}
(2)一個男服務員的類並實現服務員介面。男服務員有個方法是服務。
public class ManWaiter implements Waiter {
public void serve() {
System.out.println("服務中...");
}
}
現在想讓男服務員在服務的時候有禮貌,需要在服務的方法前後加上禮貌用語。
動態代理實現代碼:
public class Demo {
@Test
public void fun1() {
Waiter manWaiter = new ManWaiter();//目標對象
/*
* 給出三個參數,來創建方法,得到代理對象
*/
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = {Waiter.class};
InvocationHandler h = new WaiterInvocationHandler(manWaiter);//參數manWaiter表示目標對象
// 得到代理對象,代理對象就是在目標對象的基礎上進行了增強的對象!
Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(loader, interfaces, h); //獲取ManWaiter增強後的對象
waiterProxy.serve(); //在這裡執行WaiterInvocationHandler 中的invoke方法
}
}
//定義一個類實現InvocationHandler 這就是增強的類
public class WaiterInvocationHandler implements InvocationHandler {
private Waiter waiter;//目標對象
public WaiterInvocationHandler(Waiter waiter) {
this.waiter = waiter;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("您好!");
this.waiter.serve();//調用目標對象的目標方法
System.out.println("再見!");
return null;
}
}