পরিষ্কার আর্কিটেকচার: উপস্থাপক বা ডেটার রিটার্নিং যুক্ত কেস ব্যবহার করবেন?


42

ক্লিন আর্কিটেকচার একটি ব্যবহারের ক্ষেত্রে উপস্থাপক (যা ইনজেকশনের হয় চোবান নিম্নলিখিত,) প্রকৃত বাস্তবায়ন কল ইন্টারঅ্যাক্টার প্রতিক্রিয়া / প্রদর্শন হ্যান্ডেল করতে দেওয়া দাড়ায়। যাইহোক, আমি এই আর্কিটেকচারটি বাস্তবায়নকারী ব্যক্তিদের, ইন্টারেক্টর থেকে আউটপুট ডেটা ফিরিয়ে আনতে এবং তারপরে নিয়ামককে (অ্যাডাপ্টারের স্তরে) কীভাবে এটি পরিচালনা করবেন তা সিদ্ধান্ত নিতে দিন। ইন্টারেক্টরের সাথে স্পষ্টভাবে ইনপুট এবং আউটপুট পোর্টগুলি সংজ্ঞায়িত না করা ছাড়াও দ্বিতীয় সমাধানটি কি অ্যাপ্লিকেশন স্তরটির বাইরে অ্যাপ্লিকেশন দায়িত্বগুলি ফাঁস হয়?

ইনপুট এবং আউটপুট পোর্ট

ক্লিন আর্কিটেকচার সংজ্ঞা এবং বিশেষত একটি নিয়ামক, একটি ব্যবহারের ক্ষেত্রে ইন্টারেক্টর এবং উপস্থাপকের মধ্যে সম্পর্কের বর্ণনা দেওয়ার জন্য সামান্য ফ্লো ডায়াগ্রাম বিবেচনা করে , "ইউজ কেস আউটপুট পোর্ট" কী হওয়া উচিত তা আমি সঠিকভাবে বুঝতে পেরেছি কিনা তা নিশ্চিত নই।

ষড়ভুজ আর্কিটেকচারের মতো পরিষ্কার আর্কিটেকচার প্রাথমিক পোর্ট (পদ্ধতি) এবং গৌণ পোর্টগুলির (অ্যাডাপ্টারের দ্বারা প্রয়োগ করা ইন্টারফেস) মধ্যে পার্থক্য করে। যোগাযোগের প্রবাহ অনুসরণ করার পরে, আমি প্রত্যাশা করি "ইউজ কেস ইনপুট পোর্ট" একটি প্রাথমিক বন্দর হবে (সুতরাং কেবল একটি পদ্ধতি), এবং "ইন্টারফেস কেস আউটপুট পোর্ট" প্রয়োগ করা হবে একটি ইন্টারফেস, সম্ভবত কোনও নির্মাণকারী যুক্তি আসল অ্যাডাপ্টার গ্রহণ করবে, যাতে ইন্টারেক্টর এটি ব্যবহার করতে পারে।

কোড উদাহরণ

একটি কোড উদাহরণ তৈরি করতে, এটি নিয়ামক কোড হতে পারে:

Presenter presenter = new Presenter();
Repository repository = new Repository();
UseCase useCase = new UseCase(presenter, repository);
useCase->doSomething();

উপস্থাপক ইন্টারফেস:

// Use Case Output Port
interface Presenter
{
    public void present(Data data);
}

অবশেষে, ইন্টারেক্টর নিজেই:

class UseCase
{
    private Repository repository;
    private Presenter presenter;

    public UseCase(Repository repository, Presenter presenter)
    {
        this.repository = repository;
        this.presenter = presenter;
    }

    // Use Case Input Port
    public void doSomething()
    {
        Data data = this.repository.getData();
        this.presenter.present(data);
    }
}

উপস্থাপককে কল করার কথোপকথনে

পূর্ববর্তী ব্যাখ্যাটি উপরোক্ত চিত্রটি নিজেই দ্বারা নিশ্চিত হওয়া গেছে বলে মনে হয় যেখানে নিয়ামক এবং ইনপুট পোর্টের মধ্যে সম্পর্কটি একটি "তীক্ষ্ণ" মাথাযুক্ত একটি শক্ত তীর দ্বারা প্রতিনিধিত্ব করে ("সংঘের" জন্য ইউএমএল, যার অর্থ "একটি" থাকে, যেখানে কন্ট্রোলারের একটি "ব্যবহারের কেস থাকে", যখন উপস্থাপক এবং আউটপুট পোর্টের মধ্যে সম্পর্ক একটি "সাদা" মাথা ("উত্তরাধিকারের জন্য ইউএমএল") দ্বারা দৃ a় তীর দ্বারা প্রতিনিধিত্ব করে, যা "বাস্তবায়ন" এর জন্য এক নয়, তবে সম্ভবত এটি যাইহোক অর্থ)।

তদ্ব্যতীত, অন্য একটি প্রশ্নের উত্তরে রবার্ট মার্টিন হুবহু ব্যবহারের ক্ষেত্রে বর্ণনা করেছেন যেখানে ইন্টারেক্টর একটি উপস্থাপককে পড়ার অনুরোধের পরে ডাকে:

মানচিত্রে ক্লিক করার ফলে স্থান পিনকন্ট্রোলারটিকে অনুরোধ করা হয়। এটি ক্লিকের অবস্থান এবং অন্য কোনও প্রাসঙ্গিক তথ্য সংগ্রহ করে, একটি প্লেসপিনেভেস্ট তথ্য কাঠামো তৈরি করে এবং পিনের অবস্থানটি যাচাই করে এটি প্লেসপাইন ইন্টারেক্টরকে প্রেরণ করে, প্রয়োজনে এটি বৈধ করে, পিনটি রেকর্ড করার জন্য একটি স্থান সত্তা তৈরি করে, একটি সম্পাদনাপ্লেস রিপোনস গঠন করে বস্তু এবং এটি এডিটপ্লেসপ্রেসেন্টারে পাস করে যা স্থান সম্পাদক স্ক্রিনটি উপস্থিত করে।

এমভিসি দিয়ে এই নাটকটি আরও ভালভাবে তৈরি করতে, আমি ভাবতে পারি যে traditionতিহ্যগতভাবে নিয়ামকের মধ্যে থাকা অ্যাপ্লিকেশন যুক্তিটি এখানে ইন্টারঅ্যাক্টরে স্থানান্তরিত হয়েছে, কারণ আমরা অ্যাপ্লিকেশন স্তরের বাইরে কোনও অ্যাপ্লিকেশন যুক্তি চাই না। অ্যাডাপ্টার স্তরের নিয়ামক কেবল ইন্টারঅ্যাক্টরকে কল করতে পারে এবং প্রক্রিয়াটিতে কিছু ছোট ডেটা ফর্ম্যাট রূপান্তর করতে পারে:

এই স্তরের সফ্টওয়্যারটি অ্যাডাপ্টারের একটি সেট যা ব্যবহারের ক্ষেত্রে এবং সত্তাগুলির জন্য সবচেয়ে সুবিধাজনক ফর্ম্যাট থেকে ডেটা রূপান্তর করে যা ডাটাবেস বা ওয়েবের মতো কিছু বাহ্যিক এজেন্সির জন্য সবচেয়ে সুবিধাজনক ফর্ম্যাটে রূপান্তর করে।

