程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java jdk靜態署理詳解

java jdk靜態署理詳解

編輯:關於JAVA

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三個函數便可。

sp;          throw new InternalError("unexpected I/O Exception");
        }
        return bytearrayoutputstream.toByteArray();
    }


注:代碼中加紅部門proxymethod.generateMethod()為每一個辦法生成辦法體,經由過程檢查源碼可以看出都是在挪用InvocationHandler接口的完成處置器的invoke辦法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved