2014-08-28 2 views
6

मुझे लगता है कि यह एक सामान्य प्रश्न (इसलिए PHP प्रतिबंधित नहीं है) ddd और कमांड पैटर्न के संबंध में है।PHP अनुप्रयोगों में कमांड पैटर्न: नियंत्रक कार्यों को कैसे संभालें?

मान लें कि मैं अपने नियंत्रक की निर्माण कार्रवाई के भीतर से CreatePostCommand निष्पादित करता हूं, कमांड को संभाला जाएगा और अंततः सफलतापूर्वक निष्पादित किया जाएगा। नियंत्रक को सूचित करने का उचित तरीका क्या है जो कमांड विफल होने या सफल होने पर वापस लौटने का जवाब देता है? आदेश दिया गया हैडलर एक डोमेन विशिष्ट घटना को आग लगाएगा, मैं कंट्रोलर को घटना में जोड़ सकता हूं, लेकिन यह काफी अजीब लगता है, यह भी हर स्थिति के लिए उचित नहीं है (उदाहरण के लिए एक पोस्ट कहीं और बनाया जा सकता है और नियंत्रक वास्तव में नहीं करता है इसके बारे में जानें :))।

public function createAction($title, $content) 
{ 
    $this->commandBus->execute(new CreatePostCommand($title, $content); 

    $this->render('…'); // what if the command execution failed? 
} 

इस पर कोई विचार?

+0

तो निष्पादन में विफल रहा है, तो एक अपवाद फेंका गया होता, लाइन आप टिप्पणी की है | भागा नहीं किया गया है, जिसका अर्थ है। –

+2

हाँ यकीन है। मुझे यहां और अधिक विशिष्ट होना चाहिए था।आइए मान लें कि आदेश सफलतापूर्वक निष्पादित किया गया है और मैं/पोस्ट/एडिट/{$ आईडी} पर रीडायरेक्ट करना चाहता हूं, नियंत्रक पोस्ट आईडी के बारे में अवगत नहीं होगा जब तक कि नियंत्रक और कमांड हैंडलर शेयर उदा। पद भंडार। क्या इससे अधिक समझदारी होती है। – iwyg

+0

कमांड से लौटने वाले मान पैटर्न को तोड़ देंगे। तो हाँ आप सही हैं कि दोनों नियंत्रक और कमांड हैंडलर को रेपो के बारे में जानना होगा। लेकिन अगर आपको कमांड से कुछ लौटने की ज़रूरत है तो उसे मज़ेदार पैटर्न पर नज़र डालें। –

उत्तर

1

मैं अगर तुम सच में तो DDD आदेश पैटर्न का पालन करने के लिए कोशिश कर रहे हैं आप एक आग के रूप में कमान बस का इलाज और अतुल्यकालिक प्रक्रिया है कि एक लंबे समय के पूरा करने के लिए समय लग सकता है भूल जाते हैं की जरूरत है लगता है।

तुरंत कमांड सत्यापनकर्ता नियंत्रक पर रीडायरेक्ट करने पर विचार करें। सक्रिय रूप से कमांड की स्थिति की जांच करने के लिए कमांड सत्यापनकर्ता पर निर्भर है और देखें कि यह काम करता है या नहीं।

ज्यादातर मामलों में, आदेश को सफलतापूर्वक समाप्त कर दिया है जाएगा और अपने सत्यापनकर्ता तो सामान्य प्रवाह जारी रखने के लिए एक बार फिर से अनुप्रेषित कर सकते हैं।

यदि आदेश विफल रहता है तो सत्यापनकर्ता एक उचित त्रुटि संदेश डालता है।

आदेश तो आप उपयोगकर्ता कि आदेश जारी रहने के दौरान बताए जबकि पूरे एक रीडायरेक्ट लूप कर सकते हैं का कार्य प्रगति पर है।

कुछ की तरह:

// Execute the command 
$command = new CreatePostCommand($title, $content); 
$this->commandBus->execute($command); 

return redirect '/command-verifier/' . $command->getId(); 

// The verification action 
public function verifyCommandAction($commandId) 

$commandStatus = $this->commandBus->getStatus($commandId); 

if ($commandStatus == SUCCESS) redirect to all is well; 

if ($commandStatus == FAILED) then oops; 

if ($commandStatus == IN_PROGRESS) then maybe pause a bit and redirect again while keeping the user informed. 

जाहिर है वहाँ पर जा रहा लहराते हाथ की काफ़ी है, लेकिन मुझे लगता है कि इस php जहां हर अनुरोध जमीन शून्य से शुरू होता है के साथ सबसे अधिक सामान्य दृष्टिकोण विशेष रूप से है।

+0

शायद मैं आपको गलत समझता हूं, लेकिन इसका मतलब यह होगा कि बाद के बिंदु पर $ कमांड ऑब्जेक्ट में आईडी आईडी असाइन की गई है? इसका मतलब यह अपरिवर्तनीय नहीं है। इस तकनीक की शक्ति का एक हिस्सा यह है कि आपका आदेश एक इरादा को इंगित कर रहा है, राज्य या व्यवहार नहीं - यह दृष्टिकोण उस प्रतिमान को तोड़ देता है। – Oddman

+0

और विकल्प है? यदि कोई पद बनाना है तो पोस्ट कैसे बनाया गया था या नहीं, तो आप सिग्नल कैसे करेंगे? – Cerad

+0

कुछ तरीके हैं - एक कमांड हैंडलर सफल पोस्ट सृजन (मानक व्यवहार) लौटाता है, लेकिन त्रुटि (थोड़ा सा ट्रिकियर) पर आप या तो अपवाद फेंक सकते हैं, या ऐसी सेवा लिख ​​सकते हैं जो नियंत्रकों के साथ उन अपेक्षाओं को प्रबंधित करे एक पर्यवेक्षक निर्भरता के रूप में इंजेक्शन जो कमांड निष्पादन के परिणाम के आधार पर सही प्रतिक्रिया तैयार कर सकता है। – Oddman

0

जिस तरह से मैं वर्तमान में ऐसा कर रहा हूं वह इस प्रकार है (लंबी पोस्ट बहाना)।

public function createAction($title, $content) { 
    try { 
     $post = $this->commandBus->execute(new CreatePostCommand($title, $content); 
    } 
    catch (Exception $e) { 
     return $this->render('some error template file', $e); 
    } 

    return $this->render('successful creation template file', $post); 
} 

इस तरह, आप एक पोस्ट बना रहे हैं और योजना के अनुसार सब कुछ हो जाता है तो, $ पद वस्तु लौट सकते हैं और आपके विचार करने के लिए कि भेजें। दूसरी ओर, एक अपवाद निष्पादन के दौरान फेंक दिया जाता है, तो आप उस त्रुटि को पकड़ने और एक दृश्य को भेजें।

public function createAction($title, $content) { 
    $service = new CreateActionService($title, $content); 

    return $service->create($this); 
} 

public function onError(Exception $e) { 
    return $this->render('some error template file', $e); 
} 

public function onSuccess($post) { 
    return $this->render('success', $post); 
} 
तो आपकी सेवा में

:

मेरे पसंदीदा तरीका नियंत्रक कॉल एक सेवा पर एक विधि है कि उस व्यवहार का प्रबंधन करता है, और करने के लिए नियंत्रक एक श्रोता कि प्रतिक्रियाओं प्रबंधन करता है, यानी के रूप में इंजेक्ट किया है। ..

public function create($listener) 
{ 
    try { 
     $this->commandBus->execute(new CreatePostCommand($title, $content); 
    } 
    catch (Exception $e) { 
     return $this->listener->onError($e); 
    } 

    return $this->listener->onSuccess($post); 
} 

इस तरह आपकी सेवा विभिन्न परिणामों प्रबंध कर रहा है कि आदेश हैंडलर वापस आ सकते हैं, और अपने नियंत्रक जवाब है कि आप अपनी प्रस्तुति परत को लौट चाह सकते हैं का प्रबंधन करने के लिए बस छोड़ दिया है।

+0

जब नियंत्रक कमांड को समाप्त करने के लिए प्रतीक्षा कर सकता है तो ठीक है। लेकिन डीडीडी की भूमि में हमारे पास अंतिम स्थिरता की धारणा है जहां ऑपरेशन समाप्त करने में मिनट, घंटे या दिन लग सकते हैं। दो पूरी तरह से अलग समस्याएं। – Cerad

+0

यह सच है, खासकर यदि आप सीक्यूआरएस सिस्टम जैसी चीजों के बारे में बात कर रहे हैं। किसी भी मामले में, समस्याएं हो सकती हैं और हो सकती हैं - और इस फैशन में इसका प्रबंधन करना मतलब है कि आप अप्रत्याशित परिस्थितियों के कारण होने वाली किसी भी समस्या का अच्छी तरह से देखभाल कर सकते हैं। – Oddman

संबंधित मुद्दे