মূল নিবন্ধ থেকে, ইন্টারফেস অ্যাডাপ্টার সম্পর্কে কথা বলা।

মিথস্ক্রিয় তথ্য ফেরত

যাইহোক, এই পদ্ধতির সাথে আমার সমস্যাটি হ'ল ব্যবহারের ক্ষেত্রে অবশ্যই উপস্থাপনার যত্ন নেওয়া উচিত। এখন, আমি দেখতে পাচ্ছি যে Presenterইন্টারফেসের উদ্দেশ্যটি বিভিন্ন উপস্থাপক (জিইউআই, ওয়েব, সিএলআই, ইত্যাদি) উপস্থাপনের জন্য যথেষ্ট বিমূর্ত হতে পারে এবং এর সত্যিকার অর্থে "আউটপুট" বোঝায় যা ব্যবহারের ক্ষেত্রে কিছু হতে পারে খুব ভাল আছে, কিন্তু এখনও আমি এটির সাথে পুরোপুরি আত্মবিশ্বাসী নই।

এখন, ক্লিন আর্কিটেকচারের অ্যাপ্লিকেশনগুলির জন্য ওয়েবে ঘুরে দেখছি, আমি কেবলমাত্র কিছু ডিটিও ফিরিয়ে দেওয়ার পদ্ধতি হিসাবে আউটপুট পোর্টটির ব্যাখ্যার লোক খুঁজে পাচ্ছি। এটি এমন কিছু হবে:

Repository repository = new Repository();
UseCase useCase = new UseCase(repository);
Data data = useCase.getData();
Presenter presenter = new Presenter();
presenter.present(data);

// I'm omitting the changes to the classes, which are fairly obvious

এটি আকর্ষণীয় কারণ আমরা ব্যবহারের কেস থেকে উপস্থাপনাটিকে "কলিং" করার দায়িত্বটি সরিয়ে রেখেছি, সুতরাং ব্যবহারের ক্ষেত্রে কেবল তথ্য সরবরাহের পরিবর্তে ডেটা নিয়ে আর কী করা উচিত তা জেনে নিজেরাই উদ্বেগ প্রকাশ করে না। এছাড়াও, এই ক্ষেত্রে আমরা এখনও নির্ভরতা নিয়ম ভঙ্গ করছি না, কারণ ব্যবহারের ক্ষেত্রে এখনও বাইরের স্তর সম্পর্কে কিছুই জানে না।

তবে, প্রকৃত উপস্থাপনাটি আর সঞ্চালিত হওয়ার সময় ব্যবহারের ক্ষেত্রে সেই মুহুর্তটি নিয়ন্ত্রণ করা হয় না (যা কার্যকর হতে পারে, উদাহরণস্বরূপ সেই সময়ে অতিরিক্ত জিনিসগুলি যেমন লগিং করা বা প্রয়োজনে এটি পুরোপুরি বাতিল করা)। এছাড়াও, লক্ষ্য করুন যে আমরা ইউজ কেস ইনপুট পোর্টটি হারিয়েছি, কারণ এখন নিয়ামক কেবল সেই getData()পদ্ধতিটিই ব্যবহার করছেন (এটি আমাদের নতুন আউটপুট পোর্ট)। তদুপরি, এটি আমার কাছে মনে হচ্ছে যে আমরা এখানে "বলুন, জিজ্ঞাসা করবেন না" নীতিটি ভঙ্গ করছি, কারণ আমরা ইন্টারেক্টরকে প্রকৃত কাজটি করতে বলার চেয়ে কিছু তথ্য দিয়ে এর সাথে কিছু করার জন্য বলছি প্রথম স্থান.

যথাযথ

সুতরাং, এই দুটি বিকল্পের মধ্যে কোনও কি ক্লিন আর্কিটেকচার অনুসারে ইউজ কেস আউটপুট বন্দরের "সঠিক" ব্যাখ্যা? তারা উভয়ই কি কার্যকর?


3
ক্রস পোস্টিং দৃ strongly়ভাবে নিরুৎসাহিত করা হয়। আপনি যদি আপনার প্রশ্নটি এখানে থাকতে চান তবে আপনার এটি স্ট্যাক ওভারফ্লো থেকে মুছে ফেলা উচিত।
রবার্ট হার্ভে

উত্তর:


48

ক্লিন আর্কিটেকচারটি একটি ব্যবহারের ক্ষেত্রে ইন্টারেক্টরকে প্রতিক্রিয়া / ডিসপ্লে পরিচালনা করতে উপস্থাপকের (যা ইনজেকশন দেওয়া হয়, ডিআইপি অনুসরণ করে) প্রকৃত বাস্তবায়নকে কল করার পরামর্শ দেয়। যাইহোক, আমি এই আর্কিটেকচারটি বাস্তবায়নকারী ব্যক্তিদের, ইন্টারেক্টর থেকে আউটপুট ডেটা ফিরিয়ে আনতে এবং তারপরে নিয়ামককে (অ্যাডাপ্টারের স্তরে) কীভাবে এটি পরিচালনা করবেন তা সিদ্ধান্ত নিতে দিন।

এটি অবশ্যই পরিষ্কার , পেঁয়াজ বা ষড়ভুজ আর্কিটেকচার নয়। যে এই :

এখানে চিত্র বর্ণনা লিখুন

এমন নয় যে MVC যে ভাবে কাজ করতে হবে

এখানে চিত্র বর্ণনা লিখুন

আপনি মডিউলগুলির মধ্যে যোগাযোগের জন্য এবং এটিকে এমভিসি কল করার জন্য বিভিন্ন উপায় ব্যবহার করতে পারেন । আমাকে এমভিসি ব্যবহার করে এমন কিছু বললে উপাদানগুলি কীভাবে যোগাযোগ করে তা সত্যই আমাকে জানায় না। এটি মানসম্মত নয়। আমাকে কেবল এটিই জানায় যে তাদের তিনটি দায়িত্বের দিকে কমপক্ষে তিনটি উপাদান ফোকাস করা আছে।

এই কয়েকটি উপায়ের বিভিন্ন নাম দেওয়া হয়েছে : এখানে চিত্র বর্ণনা লিখুন

এবং তাদের প্রত্যেককে ন্যায়সঙ্গতভাবে এমভিসি বলা যেতে পারে।

যাইহোক, বাজওয়ার্ড আর্কিটেকচার (ক্লিন, পেঁয়াজ এবং হেক্স) আপনাকে কী জিজ্ঞাসা করছে তা সত্যিই ক্যাপচার করে নি।

এখানে চিত্র বর্ণনা লিখুন

চারদিকে প্রবাহিত হওয়া ডেটা স্ট্রাকচার যুক্ত করুন (এবং এটি কোনও কারণে উল্টোভাবে ফ্লিপ করুন) এবং আপনি পান :

এখানে চিত্র বর্ণনা লিখুন

এখানে একটি জিনিস পরিষ্কার হওয়া উচিত যে প্রতিক্রিয়া মডেলটি নিয়ামকের মাধ্যমে মার্চিং করে না।

