设计模式学习之代理模式学习(一)
設計模式學習之代理模式學習(一)
? ? ? 關于設計模式想必學習過Java語言的人都知道吧,當時對其進行深入學習的的人應該不是很多。在我看來設計方面的知識相比于框架應用配置等知識要有意思的多,并且設計模式的對一個程序員的編程思想提升有著很大的幫助。但是設計模式有二十三種,想要全部掌握還是要花點時間的,但如果是只學習常用的幾種設計模式還是相對容易的。下面是我學習代理模式的一些心得。
問題引出
? ?? 什么是代理模式,為什么要用代理模式。
? ? ? 現在有一個場景模擬:有一個tank類,他實現了Moveable接口,Moveable接口中有一個move方法,tank類重寫move方法。那么現在問題來了,我要想要知道坦克move方法的執行時間怎么辦。我想馬上就有人會想到在move方法執行前獲得一下系統時間,然后在執行后再獲得一下系統時間,兩個時間相減就能得到move方法的執行時間了。沒錯這種方法的確能解決剛剛的問題,但是同樣帶來了另外的問題那就是需要修改源碼,這是相當不友好的,在沒有源碼的前提下還不能實現。那要怎么實現才比較合理了,沒錯就是代理。講到這我想我不需要說代理的定義是什么了吧,請看下面代碼。
?
?
Tank類的源代碼:
?
import java.util.Random;public class Tank implements Moveable{@Overridepublic void move() {System.out.println("moving......");try {Thread.sleep(new Random().nextInt(10000));} catch (InterruptedException e) {e.printStackTrace();}}}?
方法一
? ? 定義一個類繼承Tank類并且重寫Tank的move方法,在move方法中加入上述邏輯。
?
* 方法一* @author admin**/ public class Tank2 extends Tank{@Overridepublic void move() {long start = System.currentTimeMillis();super.move();long end = System.currentTimeMillis();System.out.println("time="+(end-start));}}方法二
? ?定義一個Tank3類實現了Moveable接口,同時Tank3內有個Moveable類型成員變量。重寫move方法并在邏輯代碼中間調用Tank的move方法。具體代碼如下:
/*** 方法二* @author admin**/ public class Tank3 implements Moveable{private Moveable tank;public Tank3(Moveable tank) {this.tank = tank;}@Overridepublic void move() {long start = System.currentTimeMillis();tank.move();long end = System.currentTimeMillis();System.out.println("time="+(end-start));}}? ?測試程序:
/*** 對于Java代理設計模式的學習* 問題:想要知道tank類中的move方法運行的時間* 方法一:編寫一個類繼承tank類,然后在這個類中重寫move方法。加上開始時間* 和結束時間然后相減。* 方法二:編寫一個類,里面有一個成員屬性是tank類類型,并且實現Moveable* 接口。同樣重寫move方法,并在方法里調用tank中的move方法,并加上相應的* 邏輯。(常用,聚合的方式是比繼承要好得多,不會出現類爆炸。)* @author admin**/ public class Client {public static void main(String[] args) {Tank2 tank = new Tank2();tank.move();Tank3 tank1 = new Tank3(new Tank());tank1.move();}}?
?
? ?到此兩種實現方法都已給出,那么我們的任務完成了嗎,還沒有,既然是學習,那么我們就要深入一點。這里給出了兩種實現方式,那么哪種實現方式要好了?推薦使用方法二,
我想可能很多人就不服了,為什么啊?
? ? 對于上述問題,我們再來模擬一個場景:現在我們完成計算move運行時間的邏輯,那么問題來了,你的老板要你在move方法執行前后加上一個日志操作。使用方法一就是在創建一個類繼承Tank類,并重寫move方法加上日志邏輯。方法二是創建一個新的類實現Moveable接口,有個成員變量是Moveable類型成員變量。重寫move方法并在日志邏輯代碼中間調用成員變量的move方法。這里就有人會有疑問了,感覺沒區別啊,都是要創建一個新的類。是的,到現在為止表面上是沒有區別。那么現在我們老板又給了我們新的要求,他要我們在實現時間計算的同時加上日志,并且是時間執行在前面,日志執行在后面。使用方法一就是再次創建一個新的類完成兩次邏輯。好,老板又改主意了這次他要求日志執行在前,時間計算在后,這時你又要創建一個新的類來完成新的邏輯。哇,好麻煩啊,如果,要求的功能更多,就出現類爆炸了。
? ?那么方法二是怎么實現的呢?
? ? 假設你現在有了時間邏輯和日志邏輯兩個類,現在要完成時間加日志的組合我們只要修改Client程序就行了,不需要再創建新的類了(好舒服)
public class Client {public static void main(String[] args) {Tank tank1 = new Tank();Tank2 tank2 = new Tank2(tank1 );//使用方法二完成的時間計算的類 這里就不給出實現來了 Tank3 tank3 = new Tank3(tank2 );//使用方法二完成的日志邏輯的類 這里就不給出實現來了 tank3 .move();}}? ?應為Tank2和Tank3都實現了Movea接口,所以在創建Tank3的時候我們能把Tank2對象傳進去。這樣就可以把功能組合起來了。如果在創建Tank2時傳Tank3就是先日志后時間。各位看都區別了吧,整整少寫 了兩個類。所以說哪種方式要好,相信大家已經心知肚明了吧。那么到此我們的問題解決了吧。我想說的是還沒有,剛剛解決的只是各個功能之間相互組合的問題,但是我們發現每增加一個新的功能我還是要增加一個代理類,這多麻煩啊,我們能不能只生成一個,或者讓程序動態的給我們生成呢?當然可以,請關注我后續的博文
設計模式學習之代理模式學習(二)—動態代理
?
轉載于:https://www.cnblogs.com/huangliang11/p/9277923.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的设计模式学习之代理模式学习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unicode-objects must
- 下一篇: 安全开发流程(SDL、微软)