java jdk靜態署理詳解。本站提示廣大學習愛好者:(java jdk靜態署理詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是java jdk靜態署理詳解正文
先給出一個四人團對Decorator mode的界說:靜態地給一個對象添加一些額定的職責。
再來講說這個形式的利益:認證,權限檢討,記日記,檢討參數,加鎖,等等等等,這些功效和體系營業有關,但又是體系所必需的,說的更明確一點,就是面向方面的編程(AOP)。
在Python中Decorator mode可以依照像其它編程說話如C++, Java等的模樣來完成,然則Python在運用裝潢概念方面的才能上遠不止於此,Python供給了一個語法和一個編程特征來增強這方面的功效。Python供給的語法就是裝潢器語法(decorator),以下:
@aoo def foo(): pass def aoo(fn): return fn
裝潢形式強調靜態地給對象添加額定的功效。 Python內置了許多對裝潢器的支撐,是以在Python中應用裝潢形式長短常輕易的,上面是一個典范的例子,給函數增長日記功效:
import functools def log_wrapper(fun): @functools.wraps(fun) def wrapper(*args, **kwargs): print '在函數履行前加日記' ret = fun(*args, **kwargs) print '在函數履行後家日記' return ret return wrapper @log_wrapper def test(): print 'Hello, 世界'
functools.wraps是Python尺度庫供給的一個特別的裝潢器,用來處理裝潢器帶來的一些慣例成績,如函數稱號、doc等的紛歧致成績。@是Python針對裝潢器供給的一個語法糖,下面的@log_wrapper相當於wrap_test = log_rapper(test),用@後,這個步調由說明器代庖了。
裝潢器是Python編程必需控制的一項技巧,在編碼進程中常常會用到。
這裡只是一個通俗的內嵌函數
def foo(x): y = x def foo1 (): a = 1 return a return foo1
而上面boo則是一個閉包
def aoo(a, b): c = a def boo (x): x = b + 1 return x return boo
boo的特別性在於援用了內部變量b,當aoo前往後,只需前往值(boo)一向存在,則對b的援用就會一向存在。
下面的常識能夠須要花些時光消化,假如你認為曾經控制了這些常識,上面就回歸正題,看看這些說話特征是如何來完成Python中裝潢的概念的。
照樣讓我們先看一個簡略的例子,然後慢慢深刻。這個例子就是加鎖,如何完成加鎖的功效?
詳細需求是如許的:我有一個對象,完成了某些功效並供給了一些接供詞其它模塊挪用,這個對象是運轉在並發的情況中的,是以我須要對接口的挪用停止同步,初版的代碼以下:
class Foo(object): def __init__(self, …): self.lock = threading.Lock() def interface1(self, …): self.lock.acquire() try: do something finally: self.lock.release() def interface2(self, …): same as interface1() …
這版代碼的成績很顯著,那就是每一個接口函數都有雷同的加鎖/解鎖代碼,反復的代碼帶來的是更多的鍵入,更多的浏覽,更多的保護,和更多的修正,最重要的是,法式員本應集中在營業上的的精神被疏散了,並且請留意,真實的營業代碼在間隔函數界說2次縮進處開端,即便你的顯示器是寬屏,這也會帶來一些浏覽上的艱苦。
你直覺的以為,可以把這些代碼收進一個函數中,以到達復用的目標,然則請留意,這些代碼不是一個完全統一的代碼塊,而是在中央嵌入了營業代碼。
如今我們用裝潢器語法來改良這部門代碼,獲得第2版代碼:
def sync(func): def wrapper(*args, **kv): self = args[0] self.lock.acquire() try: return func(*args, **kv) finally: self.lock.release() return wrapper class Foo(object): def __init__(self, …): self.lock = threading.Lock() @sync def interface1(self, …): do something @sync def interface2(self, …): do something …
一個裝潢器函數的第一個參數是所要裝潢的誰人函數對象,並且裝潢器函數必需前往一個函數對象。如sync函數,當其裝潢interface1時,參數func的值就是interface1,前往值是wrapper,但類Foo實例的interface1被挪用時,現實挪用的是wrapper函數,在wrapper函數體中央接挪用現實的interface1;當interface2被挪用時,也挪用的是wrapper函數,不外因為在裝潢時func曾經釀成interface2,所以會直接地挪用到現實的interface2函數。
應用裝潢器語法的利益:
代碼量年夜年夜的削減了,更少的代碼意味著更少的保護,更少的浏覽,更少的鍵入,利益紛歧而足(可復用,可保護)
用戶根本大將絕年夜部門精神放在了營業代碼上,並且少了加減鎖的代碼,可讀性也進步了
缺陷:
營業對象Foo中有一個非營業數據成員lock,很礙眼;
相當水平的耦合,wrapper的第一個參數必需是對象自己,並且被裝潢的對象中必需有一個lock對象存在,這給客戶對象添加了限制,應用起來不是很舒暢。
我們可以更進一步想想:
lock對象必需要放在Foo中嗎?
為每一個接口函數都鍵入@sync照樣很煩人的反復性人工任務,假如漏添加一個,照樣會形成莫明其妙的運轉時毛病,為何不集中處置呢?
為懂得決上述的缺陷,第3版代碼以下:
class DecorateClass(object): def decorate(self): for name, fn in self.iter(): if not self.filter(name, fn): continue self.operate(name, fn) class LockerDecorator(DecorateClass): def __init__(self, obj, lock = threading.RLock()): self.obj = obj self.lock = lock def iter(self): return [(name, getattr(self.obj, name)) for name in dir(self.obj)] def filter(self, name, fn): if not name.startswith('_') and callable(fn): return True else: return False def operate(self, name, fn): def locker(*args, **kv): self.lock.acquire() try: return fn(*args, **kv) finally: self.lock.release() setattr(self.obj, name, locker) class Foo(object): def __init__(self, …): … LockerDecorator(self).decorate() def interface1(self, …): do something def interface2(self, …): do something …
對對象的功效裝潢是一個更普通的功效,不只限於為接口加鎖,我用2個類來完成這一功效,DecorateClass是一個基類,只界說了遍歷並運用裝潢功效的算法代碼(template method),LockerDecorator完成了為對象加鎖的功效,個中iter是迭代器,界說了如何遍歷對象中的成員(包含數據成員和成員函數),filter是過濾器,界說了相符甚麼規矩的成員能力成為一個接口,operate是履行函數,詳細實行了為對象接口加鎖的功效。
而在營業類Foo的__init__函數中,只須要在最初添加一行代碼:LockerDecorator(self).decorate(),便可以完成為對象加鎖的功效。
假如你的對象供給的接口有特別性,完整可以經由過程直接改寫filter或許繼續LockerDecorator並籠罩filter的方法來完成;另外,假如要應用其他的裝潢功效,可以寫一個繼續自DecorateClass的類,並完成iter,filter和operate三個函數便可。
注:代碼中加紅部門proxymethod.generateMethod()為每一個辦法生成辦法體,經由過程檢查源碼可以看出都是在挪用InvocationHandler接口的完成處置器的invoke辦法。