আপনি যদি agগলকে লক্ষ্য করেন তবে আপনি খেয়াল করেছেন যে কেবলমাত্র বুজওয়ার্ড আর্কিটেকচারগুলি পুরোপুরি বিজ্ঞপ্তি নির্ভরতা এড়িয়ে চলে । গুরুত্বপূর্ণভাবে, এর অর্থ একটি কোড পরিবর্তনের প্রভাব উপাদানগুলির মাধ্যমে সাইক্লিং দ্বারা ছড়িয়ে পড়বে না। পরিবর্তনটি যখন থামবে তখন কোডটি আঘাত করে যখন এটি সম্পর্কে কোনও চিন্তা নেই।

আশ্চর্য হ'ল তারা যদি এটিকে উল্টে দেয় তবে নিয়ন্ত্রণের প্রবাহটি ঘড়ির কাঁটার দিক দিয়ে যেতে পারে। এ সম্পর্কে আরও এবং এই "সাদা" তীর মাথা, পরে later

ইন্টারেক্টরের সাথে স্পষ্টভাবে ইনপুট এবং আউটপুট পোর্টগুলি সংজ্ঞায়িত না করা ছাড়াও দ্বিতীয় সমাধানটি কি অ্যাপ্লিকেশন স্তরটির বাইরে অ্যাপ্লিকেশন দায়িত্বগুলি ফাঁস হয়?

যেহেতু কন্ট্রোলার থেকে উপস্থাপকের কাছে যোগাযোগের অর্থ অ্যাপ্লিকেশন "স্তর" এর মধ্য দিয়ে যাওয়া হয় তবে হ্যাঁ নিয়ন্ত্রককে উপস্থাপকের কাজের অংশ হিসাবে তৈরি করা সম্ভবত একটি ফুটো হতে পারে। এটি ভিআইপিআর আর্কিটেকচারের আমার প্রধান সমালোচনা ।

এগুলি কেন এত গুরুত্বপূর্ণ তা সম্ভবত কমান্ড কোয়েরি দায়বদ্ধতা বিভাজন অধ্যয়ন করে ভালভাবে বোঝা যেতে পারে ।

ইনপুট এবং আউটপুট পোর্ট

ক্লিন আর্কিটেকচার সংজ্ঞা এবং বিশেষত একটি নিয়ামক, একটি ব্যবহারের ক্ষেত্রে ইন্টারেক্টর এবং উপস্থাপকের মধ্যে সম্পর্কের বর্ণনা দেওয়ার জন্য সামান্য ফ্লো ডায়াগ্রাম বিবেচনা করে, "ইউজ কেস আউটপুট পোর্ট" কী হওয়া উচিত তা আমি সঠিকভাবে বুঝতে পেরেছি কিনা তা নিশ্চিত নই।

আপনি যে নির্দিষ্ট API ব্যবহারের মাধ্যমে আউটপুট প্রেরণ করেন এটি এটিই। এটি এর চেয়ে বেশি কিছু নয়। এই ব্যবহারের ক্ষেত্রে ইন্টারঅ্যাক্টরটি জানতে বা জেনে নেওয়ার দরকার নেই, যদি আউটপুট কোনও জিইউআই, সিএলআই, লগ বা কোনও অডিও স্পিকারের কাছে চলে যায়। সমস্ত ইন্টারঅ্যাক্টরকে জানা দরকার যে খুব সহজ এপিআই সম্ভব এটি এটিকে তার কাজের ফলাফলগুলি রিপোর্ট করতে দেয়।

ষড়ভুজ আর্কিটেকচারের মতো পরিষ্কার আর্কিটেকচার প্রাথমিক পোর্ট (পদ্ধতি) এবং গৌণ পোর্টগুলির (অ্যাডাপ্টারের দ্বারা প্রয়োগ করা ইন্টারফেস) মধ্যে পার্থক্য করে। যোগাযোগের প্রবাহ অনুসরণ করার পরে, আমি প্রত্যাশা করি "ইউজ কেস ইনপুট পোর্ট" একটি প্রাথমিক বন্দর হবে (সুতরাং কেবল একটি পদ্ধতি), এবং "ইন্টারফেস কেস আউটপুট পোর্ট" প্রয়োগ করা হবে একটি ইন্টারফেস, সম্ভবত কোনও নির্মাণকারী যুক্তি আসল অ্যাডাপ্টার গ্রহণ করবে, যাতে ইন্টারেক্টর এটি ব্যবহার করতে পারে।

আউটপুট পোর্টটি ইনপুট পোর্টের থেকে পৃথক হওয়ার কারণটি হ'ল এটি যে স্তরটিকে বিমূর্ত করে তার দ্বারা এটি নিজস্ব W অর্থাৎ, যে স্তরটি এটি বিলোপ করে তা অবশ্যই পরিবর্তিত হবার অনুমতি দেয় না। কেবলমাত্র অ্যাপ্লিকেশন স্তর এবং এর লেখকের সিদ্ধান্ত নেওয়া উচিত যে আউটপুট পোর্ট পরিবর্তন হতে পারে।

এটি ইনপুট পোর্টের বিপরীতে যা এই স্তরটি বাতিল করে তার মালিকানাধীন। কেবলমাত্র অ্যাপ্লিকেশন স্তর লেখকের সিদ্ধান্ত নিতে হবে এটির ইনপুট পোর্টটি পরিবর্তন করা উচিত কিনা।

এই নিয়মগুলি অনুসরণ করে ধারণাটি সংরক্ষণ করে যে অ্যাপ্লিকেশন স্তর, বা কোনও অভ্যন্তরীণ স্তর বাইরের স্তরগুলির সম্পর্কে কিছুই জানে না।


উপস্থাপককে কল করার কথোপকথনে

পূর্ববর্তী ব্যাখ্যাটি উপরোক্ত চিত্রটি নিজেই দ্বারা নিশ্চিত হওয়া গেছে বলে মনে হয় যেখানে নিয়ামক এবং ইনপুট পোর্টের মধ্যে সম্পর্কটি একটি "তীক্ষ্ণ" মাথাযুক্ত একটি শক্ত তীর দ্বারা প্রতিনিধিত্ব করে ("সংঘের" জন্য ইউএমএল, যার অর্থ "একটি" থাকে, যেখানে কন্ট্রোলারের একটি "ব্যবহারের কেস থাকে", যখন উপস্থাপক এবং আউটপুট পোর্টের মধ্যে সম্পর্ক একটি "সাদা" মাথা ("উত্তরাধিকারের জন্য ইউএমএল") দ্বারা দৃ a় তীর দ্বারা প্রতিনিধিত্ব করে, যা "বাস্তবায়ন" এর জন্য এক নয়, তবে সম্ভবত এটি যাইহোক অর্থ)।

"সাদা" তীর সম্পর্কে গুরুত্বপূর্ণ বিষয়টি এটি আপনাকে এটি করতে দেয়:

এখানে চিত্র বর্ণনা লিখুন

