• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            qiezi的學(xué)習(xí)園地

            AS/C/C++/D/Java/JS/Python/Ruby

              C++博客 :: 首頁(yè) :: 新隨筆 ::  ::  :: 管理 ::
            Aspect C++支持“虛切面”,類似C++中的虛函數(shù)。方面可以繼承,“派生方面”可以重寫“基方面”的“虛切面”,類似C++中的類繼承。

            有了這個(gè)特性,就可以實(shí)現(xiàn)一些模式了,這里列出AOP中經(jīng)典的觀察者(Observer)模式[注]

            [注]這個(gè)說(shuō)法不太妥當(dāng),觀察者模式是經(jīng)典的設(shè)計(jì)模式,這里的意思是說(shuō)AOP經(jīng)典的觀察者模式實(shí)現(xiàn)。

            它的代碼如下:

            aspect ObserverPattern {
                
            // 管理subjects和observers的數(shù)據(jù)結(jié)構(gòu)
                
            // TODO 
            public:
                
            // 角色接口
                struct ISubject {};
                
            struct IObserver {
                    
            virtual void update(ISubject *= 0;
                };
                
            // 在派生方面中被重寫
                pointcut virtual observers () = 0;
                pointcut 
            virtual subjects () = 0;
                
            // subjectChange()匹配所有非const方法,但限定了subjects類
                pointcut virtual subjectChange () =
                    execution(
            " % ::%(" && !" % ::%() const")
                    
            && within(subjects ());
                
            // 為每個(gè)subject/observer類增加基類,并插入通知代碼
                advice observers () : baseclass(IObserver );
                advice subjects () : baseclass(ISubject );
                advice subjectChange () : after() {
                    ISubject 
            * subject = tjp->that ();
                    updateObservers (subject );
                }
                
            // 具體操作
                void updateObservers (ISubject * sub ) {  }
                
            void addObserver (ISubject * sub , IObserver * ob ) {  }
                
            void remObserver (ISubject * sub , IObserver * ob ) {  }
            };

            其中“...” 部分是需要完成的C++實(shí)現(xiàn)代碼,可以簡(jiǎn)單實(shí)現(xiàn)一個(gè):
            #ifndef __OBSERVER_PATTERN_AH__
            #define __OBSERVER_PATTERN_AH__

            #include 
            <map>
            #include 
            <set>
            using namespace std;

            aspect ObserverPattern {
                
            // 管理subjects和observers的數(shù)據(jù)結(jié)構(gòu)
                struct ISubject;
                
            struct IObserver;
                map 
            < ISubject*set<IObserver*> > listeners;
            public:
                
            // 角色接口
                struct ISubject {};
                
            struct IObserver {
                    
            virtual void update(ISubject *= 0;
                };
                
            // 在派生方面中被重寫
                pointcut virtual observers () = 0;
                pointcut 
            virtual subjects () = 0;
                
            // subjectChange()匹配所有非const方法
                pointcut virtual subjectChange () =
                    execution(
            " % ::%(" && !" % ::%() const")
                    
            && within(subjects ());
                
            // 為每個(gè)subject/observer類增加基類,并插入通知代碼
                advice observers () : baseclass(IObserver );
                advice subjects () : baseclass(ISubject );
                advice subjectChange () : after() {
                    ISubject 
            * subject = tjp->that ();
                    updateObservers (subject );
                }
                
            // 具體操作
                void updateObservers (ISubject * sub ) {
                    
            const set<IObserver*>& observers = listeners[sub];
                    
            set<IObserver*>::const_iterator iter = observers.begin();
                    
            for (; iter != observers.end(); iter ++)
                    {
                        (
            *iter)->update(sub);
                    }
                }
                
            void addObserver (ISubject * sub , IObserver * ob ) { listeners[sub].insert(ob); }
                
            void removeObserver (ISubject * sub , IObserver * ob ) { listeners[sub].erase(ob); }
            };

            #endif // __OBSERVER_PATTERN_AH__

            保存為ObserverPattern.ah供下面使用。

            下面編寫一個(gè)應(yīng)用實(shí)例:

            1、car.h

            #ifndef __CAR_H__
            #define __CAR_H__

            #include 
            <string>
            using namespace std;

            class Car
            {
                
            string name;
                
            int x;
                
            int y;
                
            enum Direction{South, East, North, West};
                Direction direction;

                Car (
            const Car&);
                Car
            & operator = (const Car&);
            public:
                Car (
            const string& name);
                
            void turnLeft ();
                
            void turnRight ();
                
            void forward (size_t step);

                
            const string& getName() const;
                
            int getX () const;
                
            int getY () const;
                Direction getDirection () 
            const;
            };



            #endif // __CAR_H__


            2、car.cc

            #include 
            "car.h"
            #include 
            <cassert>

            Car::Car (
            const string& name_)
            : name(name_), x(
            0), y(0), direction(South)
            {
            }

            void Car::turnLeft ()
            {
                
            if (direction == West)
                    direction 
            = South;
                
            else
                    direction 
            = (Direction)(int(direction) + 1);
            }

            void Car::turnRight ()
            {
                
            if (direction == South)
                    direction 
            = West;
                
            else
                    direction 
            = (Direction)(int(direction) - 1);
            }

            void Car::forward (size_t step)
            {
                
            switch (direction)
                {
                
            case South:
                    y 
            += step; break;
                
            case East:
                    x 
            += step; break;
                
            case North:
                    y 
            -= step; break;
                
            case West:
                    x 
            -= step; break;
                
            default:
                    assert (
            !"Invalid direction");
                }
            }

            const string& Car::getName() const
            {
                
            return name;
            }

            int Car::getX() const
            {
                
            return x;
            }

            int Car::getY() const
            {
                
            return y;
            }

            Car::Direction Car::getDirection() 
            const
            {
                
            return direction;
            }

            3、dummy.h(這個(gè)用來(lái)測(cè)試Aspect C++的匹配模式會(huì)不會(huì)混亂)
            #ifndef __DUMMY_H__
            #define __DUMMY_H__

            class Dummy
            {
            public:
                
            void test_non_const (){}
                
            void test_const () const {}
            };

            #endif // __DUMMY_H__

            4、main.cc
            #include "car.h"
            #include 
            "dummy.h"

            int main()
            {
                Car car(
            "No.1");
                car.turnLeft();
                car.forward(
            3);
                car.turnLeft();
                car.forward(
            9);
                car.turnRight();
                car.forward(
            12);

                Car car1(
            "No.2");
                car1.forward(
            7);
                car1.turnLeft();
                car1.forward(
            3);

                car.forward(
            5);

                Dummy dummy;
                dummy.test_non_const();
                dummy.test_const();
                
                
            return 0;
            }

            這個(gè)程序編譯運(yùn)行,沒(méi)有任何輸出。有時(shí)候?yàn)榱吮O(jiān)視對(duì)象的狀態(tài),可以在執(zhí)行一個(gè)操作后加上一些打印狀態(tài)的代碼,當(dāng)然這樣比較繁瑣;也可以在各個(gè)操作函數(shù)中加入這些代碼,但修改已經(jīng)寫好的代碼總是不太舒服。

            下面先實(shí)現(xiàn)一個(gè)Car狀態(tài)打印類:

            5、car_logging.h
            #ifndef __CAR_LOGGING__
            #define __CAR_LOGGING__

            #include 
            "car.h"
            #include 
            <iostream>
            using namespace std;

            class CarLogging
            {
            public:
                
            void printCarInfo (const Car& car)
                {
                    
            static const char* direction_str[] = {"South""East""North""West"};
                    cout 
            << "Car name: " << car.getName()
                        
            << ", direction: " << direction_str[int(car.getDirection())] 
                        
            << ", x: " << car.getX() 
                        
            << ", y: " << car.getY() 
                        
            << endl;
                }
            };

            extern CarLogging g_carLogging;

            #endif // __CAR_LOGGING__

            6、car_logging.cc
            #include "car_logging.h"

            CarLogging g_carLogging;

            7、CarLoggingObserver.ah
            #ifndef __CAR_LOGGING_OBSERVER_AH__
            #define __CAR_LOGGING_OBSERVER_AH__

            #include 
            "ObserverPattern.ah"
            #include 
            "car.h"
            #include 
            "car_logging.h"

            aspect CarLoggingObserver : 
            public ObserverPattern {
                
            // 定義方面(ointcuts)
                pointcut subjects() = "Car";
                pointcut observers() 
            = "CarLogging";
            public:
                advice observers() :
                
            void update( ObserverPattern::ISubject* sub ) {
                    printCarInfo (
            *(Car*)sub);
                }

                advice construction (classes(subjects())) : after()
                {
                    addObserver(tjp
            ->that(), &g_carLogging);
                }

                advice destruction (classes(subjects())) : before()
                {
                    removeObserver(tjp
            ->that(), &g_carLogging);
                }
            };

            #endif // __CAR_LOGGING_OBSERVER_AH__

            這個(gè)方面重寫了subjects以及observers切面,并定義了observers在update被調(diào)用時(shí)執(zhí)行的操作,另外還在Car的構(gòu)造函數(shù)和析構(gòu)函數(shù)中添加了注冊(cè)和注銷代碼。

            運(yùn)行ac++生成代碼,編譯并運(yùn)行,結(jié)果如下:

            這里演示的例子依舊選擇了不影響原始程序的做法,網(wǎng)上很多資料都把這個(gè)模式和實(shí)現(xiàn)代碼結(jié)合起來(lái),由于Aspect C++編譯速度還是很慢,所以選擇“外掛”的方式,這樣不需要這些方面時(shí),直接編譯C++代碼即可。

            關(guān)于Aspect C++以及AOP,還有許多話題,不過(guò)不打算再繼續(xù)了,AOP是個(gè)廣泛的議題,局限在某一實(shí)現(xiàn)上只會(huì)使我們眼界變窄。

            AOP被稱為設(shè)計(jì)模式最佳實(shí)踐者,它當(dāng)之無(wú)愧。網(wǎng)上還有很多AOP實(shí)踐設(shè)計(jì)模式的資料。
            posted on 2005-12-17 10:21 qiezi 閱讀(1713) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++
            久久久久人妻一区精品| 一个色综合久久| 伊人久久综在合线亚洲2019| 国产亚洲美女精品久久久| 天天做夜夜做久久做狠狠| 热re99久久6国产精品免费| 91麻精品国产91久久久久| 18禁黄久久久AAA片| 久久精品免费观看| 99蜜桃臀久久久欧美精品网站| 国产99精品久久| 精品久久久无码人妻中文字幕| 久久最新精品国产| 国产激情久久久久久熟女老人| 国产成人久久久精品二区三区| 亚洲国产精品无码久久久蜜芽| 国产精品日韩深夜福利久久| 久久久久国产精品嫩草影院| 亚洲国产精品人久久| 国产亚洲色婷婷久久99精品| 国产精品99久久久精品无码| 久久国产福利免费| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久免费美女视频| 久久无码中文字幕东京热| 久久精品中文字幕第23页| 亚洲国产精久久久久久久| 久久91精品国产91久久小草| 日产精品久久久久久久性色| 久久婷婷五月综合97色直播| 色婷婷噜噜久久国产精品12p| 久久WWW免费人成—看片| 久久国产精品免费| 久久夜色精品国产www| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 久久99久国产麻精品66| 中文精品99久久国产| 中文字幕精品久久久久人妻| 亚洲国产精品无码久久久久久曰| 国产精品欧美亚洲韩国日本久久 | 蜜臀av性久久久久蜜臀aⅴ麻豆|