• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    面向方面 vs 面向對象 3(AOP方法)

    發布: 2007-5-25 14:25 | 作者: 未知 | 來源: JR | 查看: 65次 | 進入軟件測試論壇討論

    領測軟件測試網  by Narayanan A.R. June 15, 2005
    翻譯zhangv (derekzhangv.at.hotmail.com)
    原文:http://www.devx.com/Java/Article/28422/0/page/3


    圖3

    圖3中描述了AOP方法的設計以及在一個更抽象的層次上類間的交互.你可以通過對比圖1和圖3來更好地理解AOP.
    程序的目的是通過BusinessUnit對象讀取CSV文件中的記錄然后 填入類BusinessUnitService 中的map.使用AOP來填充這個map有點類似后門(backdoor)方法 -- 控制被委派給BusinessUnit 來讀取存儲介質中的記錄.

    AOP就是定義一些point cut(?)和advice.一個point cut是源代碼中一個執行點.前面的例子定義了一個pointcut 給類BusinessUnitService中的findBusinessUnits 方法.一個advice就是當執行到point cut時的一塊代碼.類BusinessUnitPersistentAspect 包括advice方法findAllBusinessUnits,該方法從存儲介質中載入數據,然后使用工廠類創建BusinessUnit 對象.然后這個對象被加入map,map對象的引用通過BusinessUnitService 對象獲得.point cut 和advice組成了所謂的"方面(Aspect)"

    為了讀取存儲介質中的數據,OOP方法通過一個DAO類來做.而AOP中,你在作用域類中定義一個point cut和一個advice來讀取數據.AOP框架會以advice的形式注入代碼,既可以在執行期也可以在編譯期.

    總而言之,當類BusinessUnitService 中的findAllBusinessUnits 方法被調用時,AOP框架會注入advice方法并通過BusinessUnit 對象預先讀取數據來填充map對象.這樣,持久層方面的代碼可以從業務模型中移出.

    新方法里的方面

    本節討論如何用AOP為應用程序的各方面建模

    操作資源

    類BusinessUnitPersistenceAspect 的持久方法使用了一個buffered reader.你甚至可以定義方面的方面,但為了簡單,這里的討論只關注類的查找方法.
    1. @Aspect("perJVM")
    2. public class BufferedFileReaderAspect {
    3. @Expression("execution(* org.javatechnocrats.aop.withaop.aspects.BusinessUnitPersistenceAspect.find*(..))")
    4. Pointcut businessUnitPersistenceAspect;
    5. // 其他point cut 定義
    6. @Expression("businessUnitPersistenceAspect ||
    7. employeePersistenceAspect ||
    8. managerPersistenceAspect")
    9. Pointcut allPersistencePointcuts;
    10. private Map<ClassString> fileNames;
    11. public BufferedFileReaderAspect() {
    12. System.out.println("BufferedFileReaderAspect created");
    13. fileNames = new HashMap<ClassString>();
    14. fillFileNames();
    15. }
    16. @Before("allPersistencePointcuts")
    17. public void assignReader(JoinPoint joinPoint) throws Throwable {
    18. System.out.println("assignReader advice called");
    19. Object callee = joinPoint.getCallee();
    20. IBufferedFileReaderConsumable bufReaderConsumable = (IBufferedFileReaderConsumable)callee;
    21. Class persistenceClass = callee.getClass();
    22. String fileName = fileNames.get(persistenceClass);
    23. FileReader fileReader = new FileReader(fileName);
    24. BufferedReader bufferedReader = new BufferedReader(fileReader);
    25. bufReaderConsumable.setBufferedReader(bufferedReader);
    26. }
    27. @AfterFinally("allPersistencePointcuts")
    28. public void releaseReader(JoinPoint joinPoint) throws Throwable {
    29. //釋放buffered reader等資源
    30. }
    31. //其他方法
    32. }


    上面的代碼試圖為每一個方法名創建一個point cut -- 所有以find開頭的方法.無論何時這些方法被調用,assignReader方法都會被提前執行.這里它獲取被調用的類實例然后設置新建的buffered reader.

    同樣地,在releaseReader 方法里,代碼會預先關閉buffered reader集合.本節只解釋@before和@
    AfterFinally 這兩個point cut.(以J2SE 5.0的標記定義).另外,你也可以在方面定義的xml文件中聲明他們.你可以查看那例程源代碼中的aop.xml文件.

    下載

    持久化

    前面提到,OOP方法使用BusinessUnit 來為應用的持久層填充Map.在下面的高亮代碼中(@before一行,以及while循環代碼 - 譯者注),當BusinessUnitService 中的方法findAllBusinessUnits 被調用時advice方法findAllBusinessUnits 也將被調用.
    1. @Aspect("perJVM")
    2. public class BusinessUnitPersistenceAspect implements IBufferedFileReaderConsumable {
    3. private BufferedReader buffFileReader;
    4. @Before("execution(Collection org.javatechnocrats.aop.withaop.BusinessUnitService.findAllBusinessUnits())")
    5. public void findAllBusinessUnits(JoinPoint joinPoint) throws Throwable {
    6. System.out.println("findAllBusinessUnits advice called");
    7. Map<String, BusinessUnit> businessUnits =
    8. ((BusinessUnitService)joinPoint.getThis()).getBusinessUnits();
    9. String businessUnitRecord;
    10. while((businessUnitRecord = buffFileReader.readLine()) != null) {
    11. BusinessUnit businessUnit = BusinessUnitFactory.createBusinessUnit(businessUnitRecord);
    12. businessUnits.put(businessUnit.getId(), businessUnit);
    13. }
    14. }
    15. public void setBufferedReader(BufferedReader buffFileReader) {
    16. System.out.println("BusinessUnitPersistenceAspect.setBufferedReader called");
    17. this.buffFileReader = buffFileReader;
    18. }
    19. public BufferedReader getBufferedReader() {
    20. System.out.println("BusinessUnitPersistenceAspect.getBufferedReader called");
    21. return this.buffFileReader;
    22. }
    23. }

    advice方法從數據存儲中讀取記錄,使用工廠類創建一個BusinessUnit實例.然后這個實例被加入到Map.該Map掌管程序的所有持久化方面.

    日志/b]
    本文中的例子沒有包含一個完整的日志AOP解決方案.但是,它為java.lang.Object類的toString方法定義了一個point cut來獲取類的調試信息.因此,域中的類不需要實現toString方法.通?赡苣憧赡苄枰獮槊恳粋類都要實現這個方法.

    1. @Aspect("perJVM")
    2. public class LoggingAspect {
    3. @Around("execution(String org.javatechnocrats.aop.withaop..*.toString())")
    4. public Object toStringAdvice(JoinPoint joinPoint) throws Throwable {
    5. System.out.println("toStringAdvice called");
    6. String toString = (String)joinPoint.proceed();
    7. Object target = joinPoint.getThis();
    8. Field fields[] = target.getClass().getDeclaredFields();
    9. List members = new ArrayList(fields.length + 1);
    10. members.add(toString);
    11. for(Field field : fields) {
    12. field.setAccessible(true);
    13. Object member = field.get(target);
    14. members.add(field.getName() + "=" + member);
    15. }
    16. return members.toString();
    17. }


    你也可以用這個樣例代碼完成錯誤處理方面.

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>