আপনি নিয়ন্ত্রণের প্রবাহকে নির্ভরতার বিপরীত দিকে যেতে দিতে পারেন! এর অর্থ অভ্যন্তরীণ স্তরটি বাইরের স্তর সম্পর্কে জানতে হবে না এবং তবুও আপনি অভ্যন্তরীণ স্তরটিতে ডুব দিয়ে ফিরে আসতে পারবেন!

"ইন্টারফেস" কীওয়ার্ড ব্যবহার করার সাথে এর কোনও সম্পর্ক নেই। আপনি এটি একটি বিমূর্ত ক্লাস দিয়ে করতে পারেন। হেক আপনি এটিকে (ick) কংক্রিটের ক্লাস দিয়ে এতক্ষণ চালিয়ে যেতে পারেন যতক্ষণ না এটি প্রসারিত করা যায়। এটি উপস্থাপককে প্রয়োগ করতে হবে এমন এপিআই সংজ্ঞায়িত করে এমন কিছু সংক্ষেপে এটি করা সহজ simply খোলা তীরটি কেবল পলিমারফিজম চাইছে। কি ধরনের আপনার উপর নির্ভর করে।

সেই নির্ভরতার দিকটি কেন বিপরীত করা এত গুরুত্বপূর্ণ, তা নির্ভরতা বিপর্যয় নীতিটি অধ্যয়ন করে শিখতে পারে । আমি এই নীতিটি এখানে এই চিত্রগুলিতে ম্যাপ করেছি ।

মিথস্ক্রিয় তথ্য ফেরত

যাইহোক, এই পদ্ধতির সাথে আমার সমস্যাটি হ'ল ব্যবহারের ক্ষেত্রে উপস্থাপনাটি নিজেই যত্ন নিতে হবে। এখন, আমি দেখতে পাচ্ছি যে উপস্থাপক ইন্টারফেসের উদ্দেশ্যটি বিভিন্ন উপস্থাপক (জিইউআই, ওয়েব, সিএলআই, ইত্যাদি) উপস্থাপনের জন্য যথেষ্ট বিমূর্ত হতে পারে, এবং এর সত্যিকার অর্থে "আউটপুট" বোঝানো হয়, যা ব্যবহারের ক্ষেত্রে কিছু হয় means খুব ভাল থাকতে পারে, কিন্তু এখনও আমি এটির সাথে পুরোপুরি আত্মবিশ্বাসী নই।

না আসলেই এটি। বাইরের স্তরগুলি সম্পর্কে অভ্যন্তরীণ স্তরগুলি জানেন না তা নিশ্চিত করার বিষয়টি হ'ল আমরা বাইরের স্তরগুলিকে সরিয়ে ফেলতে, প্রতিস্থাপন করতে বা রিফেক্টর করতে পারি এবং আত্মবিশ্বাস করি যে এর ফলে অভ্যন্তরীণ স্তরগুলিতে কোনও কিছু ভেঙে যাবে না। তারা যা জানে না সেগুলি তাদের ক্ষতি করবে না। যদি আমরা এটি করতে পারি তবে আমরা বাইরেরগুলি যা খুশি তাই পরিবর্তন করতে পারি।

এখন, ক্লিন আর্কিটেকচারের অ্যাপ্লিকেশনগুলির জন্য ওয়েবে ঘুরে দেখছি, আমি কেবলমাত্র কিছু ডিটিও ফিরিয়ে দেওয়ার পদ্ধতি হিসাবে আউটপুট পোর্টটির ব্যাখ্যার লোক খুঁজে পাচ্ছি। এটি এমন কিছু হবে:

Repository repository = new Repository();
UseCase useCase = new UseCase(repository);
Data data = useCase.getData();
Presenter presenter = new Presenter();
presenter.present(data);
// I'm omitting the changes to the classes, which are fairly obvious

এটি আকর্ষণীয় কারণ আমরা ব্যবহারের কেস থেকে উপস্থাপনাটিকে "কলিং" করার দায়িত্বটি সরিয়ে রেখেছি, সুতরাং ব্যবহারের ক্ষেত্রে কেবল তথ্য সরবরাহের পরিবর্তে ডেটা নিয়ে আর কী করা উচিত তা জেনে নিজেরাই উদ্বেগ প্রকাশ করে না। এছাড়াও, এই ক্ষেত্রে আমরা এখনও নির্ভরতা নিয়ম ভঙ্গ করছি না, কারণ ব্যবহারের ক্ষেত্রে এখনও বাইরের স্তর সম্পর্কে কিছুই জানে না।

এখানে সমস্যা এখন যা আছে তা কীভাবে ডেটা জিজ্ঞাসা করতে হবে তাও হ'ল ডেটা গ্রহণ করার জিনিস। রেসপন্স মডেলটি দেখতে কেমন হবে, কোথায় যেতে হবে এবং হি কীভাবে উপস্থাপন করবে সে সম্পর্কে কন্ট্রোলার আনন্দের সাথে ইউজকেস ইন্টারেক্টরকে কল করতে পারে।

আবার, কেন গুরুত্বপূর্ণ তা জানতে দয়া করে কমান্ড ক্যোয়ারির দায়িত্বশীলতা বিভাজন অধ্যয়ন করুন ।

তবে, প্রকৃত উপস্থাপনাটি আর সঞ্চালিত হওয়ার সময় ব্যবহারের ক্ষেত্রে সেই মুহুর্তটি নিয়ন্ত্রণ করা হয় না (যা কার্যকর হতে পারে, উদাহরণস্বরূপ সেই সময়ে অতিরিক্ত জিনিসগুলি যেমন লগিং করা বা প্রয়োজনে এটি পুরোপুরি বাতিল করা)। এছাড়াও, লক্ষ্য করুন যে আমরা ইউজ কেস ইনপুট পোর্টটি হারিয়েছি, কারণ এখন নিয়ামকটি কেবল getData () পদ্ধতিটি (যা আমাদের নতুন আউটপুট পোর্ট) ব্যবহার করে। তদুপরি, এটি আমার কাছে মনে হচ্ছে যে আমরা এখানে "বলুন, জিজ্ঞাসা করবেন না" নীতিটি ভঙ্গ করছি, কারণ আমরা ইন্টারেক্টরকে প্রকৃত কাজটি করতে বলার চেয়ে কিছু তথ্য দিয়ে এর সাথে কিছু করার জন্য বলছি প্রথম স্থান.

হ্যাঁ! বলা, জিজ্ঞাসা না করা প্রক্রিয়াগতের চেয়ে এই বিষয়টিকে ওরিয়েন্টেড রাখতে সহায়তা করবে।

যথাযথ

সুতরাং, এই দুটি বিকল্পের মধ্যে কোনও কি ক্লিন আর্কিটেকচার অনুসারে ইউজ কেস আউটপুট বন্দরের "সঠিক" ব্যাখ্যা? তারা উভয়ই কি কার্যকর?

যে কোনও কাজ করে তা কার্যক্ষম। তবে আমি বলব না যে আপনি যে দ্বিতীয় বিকল্পটি বিশ্বস্ততার সাথে উপস্থাপন করেছেন তা ক্লিন আর্কিটেকচার অনুসরণ করে। এটি কাজ করে এমন কিছু হতে পারে। তবে ক্লিন আর্কিটেকচার যা চাইবে তা নয়।


