国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ZStack源碼剖析之設(shè)計(jì)模式鑒賞——三駕馬車

honhon / 2249人閱讀

摘要:但新增模塊的結(jié)構(gòu)卻還是大致相同,此即是的經(jīng)典設(shè)計(jì)模式這套模式也被開發(fā)者稱為三駕馬車。領(lǐng)域?qū)佣x負(fù)責(zé)表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則。

本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog...
前言

隨著ZStack的版本迭代,其可以掌管的資源也越來越多。但新增模塊的結(jié)構(gòu)卻還是大致相同,此即是ZStack的經(jīng)典設(shè)計(jì)模式——這套模式也被開發(fā)者稱為ZStack三駕馬車

實(shí)例分析

以PrimaryStorage為例,其APIMsg的真正邏輯處理第一站就是PrimaryStorageManagerImpl。

如果是對(duì)特定的PrimaryStorage進(jìn)行操作,將會(huì)通過相應(yīng)的Factory得出對(duì)應(yīng)類型并轉(zhuǎn)發(fā)至相應(yīng)的Base:

    private void passThrough(PrimaryStorageMessage pmsg) {
        PrimaryStorageVO vo =  dbf.findByUuid(pmsg.getPrimaryStorageUuid(), PrimaryStorageVO.class);
        if (vo == null && allowedMessageAfterSoftDeletion.contains(pmsg.getClass())) {
            PrimaryStorageEO eo = dbf.findByUuid(pmsg.getPrimaryStorageUuid(), PrimaryStorageEO.class);
            vo = ObjectUtils.newAndCopy(eo, PrimaryStorageVO.class);
        }

        Message msg = (Message) pmsg;
        if (vo == null) {
            String err = String.format("Cannot find primary storage[uuid:%s], it may have been deleted", pmsg.getPrimaryStorageUuid());
            bus.replyErrorByMessageType(msg, errf.instantiateErrorCode(SysErrors.RESOURCE_NOT_FOUND, err));
            return;
        }

        PrimaryStorageFactory factory = getPrimaryStorageFactory(PrimaryStorageType.valueOf(vo.getType()));
        PrimaryStorage ps = factory.getPrimaryStorage(vo);
        ps.handleMessage(msg);
    }

PrimaryStorageFactory是一個(gè)接口,在此基礎(chǔ)上有各式各樣的實(shí)現(xiàn):如Local、CephNFS等。

public interface PrimaryStorageFactory {
    PrimaryStorageType getPrimaryStorageType();

    PrimaryStorageInventory createPrimaryStorage(PrimaryStorageVO vo, APIAddPrimaryStorageMsg msg);

    PrimaryStorage getPrimaryStorage(PrimaryStorageVO vo);

    PrimaryStorageInventory getInventory(String uuid);
}

這就像現(xiàn)實(shí)中的模型一樣——在ZStack中可以有PrimaryStorage,而且可以有不同類型的PrimaryStorage:

PrimaryStorage:

Local

Ceph

NFS

這在軟件工程中即是一種分離領(lǐng)域(Layered Architecture)的具象。應(yīng)用層對(duì)應(yīng)ZStack的ManagerImpl,而Base更像是領(lǐng)域?qū)印?/p> 應(yīng)用層

應(yīng)用層的定義應(yīng)該是:

定義軟件要完成的任務(wù),并且指揮表達(dá)領(lǐng)域概念的對(duì)象來解決問題。這一層負(fù)責(zé)的工作對(duì)業(yè)務(wù)來說意義重大,也是與其他系統(tǒng)的應(yīng)用層進(jìn)行交互的必要渠道。

應(yīng)用層要盡量簡(jiǎn)單,不包含業(yè)務(wù)規(guī)則或者知識(shí),而只為下一次的領(lǐng)域?qū)ο髤f(xié)調(diào)任務(wù),分配工作,使它們互相協(xié)作。它沒有反映業(yè)務(wù)情況的狀態(tài),但是卻可以具有另外一種狀態(tài),為用戶或程序顯示某個(gè)任務(wù)的進(jìn)度。

