অধ্যবসায়ের মোকাবেলায় কমান্ড হ্যান্ডলারগুলি ব্যবহার করার ধরণটি কীভাবে খাঁটি কার্যকরী ভাষায় ফিট করে, যেখানে আমরা আইও-সম্পর্কিত কোডটিকে যতটা সম্ভব পাতলা করতে চাই?
কোনও বস্তু-ভিত্তিক ভাষায় ডোমেন-চালিত ডিজাইন প্রয়োগ করার সময়, রাষ্ট্রীয় পরিবর্তনগুলি কার্যকর করতে কমান্ড / হ্যান্ডলার প্যাটার্নটি ব্যবহার করা সাধারণ । এই নকশায়, কমান্ড হ্যান্ডলারগুলি আপনার ডোমেন অবজেক্টগুলির শীর্ষে বসে থাকে এবং বিরক্তিকর দৃ pers়তা সম্পর্কিত যুক্তির জন্য যেমন रिपোজিটরিগুলি ব্যবহার এবং ডোমেন ইভেন্টগুলি প্রকাশ করার জন্য দায়বদ্ধ। হ্যান্ডলারগুলি আপনার ডোমেন মডেলের সর্বজনীন মুখ; ইউআই এর মতো অ্যাপ্লিকেশন কোড হ্যান্ডলারের কল করে যখন এটি ডোমেন অবজেক্টের অবস্থা পরিবর্তন করতে পারে।
সি # তে একটি স্কেচ:
public class DiscardDraftDocumentCommandHandler : CommandHandler<DiscardDraftDocument>
{
IDraftDocumentRepository _repo;
IEventPublisher _publisher;
public DiscardDraftCommandHandler(IDraftDocumentRepository repo, IEventPublisher publisher)
{
_repo = repo;
_publisher = publisher;
}
public override void Handle(DiscardDraftDocument command)
{
var document = _repo.Get(command.DocumentId);
document.Discard(command.UserId);
_publisher.Publish(document.NewEvents);
}
}
document
ডোমেইন বস্তুর ব্যবসার নীতি (যেমন অথবা "আপনি যদি একটি নথি যা ইতিমধ্যে বাতিল করা হয়েছে বাতিল করতে পারছি না" "ব্যবহারকারী ডকুমেন্ট বাতিল করতে অনুমতি থাকা উচিত") বাস্তবায়নের জন্য এবং ডোমেইন ঘটনা আমরা প্রকাশ করতে হবে জেনারেট করার জন্য দায়ী ( document.NewEvents
would একটি হতে পারে IEnumerable<Event>
এবং সম্ভবত একটি DocumentDiscarded
ইভেন্ট থাকবে)।
এটি একটি দুর্দান্ত নকশা - এটি প্রসারিত করা সহজ (আপনি আপনার ডোমেন মডেলটি পরিবর্তন না করে নতুন কমান্ড হ্যান্ডলার যোগ করে নতুন ব্যবহারের কেস যুক্ত করতে পারেন) এবং কীভাবে অবজেক্টগুলি বজায় রাখা যায় তা সম্পর্কে অজ্ঞতাবাদী (আপনি সহজেই কোনও মঙ্গোর জন্য এনএইচবারনেট সংগ্রহস্থল সরিয়ে নিতে পারবেন) সংগ্রহস্থল, বা একটি ইভেন্টস্টোর প্রকাশকের জন্য একটি রেবিট এমকিউ প্রকাশককে স্যুপ করুন) যা জাল এবং মক ব্যবহার করে পরীক্ষা করা সহজ করে তোলে। এটি মডেল / ভিউ বিভাজনও মেনে চলেন - কমান্ড হ্যান্ডলারের কোনও ব্যাচ কাজ, জিইউআই, বা কোনও আরএসটি এপিআই দ্বারা ব্যবহৃত হচ্ছে কিনা সে সম্পর্কে কোনও ধারণা নেই।
খাঁটি-কার্যকরী ভাষায় হাস্কেলের মতো আপনি কমান্ড হ্যান্ডলারটিকে মোটামুটি এভাবে মডেল করতে পারেন:
newtype CommandHandler = CommandHandler {handleCommand :: Command -> IO Result)
data Result a = Success a | Failure Reason
type Reason = String
discardDraftDocumentCommandHandler = CommandHandler handle
where handle (DiscardDraftDocument documentID userID) = do
document <- loadDocument documentID
let result = discard document userID :: Result [Event]
case result of
Success events -> publishEvents events >> return result
-- in an event-sourced model, there's no extra step to save the document
Failure _ -> return result
handle _ = return $ Failure "I expected a DiscardDraftDocument command"
আমি যে অংশটি বুঝতে চেষ্টা করছি তা এখানে। সাধারণত, কিছু প্রকারের 'প্রেজেন্টেশন' কোড আসবে যা জিইউআই বা একটি রেস্ট এপিআইয়ের মতো কমান্ড হ্যান্ডলারে কল করে। সুতরাং এখন আমাদের প্রোগ্রামে দুটি স্তর রয়েছে যার জন্য আইও করা দরকার - কমান্ড হ্যান্ডলার এবং ভিউ - যা হাস্কেলের একটি বড় সংখ্যা নয়।
আমি যতদূর পেরে উঠতে পারি, এখানে দুটি বিরোধী শক্তি রয়েছে: একটি হ'ল মডেল / ভিউ বিচ্ছেদ এবং অন্যটি হ'ল মডেলটি ধরে রাখা দরকার। মডেলটি কোথাও ধরে রাখতে আইও কোড থাকা দরকার , তবে মডেল / ভিউ বিভাজনটি বলে যে আমরা অন্য সমস্ত আইও কোড সহ উপস্থাপনা স্তরটিতে রাখতে পারি না।
অবশ্যই, একটি "সাধারণ" ভাষায়, আইও কোথাও ঘটতে পারে (এবং করবে)। ভাল ডিজাইন নির্দেশ দেয় যে বিভিন্ন ধরণের আইও আলাদা রাখতে হবে, তবে সংকলক এটি প্রয়োগ করে না।
সুতরাং: আমরা মডেলটির ক্রমাগত যখন আইও কোডটি প্রান্তের প্রান্তে ধাক্কা দেওয়ার আকাঙ্ক্ষার সাথে মডেল / ভিউ বিচ্ছিন্নতার সাথে কীভাবে মিলিত করব? আমরা কীভাবে দুটি ভিন্ন ধরণের আইও আলাদা রাখব , তবে সমস্ত খাঁটি কোড থেকে এখনও দূরে রেখেছি?
আপডেট : অনুগ্রহটির মেয়াদ 24 ঘন্টােরও কম সময়ের মধ্যে শেষ হয়। আমার মনে হয় না যে বর্তমানের উত্তরগুলির মধ্যে কোনওটিই আমার প্রশ্নের সমাধান করেছে। @ পাথারিয়ানের শিখার মন্তব্য সম্পর্কে মন্তব্য আশাপ্রদজনক acid-state
বলে মনে হচ্ছে, তবে এটি কোনও উত্তর নয় এবং এটির বিশদর অভাব রয়েছে। আমি এই পয়েন্টগুলি নষ্ট করতে যেতে ঘৃণা করব!
acid-state
দেখতে দুর্দান্ত লাগছে, এই লিঙ্কটির জন্য ধন্যবাদ। এপিআই ডিজাইনের ক্ষেত্রে এটি এখনও আবদ্ধ বলে মনে হচ্ছে IO
; আমার প্রশ্নটি কীভাবে একটি অধ্যবসায় কাঠামোটি একটি বৃহত স্থাপত্যের সাথে ফিট করে into আপনি কি এমন কোনও ওপেন-সোর্স অ্যাপ্লিকেশন সম্পর্কে জানেন যা acid-state
উপস্থাপনা স্তরের পাশাপাশি ব্যবহার করে এবং দুটি পৃথক রাখতে সফল হয়?
Query
এবং Update
monads বেশ দূরে থেকে সরিয়ে ফেলা হয় IO
, আসলে। আমি একটি উত্তরের একটি সহজ উদাহরণ দেওয়ার চেষ্টা করব।
acid-state
আপনি যা বর্ণনা করছেন তার কাছাকাছি মনে হচ্ছে ।