4
এরকম গভীরতার ব্যাখ্যা লিখতে সময় দেওয়ার জন্য ধন্যবাদ।
swahnee

1
আমি ক্লিন আর্কিটেকচারের চারপাশে আমার মাথা গুটিয়ে দেওয়ার চেষ্টা করেছি এবং এই উত্তরটি একটি দুর্দান্ত উত্স। খুবই ভালো করেছ!
নাথান

দুর্দান্ত এবং বিস্তারিত উত্তরে .. এর জন্য ধন্যবাদ .. আপনি কি আমাকে ইউসকেস রান চলাকালীন জিইউআই আপডেট করার বিষয়ে কিছু টিপস (বা ব্যাখ্যা করার জন্য নির্দেশ) দিতে পারেন, অর্থাত্ বড় ফাইল আপলোড করার সময় অগ্রগতি বার আপডেট?
ইওকস

1
@ সম্প্রদায়, আপনার প্রশ্নের তাত্ক্ষণিক উত্তর হিসাবে আপনার পর্যবেক্ষণযোগ্য প্যাটার্নটি খতিয়ে দেখা উচিত। আপনার ব্যবহারের ক্ষেত্রে একটি বিষয় ফিরে আসতে পারে এবং অগ্রগতি আপডেটের বিষয়টিকে অবহিত করতে পারে। উপস্থাপক সাবস্ক্রাইব করুন এবং বিজ্ঞপ্তি প্রতিক্রিয়া।
নাথান

7

আপনার প্রশ্ন সম্পর্কিত একটি আলোচনায় , চাচা বব তার ক্লিন আর্কিটেকচারে উপস্থাপকের উদ্দেশ্য ব্যাখ্যা করেছেন:

এই কোড নমুনা দেওয়া:

namespace Some\Controller;

class UserController extends Controller {
    public function registerAction() {
        // Build the Request object
        $request = new RegisterRequest();
        $request->name = $this->getRequest()->get('username');
        $request->pass = $this->getRequest()->get('password');

        // Build the Interactor
        $usecase = new RegisterUser();

        // Execute the Interactors method and retrieve the response
        $response = $usecase->register($request);

        // Pass the result to the view
        $this->render(
            '/user/registration/template.html.twig', 
            array('id' =>  $response->getId()
        );
    }
}

চাচা বব এই বলেছিলেন:

" উপস্থাপকের উদ্দেশ্য হ'ল ইউআই এর ফর্ম্যাট থেকে ব্যবহারের কেসগুলি দ্বিগুণ করা In আপনার উদাহরণস্বরূপ, $ প্রতিক্রিয়া পরিবর্তনশীল ইন্টারেক্টর দ্বারা তৈরি করা হয় তবে ভিউ দ্বারা ব্যবহৃত হয় This এটি ইন্টারঅ্যাক্টরটিকে দর্শনটির সাথে যুক্ত করে example উদাহরণস্বরূপ interact , আসুন আমরা say প্রতিক্রিয়া অবজেক্টের ক্ষেত্রগুলির মধ্যে একটি তারিখ That ক্ষেত্রটি একটি বাইনারি ডেট অবজেক্ট হতে পারে যা বিভিন্ন তারিখের বিভিন্ন ফর্ম্যাটে রেন্ডার করা যায় The সম্ভবত একটি খুব নির্দিষ্ট তারিখের বিন্যাস চায়, সম্ভবত ডিডি / এমএম / ওয়াইওয়াইওয়াই। ফর্ম্যাটটি তৈরি করা কার দায়িত্ব? যদি ইন্টারেক্টর সেই ফর্ম্যাটটি তৈরি করে তবে তা ভিউ সম্পর্কে খুব বেশি জানে But তবে যদি ভিউটি বাইনারি ডেট অবজেক্ট নেয় তবে ইন্টারঅ্যাক্টর সম্পর্কে এটি খুব বেশি জানে

The "উপস্থাপকের কাজটি গ্রহণ করা হয় প্রতিক্রিয়া অবজেক্ট থেকে ডেটা এবং দেখুন জন্য এটি বিন্যাস। দৃষ্টিভঙ্গি বা ইন্টারেক্টর উভয়েই একে অপরের ফর্ম্যাটগুলি সম্পর্কে জানে না। "

--- চাচা বব

(আপডেট: 31 মে, 2019)

প্রদত্ত আঙ্কেল বব এর উত্তর, আমি মনে করি যে এটা কোন ব্যাপার না যে কত আমরা কি কিনা বিকল্প # 1 (দিন ইন্টারঅ্যাক্টার ব্যবহার উপস্থাপক) ...

class UseCase
{
    private Presenter presenter;
    private Repository repository;

    public UseCase(Repository repository, Presenter presenter)
    {
        this.presenter = presenter;
        this.repository = repository;
    }

    public void Execute(Request request)
    {
        ...
        Response response = new Response() {...}
        this.presenter.Show(response);
    }
}

... বা আমরা বিকল্প # 2 করি (ইন্টারেক্টরকে প্রতিক্রিয়া জানাতে দিন, নিয়ন্ত্রণকারীর ভিতরে একটি উপস্থাপক তৈরি করুন, তারপরে উপস্থাপকের প্রতিক্রিয়াটি প্রেরণ করুন) ...

class Controller
{
    public void ExecuteUseCase(Data data)
    {
        Request request = ...
        UseCase useCase = new UseCase(repository);
        Response response = useCase.Execute(request);
        Presenter presenter = new Presenter();
        presenter.Show(response);
    }
}

ব্যক্তিগতভাবে, আমি বিকল্প # 1 পছন্দ করি কারণ আমি নীচে এই উদাহরণের মতো ডেটা এবং ত্রুটি বার্তাগুলি কখন প্রদর্শন করতে পারি তার ভিতরেinteractor নিয়ন্ত্রণ করতে সক্ষম হতে চাই:

class UseCase
{
    private Presenter presenter;
    private Repository repository;

    public UseCase(Repository repository, Presenter presenter)
    {
        this.presenter = presenter;
        this.repository = repository;
    }

    public void Execute(Request request)
    {
        if (<invalid request>) 
        {
            this.presenter.ShowError("...");
            return;
        }

        if (<there is another error>) 
        {
            this.presenter.ShowError("another error...");
            return;
        }

        ...
        Response response = new Response() {...}
        this.presenter.Show(response);
    }
}

... আমি এটি করতে সক্ষম হতে চাই if/elseযা ইন্টারেস্টরের interactorবাইরে নয় বরং অভ্যন্তরের উপস্থাপনার সাথে সম্পর্কিত ।

অন্যদিকে আমরা বিকল্প # 2 করেন তাহলে আমরা ভুল বার্তা (গুলি) সংরক্ষণ করতে হবে response, বস্তুর যে আসতে responseথেকে অবজেক্ট interactorথেকে controller, এবং controller পার্সresponse বস্তুর ...

class UseCase
{
    public Response Execute(Request request)
    {
        Response response = new Response();
        if (<invalid request>) 
        {
            response.AddError("...");
        }

        if (<there is another error>) 
        {
            response.AddError("another error...");
        }

        if (response.HasNoErrors)
        {
            response.Whatever = ...
        }

        ...
        return response;
    }
}
class Controller
{
    private UseCase useCase;