而在ZStack中,的確也像上面說的如此。在源碼中我們可以看到,對(duì)實(shí)例操作的API全部被轉(zhuǎn)發(fā)到了Base層去,而Manager這里handle的往往是一些過濾性、Get型API,如APIListPrimaryStorageMsg、APIGetPrimaryStorageMsgAPIGetPrimaryStorageTypesMsg等。

Manager即是API(這里API不僅僅是APIxxxMsg,同時(shí)包含用于通信的內(nèi)部Msg。注意,它們都implements自Message這個(gè)接口)的入口,以及用于管理服務(wù)的生命周期。

領(lǐng)域?qū)?/b>

定義:

負(fù)責(zé)表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則。盡管保存業(yè)務(wù)狀態(tài)的技術(shù)細(xì)節(jié)由基礎(chǔ)設(shè)施層(在ZStack如DataBaseFacade即是),但是反映業(yè)務(wù)情況的狀態(tài)是由本層控制并且使用的。注意,領(lǐng)域?qū)邮菢I(yè)務(wù)軟件的核心。

以PrimaryStorageBase為例,其本身對(duì)應(yīng)了DB中的一條記錄,并且在改變狀態(tài)后也Refresh自己。并對(duì)操作多帶帶實(shí)例的Msg進(jìn)行handle。

通信

雖然分了層,并且關(guān)系是松散的。但是各個(gè)層之間也是需要通信的,那么層與層之間只能是單向的。上層可以直接使用或操作下層元素,方法是通過調(diào)用下層元素的公共接口,保持對(duì)下層元素的引用(至少是暫時(shí)的),以及采用常規(guī)的交互手段。而如果下層元素需要與上層元素通信,則需要采用另一種通信機(jī)制——比如回調(diào)或者Observers模式(在ZStack中即是ExtensionPoint)。

回調(diào)

我們還是以PrimaryStorageBase為例。在其做鏈接操作時(shí),邏輯如下:

    private void doConnect(ConnectParam param, final Completion completion) {
        thdf.chainSubmit(new ChainTask(completion) {
            @Override
            public String getSyncSignature() {
                return String.format("reconnect-primary-storage-%s", self.getUuid());
            }

            @Override
            public void run(SyncTaskChain chain) {
                changeStatus(PrimaryStorageStatus.Connecting);

                connectHook(param, new Completion(chain, completion) {
                    @Override
                    public void success() {
                        self = dbf.reload(self);
                        changeStatus(PrimaryStorageStatus.Connected);
                        logger.debug(String.format("successfully connected primary storage[uuid:%s]", self.getUuid()));

                        RecalculatePrimaryStorageCapacityMsg rmsg = new RecalculatePrimaryStorageCapacityMsg();
                        rmsg.setPrimaryStorageUuid(self.getUuid());
                        bus.makeLocalServiceId(rmsg, PrimaryStorageConstant.SERVICE_ID);
                        bus.send(rmsg);

                        tracker.track(self.getUuid());

                        completion.success();
                        chain.next();
                    }

                    @Override
                    public void fail(ErrorCode errorCode) {
                        tracker.track(self.getUuid());

                        self = dbf.reload(self);
                        changeStatus(PrimaryStorageStatus.Disconnected);
                        logger.debug(String.format("failed to connect primary storage[uuid:%s], %s", self.getUuid(), errorCode));
                        completion.fail(errorCode);
                        chain.next();
                    }
                });
            }

            @Override
            public String getName() {
                return getSyncSignature();
            }
        });
    }

而不同的connectHook都有不同的實(shí)現(xiàn)。

在抽象等級(jí)上,PrimaryStorageBase是比圖中的這些Base高的。而這類具象Base可以Message返回Success或者Fail使高層Base做出不同的決策。

Observers

繼續(xù),在PrimaryStorageBase中,其中handle APIAttachPrimaryStorageToClusterMsg的地方會(huì)做事件發(fā)送:

 extpEmitter.preAttach(self, msg.getClusterUuid());

其會(huì)發(fā)送向:

在這里,一個(gè)Base通過了Observers模式向某個(gè)ManagerImpl發(fā)送了事件,實(shí)現(xiàn)了下層往上層的通信。

