設計模式之觀察和代理
1.觀察者模式
其實就是釋出訂閱模式,釋出者釋出資訊,訂閱者獲取資訊,訂閱了就能收到資訊,沒訂閱就收不到資訊。
- 1.1 抽象被觀察者角色:也就是一個抽象主題,它把所有對觀察者物件的引用儲存在一個集合中,每個主題都可以有任意數量的觀察者。抽象主題提供一個介面,可以增加和刪除觀察者角色。一般用一個抽象類和介面來實現。
- 1.2 抽象觀察者角色:為所有的具體觀察者定義一個介面,在得到主題通知時更新自己。
- 1.3 具體被觀察者角色:也就是一個具體的主題,在集體主題的內部狀態改變時,所有登記過的觀察者發出通知。
- 1.4 具體觀察者角色:實現抽象觀察者角色所需要的更新介面,一邊使本身的狀態與製圖的狀態相協調。
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<>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumeration = vector.elements();
while (enumeration.hasMoreElements()){
enumeration.nextElement().update();
}
}
}
public interface Observer {
public void update();
}
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 have received!");
}
}
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received");
}
}
public class Test {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}
2.代理模式
代理模式的定義:代理模式給某一個物件提供一個代理物件,並由代理物件控制對原物件的引用。通俗的來講代理模式就是我們生活中常見的中介。
舉個例子來說明:假如說我現在想買一輛二手車,雖然我可以自己去找車源,做質量檢測等一系列的車輛過戶流程,但是這確實太浪費我得時間和精力了。我只是想買一輛車而已為什麼我還要額外做這麼多事呢?於是我就通過中介公司來買車,他們來給我找車源,幫我辦理車輛過戶流程,我只是負責選擇自己喜歡的車,然後付錢就可以了。
2.1. 分類
- 靜態代理是建立或特定工具自動生成原始碼,在對其編譯。在程式執行之前,代理類.class檔案就已經被建立了。
- 動態代理是在程式執行時通過反射機制動態建立的。
2.2. 靜態代理實現
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Proxy implements Sourceable {
private Source source;
public Proxy() {
super();
this.source = new Source();
}
@Override
public void method() {
before();
source.method();
atfer();
}
private void atfer() {
System.out.println("after proxy!");
}
private void before() {
System.out.println("before proxy!");
}
}
public class Test {
public static void main(String[] args) {
Sourceable sourceable = new Proxy();
sourceable.method();
}
}
2.3. 動態代理實現(JDK)
public class DynamicProxyHandler implements InvocationHandler {
private Object object;
public DynamicProxyHandler(final Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("買房前準備");
Object result = method.invoke(object, args);
System.out.println("買房後裝修");
return result;
}
}
public class DynamicProxyTest {
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
proxyBuyHouse.buyHosue();
}
}
2.4. 動態代理實現(CGLIB代理)
public class CglibProxy implements MethodInterceptor {
private Object target;
public Object getInstance(final Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("買房前準備");
Object result = methodProxy.invoke(object, args);
System.out.println("買房後裝修");
return result;
}
}
public class CglibProxyTest {
public static void main(String[] args){
BuyHouse buyHouse = new BuyHouseImpl();
CglibProxy cglibProxy = new CglibProxy();
BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);
buyHouseCglibProxy.buyHosue();
}
}
總結:CGLIB建立的動態代理物件比JDK建立的動態代理物件的效能更高,但是CGLIB建立代理物件時所花費的時間卻比JDK多得多。所以對於單例的物件,因為無需頻繁建立物件,用CGLIB合適,反之使用JDK方式要更為合適一些。同時由於CGLib由於是採用動態建立子類的方法,對於final修飾的方法無法進行代理。
相關文章
- 設計模式之觀察者模式設計模式
- 設計模式之-觀察者模式設計模式
- 設計模式之【觀察者模式】設計模式
- Go 設計模式之觀察者模式Go設計模式
- 設計模式之觀察者模式(一)設計模式
- PHP 設計模式之——觀察者模式PHP設計模式
- JavaScript設計模式之觀察者模式JavaScript設計模式
- golang設計模式之觀察者模式Golang設計模式
- Java 設計模式之《觀察者模式》Java設計模式
- python設計模式之觀察者模式Python設計模式
- PHP設計模式之觀察者模式PHP設計模式
- PHP 設計模式之觀察者模式PHP設計模式
- Java常用設計模式之觀察者模式Java設計模式
- 設計模式之觀察者模式(Observer Pattern)設計模式Server
- Java設計模式之(十二)——觀察者模式Java設計模式
- 折騰Java設計模式之觀察者模式Java設計模式
- 17.java設計模式之觀察者模式Java設計模式
- 設計模式 —— 觀察者模式設計模式
- 設計模式(觀察者模式)設計模式
- 設計模式----觀察者模式設計模式
- 【設計模式】觀察者模式設計模式
- 設計模式——觀察者模式設計模式
- 設計模式學習之觀察者模式和釋出訂閱模式設計模式
- Java進階篇設計模式之十三 ---- 觀察者模式和空物件模式Java設計模式物件
- PHP設計模式-觀察者模式PHP設計模式
- Java設計模式-觀察者模式Java設計模式
- 設計模式解析:觀察者模式設計模式
- 設計模式 #6 (觀察者模式)設計模式
- JS設計模式(觀察者模式)JS設計模式
- 設計模式(十六)觀察者模式設計模式
- 設計模式(9) 觀察者模式設計模式
- 設計模式-觀察者模式上設計模式
- 設計模式-觀察者模式下設計模式
- 設計模式實戰 - 觀察者模式設計模式
- PHP設計模式(5)—— 觀察者模式PHP設計模式
- 設計模式解析-1:觀察者模式設計模式
- 《Head First 設計模式》:觀察者模式設計模式
- 簡說設計模式——觀察者模式設計模式