    public Controller(UseCase useCase)
    {
        this.useCase = useCase;
    }

    public void ExecuteUseCase(Data data)
    {
        Request request = new Request() 
        {
            Whatever = data.whatever,
        };
        Response response = useCase.Execute(request);
        Presenter presenter = new Presenter();
        if (response.ErrorMessages.Count > 0)
        {
            if (response.ErrorMessages.Contains(<invalid request>))
            {
                presenter.ShowError("...");
            }
            else if (response.ErrorMessages.Contains("another error")
            {
                presenter.ShowError("another error...");
            }
        }
        else
        {
            presenter.Show(response);
        }
    }
}

আমি responseভিতরে ত্রুটিগুলির জন্য ডেটা পার্সিং পছন্দ করি না controllerকারণ যদি আমরা এটি করি যে আমরা অনর্থক কাজ করছি --- যদি আমরা কিছুতে পরিবর্তন করি তবে আমাদের মধ্যে interactorকিছু পরিবর্তন করতে হবে controller

এছাড়াও, যদি আমরা পরে আমাদের interactorকনসোল ব্যবহার করে ডেটা উপস্থাপনের জন্য পুনরায় ব্যবহার করার সিদ্ধান্ত নিই , উদাহরণস্বরূপ, আমাদের কনসোল অ্যাপ্লিকেশনটিতে if/elseথাকা সমস্ত কপি-পেস্ট করতে আমাদের মনে রাখতে হবে controller

// in the controller for our console app
if (response.ErrorMessages.Count > 0)
{
    if (response.ErrorMessages.Contains(<invalid request>))
    {
        presenterForConsole.ShowError("...");
    }
    else if (response.ErrorMessages.Contains("another error")
    {
        presenterForConsole.ShowError("another error...");
    }
}
else
{
    presenterForConsole.Present(response);
}

আমরা যদি বিকল্প # 1 ব্যবহার আমরা এই থাকবে if/else শুধুমাত্র একটি স্থানে : interactor


আপনি যদি এএসপি.নেট এমভিসি (বা অন্যান্য অনুরূপ এমভিসি ফ্রেমওয়ার্ক) ব্যবহার করেন তবে বিকল্প # 2 হ'ল সহজ উপায়।

তবে আমরা সেই ধরণের পরিবেশে # 1 বিকল্পটি করতে পারি। এএসপি.নেট এমভিসি-তে বিকল্প # 1 করার উদাহরণ এখানে রয়েছে:

(লক্ষ্য করুন যে public IActionResult Resultআমাদের আমাদের এএসপি.নেট এমভিসি অ্যাপের উপস্থাপক থাকা দরকার )

class UseCase
{
    private Repository repository;

    public UseCase(Repository repository)
    {
        this.repository = repository;
    }

    public void Execute(Request request, Presenter presenter)
    {
        if (<invalid request>) 
        {
            this.presenter.ShowError("...");
            return;
        }

        if (<there is another error>) 
        {
            this.presenter.ShowError("another error...");
            return;
        }

        ...
        Response response = new Response() {
            ...
        }
        this.presenter.Show(response);
    }
}
// controller for ASP.NET app

class AspNetController
{
    private UseCase useCase;

    public AspNetController(UseCase useCase)
    {
        this.useCase = useCase;
    }

    [HttpPost("dosomething")]
    public void ExecuteUseCase(Data data)
    {
        Request request = new Request() 
        {
            Whatever = data.whatever,
        };
        var presenter = new AspNetPresenter();
        useCase.Execute(request, presenter);
        return presenter.Result;
    }
}
// presenter for ASP.NET app

public class AspNetPresenter
{
    public IActionResult Result { get; private set; }

    public AspNetPresenter(...)
    {
    }

    public async void Show(Response response)
    {
        Result = new OkObjectResult(new { });
    }

    public void ShowError(string errorMessage)
    {
        Result = new BadRequestObjectResult(errorMessage);
    }
}

(লক্ষ্য করুন যে public IActionResult Resultআমাদের আমাদের এএসপি.নেট এমভিসি অ্যাপের উপস্থাপক থাকা দরকার )

যদি আমরা কনসোলের জন্য অন্য অ্যাপ্লিকেশন তৈরি করার সিদ্ধান্ত নিই তবে আমরা উপরেরটি পুনরায় ব্যবহার করতে পারি UseCaseএবং কনসোলের জন্য কেবল Controllerএবং এর Presenterজন্য তৈরি করতে পারি :

// controller for console app

class ConsoleController
{    
    public void ExecuteUseCase(Data data)
    {
        Request request = new Request() 
        {
            Whatever = data.whatever,
        };
        var presenter = new ConsolePresenter();
        useCase.Execute(request, presenter);
    }
}
// presenter for console app

public class ConsolePresenter
{
    public ConsolePresenter(...)
    {
    }

    public async void Show(Response response)
    {
        // write response to console
    }

    public void ShowError(string errorMessage)
    {
        Console.WriteLine("Error: " + errorMessage);
    }
}

(লক্ষ্য করুন যে আমরা public IActionResult Resultআমাদের কনসোল অ্যাপের উপস্থাপকটিতে নেই)


অবদানের জন্য ধন্যবাদ। কথোপকথনটি পড়া, তবে একটি জিনিস আমি বুঝতে পারি না: তিনি বলেছেন যে উপস্থাপকের প্রতিক্রিয়া থেকে আসা ডেটা রেন্ডার করা উচিত এবং একই সাথে প্রতিক্রিয়াটি ইন্টারেক্টর দ্বারা তৈরি করা উচিত নয়। তবে এরপরে কে সাড়া দিচ্ছে? আমি বলব যে ইন্টারেক্টরটি উপস্থাপকের কাছে অ্যাপ্লিকেশন নির্দিষ্ট ফর্ম্যাটে ডেটা সরবরাহ করা উচিত, এটি উপস্থাপকের দ্বারা জানা যায়, যেহেতু অ্যাডাপ্টার স্তর অ্যাপ্লিকেশন স্তরের উপর নির্ভর করতে পারে (তবে অন্যভাবে নয়)।
swahnee

আমি দুঃখিত. হতে পারে এটি বিভ্রান্ত হয়ে যায় কারণ আমি আলোচনা থেকে কোড উদাহরণটি অন্তর্ভুক্ত করি নি। কোডের উদাহরণ অন্তর্ভুক্ত করার জন্য আমি এটি আপডেট করব।
Jboy ফ্লাগা

চাচা বব বলেন নি যে প্রতিক্রিয়াটি ইন্টারেক্টর দ্বারা তৈরি করা উচিত নয়। প্রতিক্রিয়া ইন্টারেক্টর দ্বারা তৈরি করা হবে । চাচা বব যা বলছেন তা হ'ল ইন্টারেক্টর দ্বারা তৈরি প্রতিক্রিয়া উপস্থাপক ব্যবহার করবেন। উপস্থাপক তারপরে "এটিকে ফর্ম্যাট করুন", একটি ভিউমডেলের ফর্ম্যাট প্রতিক্রিয়া রাখবেন, তারপরে সেই ভিউমোডেলটিকে ভিউতে পাস করবেন <br <br/> আমি এটি বুঝতে পারি।
Jboy Flaga

1
এটি আরও অর্থবোধ করে। আমি এই ধারণার মধ্যে ছিলাম যে "ভিউ" "উপস্থাপক" এর প্রতিশব্দ ছিল, যেহেতু ক্লিন আর্কিটেকচারটি "ভিউ" বা "ভিউমডেল" এর কোনটিই উল্লেখ করে না, যা আমি বিশ্বাস করি যে কেবলমাত্র এমভিসি ধারণাগুলি, যা বাস্তবায়ন করার সময় ব্যবহার করা হতে পারে বা নাও হতে পারে অ্যাডাপ্টার।
swahnee

2

কোনও ব্যবহারের ক্ষেত্রে উপস্থাপক বা রিটার্নিং ডেটা থাকতে পারে, যা অ্যাপ্লিকেশন প্রবাহের দ্বারা প্রয়োজনীয় on

আসুন বিভিন্ন অ্যাপ্লিকেশন প্রবাহ বোঝার আগে কয়েকটি শর্ত বুঝি:

  • ডোমেন অবজেক্ট : একটি ডোমেন অবজেক্ট হ'ল ডোমেন স্তরের ডেটা কনটেইনার যার উপর ব্যবসায়িক লজিক অপারেশন করা হয়।
  • মডেল দেখুন : ব্যবহারকারী ইন্টারফেসের সাথে সামঞ্জস্যপূর্ণ এবং বন্ধুত্বপূর্ণ করতে ডোমেন অবজেক্টগুলি সাধারণত অ্যাপ্লিকেশন স্তরে মডেলগুলি দেখতে ম্যাপ করা হয়।
  • উপস্থাপক : যদিও অ্যাপ্লিকেশন স্তরের একজন নিয়ামক সাধারণত একটি ব্যবহারের ক্ষেত্রে আবেদন করেন তবে মডেল ম্যাপিংয়ের যুক্তিকে পৃথক শ্রেণিতে (একক দায়িত্বের নীতি অনুসরণ করে) দেখার জন্য ডোমেনটি অর্পণ করার পরামর্শ দেওয়া হয়, যাকে "উপস্থাপক" বলা হয়।

রিটার্নিং ডেটাযুক্ত একটি ব্যবহারের কেস

একটি সাধারণ ক্ষেত্রে, ব্যবহারের ক্ষেত্রে সহজেই অ্যাপ্লিকেশন স্তরে একটি ডোমেন অবজেক্ট ফিরে আসে যা ইউআইতে প্রদর্শন করার জন্য বন্ধুত্বপূর্ণ করে তুলতে অ্যাপ্লিকেশন স্তরটিতে আরও প্রক্রিয়া করা যায়।

যেহেতু নিয়ামক ব্যবহারের ক্ষেত্রে আবেদন করার জন্য দায়বদ্ধ তাই এই ক্ষেত্রে এটি রেন্ডার হওয়ার জন্য প্রেরণের আগে পাঠানোর আগে মডেল ম্যাপিং দেখার জন্য ডোমেন পরিচালনা করার জন্য সম্পর্কিত উপস্থাপকের একটি উল্লেখও রয়েছে।

এখানে একটি সরলীকৃত কোড নমুনা দেওয়া হয়েছে:

namespace SimpleCleanArchitecture
{
    public class OutputDTO
    {
        //fields
    }

    public class Presenter 
    {
        public OutputDTO Present(Domain domain)
        {
            // Mapping takes action. Dummy object returned for demonstration purpose
            // Usually frameworks like automapper to the mapping job.
            return new OutputDTO();
        }
    }

    public class Domain
    {
        //fields
    }

    public class UseCaseInteractor
    {
        public Domain Process(Domain domain)
        {
            // additional processing takes place here
            return domain;
        }
    }

    // A simple controller. 
    // Usually frameworks like asp.net mvc provides url routing mechanism to reach here through this type of class.
    public class Controller
    {
        public View Action()
        {
            UseCaseInteractor userCase = new UseCaseInteractor();
            var domain = userCase.Process(new Domain());//passing dummy domain(for demonstration purpose) to process
            var presenter = new Presenter();//presenter might be initiated via dependency injection.

            return new View(presenter.Present(domain));
        }
    }

    // A simple view. 
    // Usually frameworks like asp.net mvc provides mechanism to render html based view through this type of class.
    public class View
    {
        OutputDTO _outputDTO;

        public View(OutputDTO outputDTO)
        {
            _outputDTO = outputDTO;
        }

    }
}

উপস্থাপক সমন্বিত একটি ব্যবহারের কেস

সাধারণ না হলেও, এটি ব্যবহারের ক্ষেত্রে উপস্থাপককে কল করার প্রয়োজন হতে পারে। সেক্ষেত্রে উপস্থাপকের কংক্রিট রেফারেন্স ধরে রাখার পরিবর্তে, একটি ইন্টারফেস (বা বিমূর্ত শ্রেণি )টিকে রেফারেন্স পয়েন্ট হিসাবে বিবেচনা করার পরামর্শ দেওয়া হয় (যা নির্ভরতার ইনজেকশনের মাধ্যমে রান সময়ে শুরু করা উচিত)।

পৃথক শ্রেণিতে মডেল ম্যাপিংয়ের যুক্তি দেখার জন্য ডোমেন থাকা (নিয়ন্ত্রকের অভ্যন্তরের পরিবর্তে) নিয়ামক এবং ব্যবহারের ক্ষেত্রে বিজ্ঞপ্তি নির্ভরতাও ভেঙে দেয় (যখন ম্যাপিং যুক্তির রেফারেন্সটি ব্যবহারের ক্ষেত্রে শ্রেণীর দ্বারা প্রয়োজনীয় হয়)।

এখানে চিত্র বর্ণনা লিখুন

নীচে মূল প্রবন্ধে চিত্রিত হিসাবে নিয়ন্ত্রণ প্রবাহকে সহজীকরণের বাস্তবায়ন দেওয়া হয়েছে, এটি দেখায় যে এটি কীভাবে করা যায়। দয়া করে নোট করুন যে সরলতার জন্য চিত্রের মতো চিত্রের মতো দেখানো হয়েছে ইউজকেইস ইন্টেেক্টর একটি কংক্রিট বর্গ।

namespace CleanArchitectureWithPresenterInUseCase
{
    public class Domain
    {
        //fields
    }

    public class OutputDTO
    {
        //fields
    }

    // Use Case Output Port
    public interface IPresenter
    {
        OutputDTO Present(Domain domain);
    }

    public class Presenter: IPresenter
    {
        public OutputDTO Present(Domain domain)
        {
            // Mapping takes action. Dummy object returned for demonstration purpose
            // Usually frameworks like automapper to the mapping job.
            return new OutputDTO();
        }
    }

    // Use Case Input Port / Interactor   
    public class UseCaseInteractor
    {
        IPresenter _presenter;
        public UseCaseInteractor (IPresenter presenter)
        {
            _presenter = presenter;
        }

        public OutputDTO Process(Domain domain)
        {
            return _presenter.Present(domain);
        }
    }

    // A simple controller. 
    // Usually frameworks like asp.net mvc provides url routing mechanism to reach here through this type of class.
    public class Controller
    {
        public View Action()
        {
            IPresenter presenter = new Presenter();//presenter might be initiated via dependency injection.
            UseCaseInteractor userCase = new UseCaseInteractor(presenter);
            var outputDTO = userCase.Process(new Domain());//passing dummy domain (for demonstration purpose) to process
            return new View(outputDTO);
        }
    }

    // A simple view. 
    // Usually frameworks like asp.net mvc provides mechanism to render html based view through this type of class.
    public class View
    {
        OutputDTO _outputDTO;

        public View(OutputDTO outputDTO)
        {
            _outputDTO = outputDTO;
        }

    }
}

1

যদিও আমি সাধারণভাবে @ ক্যান্ডিওডআরঞ্জের উত্তরগুলির সাথে একমত হই, তবে আমি সেই পদ্ধতির মধ্যেও উপকার দেখতে পাব যেখানে ইন্টারেক্টর কেবল উপস্থাপকের কাছে নিয়ন্ত্রকের মাধ্যমে প্রেরণ করা ডেটা পুনরায় ফিরিয়ে দেয়।

উদাহরণস্বরূপ এটি Asp.Net MVC এর প্রসঙ্গে ক্লিন আর্কিটেকচার (নির্ভরতা বিধি) এর ধারণাগুলি ব্যবহার করার একটি সহজ উপায়।

এই আলোচনার আরও গভীর দিকে ডুবতে আমি একটি ব্লগ পোস্ট লিখেছি: https://plainionist.github.io/Implementing-Clean- আরকিটেকচার- নিয়ন্ত্রণকারী- প্রতিনিধি /


1

উপস্থাপক বা রিটার্নিং ডেটাযুক্ত কেসটি ব্যবহার করবেন?

সুতরাং, এই দুটি বিকল্পের মধ্যে কোনও কি ক্লিন আর্কিটেকচার অনুসারে ইউজ কেস আউটপুট বন্দরের "সঠিক" ব্যাখ্যা? তারা উভয়ই কি কার্যকর?


সংক্ষেপে

হ্যাঁ, উভয় পদ্ধতির ব্যবসায়ের স্তর এবং বিতরণ ব্যবস্থার মধ্যে নিয়ন্ত্রণের বিপরীতমুখীকরণকে বিবেচনা করা যতক্ষণ না তারা উভয়ই কার্যকর । দ্বিতীয় পদ্ধতির সাহায্যে আমরা এখনও পর্যবেক্ষক, মধ্যস্থতাকারী কয়েকজনকে নকশার নকশাগুলির ব্যবহার করে আইওসি প্রবর্তন করতে সক্ষম ...

তার ক্লিন আর্কিটেকচারের সাহায্যে , আঙ্কেল বব এর প্রচেষ্টা আমাদের ওওপ নীতিমালার সাথে ব্যাপকভাবে মেনে চলার জন্য গুরুত্বপূর্ণ ধারণা এবং উপাদানগুলি প্রকাশ করার জন্য একাধিক পরিচিত স্থাপত্যের সংশ্লেষ করা।

তাঁর ইউএমএল বর্গ চিত্রটি (নীচের চিত্রটি) অনন্য ক্লিন আর্কিটেকচার ডিজাইন হিসাবে বিবেচনা করা প্রতিফলনশীল হবে । এই চিত্রটি কংক্রিটের উদাহরণগুলির জন্য আঁকতে পারে … তবে, যেহেতু এটি সাধারণ স্থাপত্যের উপস্থাপনাগুলির তুলনায় অনেক কম বিমূর্ত, তাকে কন্ট্রাক্ট পছন্দ করতে হয়েছিল যার মধ্যে ইন্টারেক্টর আউটপুট পোর্ট ডিজাইন যা কেবলমাত্র একটি বাস্তবায়ন বিশদ ...

চাচা ববসের ইউএমএল ক্লাস চিত্রটি ক্লিন আর্কিটেকচারের ure


আমার দুই সেন্ট

আমি কেন ফিরে আসতে পছন্দ করি তার মূল কারণ UseCaseResponseহ'ল এই পদ্ধতিটি আমার ব্যবহারের কেসগুলিকে নমনীয় রাখে , তাদের এবং উদারতা ( সাধারণীকরণ এবং নির্দিষ্ট প্রজন্ম ) উভয়ের মধ্যে রচনা তৈরি করে । একটি প্রাথমিক উদাহরণ:

// A generic "entity type agnostic" use case encapsulating the interaction logic itself.
class UpdateUseCase implements UpdateUseCaseInterface
{
    function __construct(EntityGatewayInterface $entityGateway, GetUseCaseInterface $getUseCase)
    {
        $this->entityGateway = $entityGateway;
        $this->getUseCase = $getUseCase;
    }

    public function execute(UpdateUseCaseRequestInterface $request) : UpdateUseCaseResponseInterface
    {
        $getUseCaseResponse = $this->getUseCase->execute($request);

        // Update the entity and build the response...

        return $response;
    }
}

// "entity type aware" use cases encapsulating the interaction logic WITH the specific entity type.
final class UpdatePostUseCase extends UpdateUseCase;
final class UpdateProductUseCase extends UpdateUseCase;

মনে রাখবেন এটি ইউএমএল ব্যবহারের ক্ষেত্রে একে অপরের সাথে প্রসারিত / প্রসারিত এবং বিভিন্ন বিষয়ে (সত্তাগুলি) পুনঃব্যবহারযোগ্য হিসাবে সংজ্ঞায়িত হয়ে থাকে alog


মিথস্ক্রিয় তথ্য ফেরত

তবে, প্রকৃত উপস্থাপনাটি আর সঞ্চালিত হওয়ার সময় ব্যবহারের ক্ষেত্রে সেই মুহুর্তটি নিয়ন্ত্রণ করা হয় না (যা কার্যকর হতে পারে, উদাহরণস্বরূপ সেই সময়ে অতিরিক্ত জিনিসগুলি যেমন লগিং করা বা প্রয়োজনে এটি পুরোপুরি বাতিল করা)।

আপনি এর অর্থ কী তা বোঝার জন্য নিশ্চিত নন, উপস্থাপনার পারফরম্যান্সটি কেন আপনার "নিয়ন্ত্রণ" করতে হবে? আপনি যতক্ষণ ব্যবহারের ক্ষেত্রে প্রতিক্রিয়া না ফেরান ততক্ষণ আপনি এটি নিয়ন্ত্রণ করেন না?

ব্যবহারের কেসটি তার প্রতিক্রিয়ায় একটি স্ট্যাটাস কোড ফিরে আসতে পারে যাতে ক্লায়েন্ট স্তরটির কাজটি চলাকালীন ঠিক কী ঘটেছিল তা জানাতে। HTTP প্রতিক্রিয়া স্থিতি কোডগুলি ব্যবহারের মামলার অপারেশন স্থিতি বর্ণনা করার জন্য বিশেষভাবে উপযুক্ত ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.