小結(jié)

在大型軟件工程中,我們通常會(huì)給這樣的應(yīng)用劃分層次。分別在每層中進(jìn)行設(shè)計(jì),使其具有內(nèi)聚性并且只依賴于它的下層,而下層與上層也只有松散的耦合。這使得模型含義豐富,結(jié)構(gòu)清晰。也使得整個(gè)應(yīng)用架構(gòu)更加茁壯。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/68279.html

相關(guān)文章

  • ZStack源碼剖析二次開發(fā)——可擴(kuò)展框架

    摘要:但在實(shí)際的二次開發(fā)中,這些做法未必能夠完全滿足需求。在源碼剖析之核心庫(kù)鑒賞一文中,我們了解到是的基礎(chǔ)設(shè)施之一,同時(shí)也允許通過顯示聲明的方式來聲明。同理,一些也可以使用繼承進(jìn)行擴(kuò)展。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack博文-5.通用插件系統(tǒng)中,官方提出了幾個(gè)較為經(jīng)典的擴(kuò)展方式。但在實(shí)際的二次開發(fā)中,這些做法未必...

    lolomaco 評(píng)論0 收藏0
  • 談?wù)劥a——如何避免寫出糟糕if...else語(yǔ)句

    摘要:源碼剖析之設(shè)計(jì)模式鑒賞策略模式小結(jié)在這篇文章中筆者和大家分享幾個(gè)減少的小由于這些都會(huì)有一定的限制因此還向大家介紹了幾個(gè)能夠避免寫出糟糕的的設(shè)計(jì)模式并使用觀察者模式簡(jiǎn)單的改進(jìn)了仲裁者模式的例子 本文首發(fā)于數(shù)據(jù)浮云:https://mp.weixin.qq.com/s?__... 在寫代碼的日常中,if...else語(yǔ)句是極為常見的.正因其常見性,很多同學(xué)在寫代碼的時(shí)候并不會(huì)去思考其在目...

    huhud 評(píng)論0 收藏0
  • ZStack源碼剖析設(shè)計(jì)模式鑒賞——策略模式

    摘要:能夠整體地替換算法,能讓我們輕松地以不同的算法去解決一個(gè)問題,這種模式就是模式。這個(gè)類是在發(fā)布前常在中被使用的一個(gè)類,代碼如下以為例,從語(yǔ)義上來說就是為了中的每個(gè)元素調(diào)用函數(shù)。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 無論什么程序,其目的都是解決問題。而為了解決問題,我們又需要編寫特定的算法。使用Strategy模式可以整體地替...

    Eric 評(píng)論0 收藏0
  • ZStack源碼剖析核心庫(kù)鑒賞——Defer

    摘要:本文首發(fā)于泊浮目的專欄在語(yǔ)言中,有一個(gè)關(guān)鍵字叫做其作用是在函數(shù)前執(zhí)行。一般有兩種用法在該函數(shù)拋出異常時(shí)執(zhí)行。在該函數(shù)返回前執(zhí)行。這里的放入來自系統(tǒng)啟動(dòng)時(shí)利用反射所做的一個(gè)行為。因此并不會(huì)影響使用時(shí)的性能。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 在Go語(yǔ)言中,有一個(gè)關(guān)鍵字叫做defer——其作用是在函數(shù)return前執(zhí)行。在ZStac...

    DevWiki 評(píng)論0 收藏0
  • ZStack源碼剖析核心庫(kù)鑒賞——Defer

    摘要:本文首發(fā)于泊浮目的專欄在語(yǔ)言中,有一個(gè)關(guān)鍵字叫做其作用是在函數(shù)前執(zhí)行。一般有兩種用法在該函數(shù)拋出異常時(shí)執(zhí)行。在該函數(shù)返回前執(zhí)行。這里的放入來自系統(tǒng)啟動(dòng)時(shí)利用反射所做的一個(gè)行為。因此并不會(huì)影響使用時(shí)的性能。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 在Go語(yǔ)言中,有一個(gè)關(guān)鍵字叫做defer——其作用是在函數(shù)return前執(zhí)行。在ZStac...

    ymyang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<