第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

編寫處理來自另一個函數的輸出的 PHP 函數時使用什么設計模式?

編寫處理來自另一個函數的輸出的 PHP 函數時使用什么設計模式?

PHP
浮云間 2022-07-22 18:48:18
我有兩個功能:myFunctionA()和myFunctionB().myFunctionA()返回一個Object包含Page_Type具有字符串值的鍵的值。myFunctionB()處理Object返回的多個條目myFunctionA(),包括Page_Type及其字符串值。稍后,myFunctionA()它被更新,因此它不再返回包含鍵的對象Page_Type,而是返回包含Page_Types數組值的鍵。因此,myFunctionB()現在也需要更新——它將不再處理Page_Type哪個是字符串,而是Page_Types哪個是數組。如果我理解正確(我可能沒有),以上是依賴請求的一個示例,并且可以通過(我認為)部署依賴注入模式(甚至可能是服務定位器模式)來避免它引發(fā)的大量重構?)反而 (??)但是,盡管閱讀了這個主題,我仍然不確定依賴注入如何在 PHP 或 Javascript 函數中工作(大部分解釋涉及編程語言C++和 OOP 概念Classes,而我正在處理 PHP 中的第三方函數和javascript)。有什么方法可以構造我的代碼,以便更新myFunctionA()(以任何重要方式)不需要我也更新myFunctionB()(以及所有其他調用的函數myFunctionA()- 例如myFunctionC(),myFunctionD()等myFunctionE())?如果myFunctionH()需要myFunctionG()需要myFunctionF()哪個需要myFunctionA()呢?我不希望myFunctionA()現在更新意味著另外三個函數(F和G)H都必須更新。嘗試回答:目前我能想到的最佳答案——這可能不是最佳實踐答案,因為我還不知道是否存在與我在上述問題中描述的問題相對應的正式問題——是以下重述我如何展示設置:我有兩個(不可變的)函數:myFunctionA__v1_0()和myFunctionB__v1_0().myFunctionA__v1_0()返回一個對象,其中包括 Page_Type具有字符串值的鍵。myFunctionB__v1_0()處理由 返回的 Object 中的許多條目myFunctionA__v1_0(),包括Page_Type及其字符串值。后來,myFunctionA__v1_0()仍然存在,但也成功了,myFunctionA__v2_0()它返回一個包含鍵的對象Page_Types- 它具有一個數組值。為了myFunctionB訪問由返回的對象myFunctionA__v2_0(),現在還需要一個myFunctionB__v1_1()能夠處理數組的對象Page_Types。這可以概括為:myFunctionB__v1_0()需要由返回的對象myFunctionA__v1_0()myFunctionB__v1_1()需要由返回的對象myFunctionA__v2_0()由于每個函數在正式命名后都變得不可變,所以永遠不會發(fā)生的是我們最終得到了一個myFunctionB__v1_0()要求返回的對象的示例myFunctionA__v2_0()。我不知道我是否以正確的方式接近這個,但這是迄今為止我想出的最好的方法。
查看完整描述

4 回答

?
有只小跳蛙

TA貢獻1824條經驗 獲得超8個贊

在提供程序的編程中很常見- 即。對其消費者myFunctionA()一無所知。處理這個問題的唯一正確方法是預先定義一個 API 并且永遠不要更改它;) myFunctionB()


我看不到對消費者進行版本控制的目的——這個原因必須是“下游” myFunctionB()——即。的消費者,myFunctionB()作者myFunctionB()無法控制...在這種情況下,它myFunctionB()本身成為提供者,作者將不得不處理這個問題(可能使用與您相同的模式)...但這不是您的要處理的問題。


至于您的提供者 myFunctionA():如果您不能預先為數據本身定義接口/API - 即。你知道數據的結構必須改變(以非向后兼容的方式),但你不知道如何......那么你將需要以一種或另一種方式對某些東西 進行版本控制。


你比大多數人領先幾英里,因為你看到了這一點,并從一開始就計劃好了。


避免myFunctionB()在某些時候對消費者進行更改的唯一方法是以向后兼容的方式對提供者進行所有更改。myFunctionA()您描述的更改不是向后兼容的,因為myFunctionB()在不修改的情況下不可能知道如何處理新輸出myFunctionA()。


您提出的解決方案聽起來應該可行。但是,至少有兩個缺點:


它要求您保留不斷增長的遺留功能列表,以防有任何消費者請求他們的數據。這將變得非常難以維護,并且從長遠來看可能是不可能的。

根據將來需要進行哪些更改,可能根本無法再生成輸出myFunctionA__v1_0()- 在您的示例中page_types,您在系統(tǒng)中添加了幾個的可能性 - 在這種情況下,您可能只需重寫v1_0以使用第一個和傳統(tǒng)的消費者會很高興。但是,如果您決定page_types從系統(tǒng)中完全放棄 的概念,則必須計劃完全刪除v1_0一種或另一種方式。因此,您需要建立一種與消費者溝通的方式。

處理這個問題的唯一正確方法仍然是預先定義一個 API 并且永遠不要更改它。


由于我們已經確定:


您將不得不進行向后不兼容的更改

您對消費者一無所知,并且您無權在需要時更改它們

我建議不要為您的數據定義一個不可變的 API,而是定義一個不可變的 API,允許您在消費者應該或必須升級時與他們進行通信。


這聽起來可能很復雜,但不一定是:


接受提供者中的版本參數:

這個想法是讓消費者明確告訴提供者返回哪個版本。


提供者可能如下所示:


function myFunctionA(string $version) {

    $page_types = ['TypeA', 'TypeB'];

    $page = new stdClass();

    $page->title = 'Page title';

    switch ($version) {

        case '1.0':

            $page->error = 'Version 1.0 no longer available. Please upgrade!';

            break;

        case '1.1':

            $page->page_type = $page_types[0];

            $page->warning = 'Deprecated version. Please upgrade!';

            break;

        case '2.0':

            $page->page_types = $page_types;

            break;

        default:

            $page->error = 'Unknown version: ' . $version;

            break;

    }

    return $page;

}

因此,提供者接受一個參數,該參數將包含消費者可以理解的版本——通常是消費者上次更新時最新的版本。


提供者盡最大努力提供所請求的版本


如果不可能有一個“合同”來通知消費者($page->error將存在于返回值上)

如果可能,但有可用的較新版本,則另一個“合同”已到位以通知消費者這一點($page->warning將存在于返回值上)。

并在消費者中處理一些案例:

消費者需要發(fā)送它期望的版本作為參數。


function myFunctionB() {

    //The consumer tells the provider which version it wants:

    $page = myFunctionA('2.0');

    if ($page->error) {

        //Notify developers and throw an error

        pseudo_notify_devs($page->error);

        throw new Exception($page->error);

    } else if ($page->warning) {

        //Notify developers

        pseudo_notify_devs($page->warning);

    }

    do_stuff_with($page);

}

舊版本的第二行myFunctionB()- 或完全不同的消費者myFunctionC()可能會要求舊版本:


$page = myFunctionA('1.1');

這使您可以隨時進行向后兼容的更改,而無需消費者做任何事情。您可以盡最大努力在可能的情況下仍然支持舊版本,從而在舊版使用者中提供“優(yōu)雅”的降級。


當您必須進行重大更改時,您可以繼續(xù)支持舊版本一段時間,然后最終將其完全刪除。


元信息

我不相信這會有用......但您可以使用過時的版本為消費者添加一些元信息:


function myFunctionA(string $version) {

    # [...]

    if ($page->error || $page->warning) {

        $page->meta = [

            'current_version' => '3.0',

            'API_docs' => 'http://some-url.fake'

        ]

    }

    return $page;

}

然后可以在消費者中使用它:


pseudo_notify_devs(

    $page->error .

    ' - Newest version: ' . $page->meta['current_version'] .

    ' - Docs: ' . $page->meta['API_docs']

);

......如果我是你,我會小心不要讓事情過于復雜......總是親吻


查看完整回答
反對 回復 2022-07-22
?
DIEA

TA貢獻1820條經驗 獲得超3個贊

通過將返回類型從字符串更改為數組,您似乎破壞了 myFunctionA 和 myFunctionB 之間的接口。我不認為 DI 可以提供幫助。



查看完整回答
反對 回復 2022-07-22
?
動漫人物

TA貢獻1815條經驗 獲得超10個贊

依賴注入在 OOP 上下文中更相關。但是,我在這里要做的主要事情是停止考慮返回可用的東西,并開始考慮這兩種方法如何協(xié)同工作以及它們的合同是什么。

弄清楚 myFunctionA() 的邏輯輸出是什么,將該合約編碼為一個對象,然后將您擁有的數據轉換為該格式。這樣,即使您在 myFunctionA() 中獲取數據的方式發(fā)生了變化,您也只需更新該一次轉換。

只要您遵守該合同(可以通過自定義對象表示)、myFunctionB() 和其他希望根據合同接收數據的方法,您就不必再更改這些方法。

所以我在這里的主要收獲是開始考慮你需要的數據,而不是在你收到它的結構中傳遞它,而是以它對你的應用程序最有意義的方式傳遞。


查看完整回答
反對 回復 2022-07-22
?
夢里花落0921

TA貢獻1772條經驗 獲得超6個贊

首先,這不是依賴注入。


你myFunctionA()可以被稱為生產者,因為它提供數據,它應該被證明是一個Data Structure. 您myFunctionB()可以被稱為消費者,因為它使用提供的數據myFunctionA。


因此,為了使您的生產者和消費者獨立工作,您需要在它們之間添加另一層,調用Converter. 該Converter層會將Data Structure提供的內容轉換為可以理解的Producer眾所周知的Data StructureConsumer


我真的建議您閱讀本書Clean Code第 6 章:對象和數據結構。這樣你就可以完全理解上面的概念,關于Data Structure


例子


假設我們有Data Structurecall Hand,有屬性右手和左手。


class Hand {

    private $rightHand;

    private $leftHand

    // Add Constructor, getter and setter

}

myFunctionA()將提供對象Hand,Hand是一個Data Structure


function myFunctionA() {

    $hand = Hand::createHand(); //Assume a function to create new Hand object

    return $hand;

}

假設我們還有另一個Data Structurecall Leg, Leg 將能夠通過 myFunctionB() 消費;


class Leg {

    private $rightLeg;

    private $leftLeg

    // Add Constructor, getter and setter

}

然后,我們需要有一個轉換器,在中間,從手轉換為腿,并使用myFunctionB()


class Converter {

    public static function convertFromHandToLeg($hand) {

        $leg = makeFromHand($hand); //Assume a method to convert from Hand to Leg

        return $leg; 

    }

}

myFunctionB(Converter::convertFromHandToLeg($hand))

因此,每當您編輯 的響應時myFunctionA(),意味著您將要編輯Data Structure的Hand。您只需要編輯Converter以確保它繼續(xù)Hand正確轉換Leg。你不需要觸摸myFunctionB,反之亦然。


當您有另一個Producer會Hand像您在問題中提到的那樣提供時,這將非常有幫助myFunctionC(),myFunctionD()...而且您還有許多其他Consumer會Leg像myFunctionH()...一樣消耗的myFunctionG()東西


希望這有幫助


查看完整回答
反對 回復 2022-07-22
  • 4 回答
  • 0 關注
  • 145 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號