একজন অবশ্যই অবশ্যই ফাঁসী বিমূর্তনের আইনটি আহ্বান করতে পারেন, তবে এটি বিশেষ আকর্ষণীয় নয় কারণ এটি মনে করেন যে সমস্ত বিমূর্ততা ফাঁস। কেউ এই অনুমানের পক্ষে বা বিপক্ষে যুক্তি দিতে পারে, তবে আমরা যদি বিমূর্তির দ্বারা আমরা কী বোঝাতে চাইছি এবং ফাঁস দিয়ে কী বোঝাতে চাইছি তার কোনও বোঝা ভাগ না করি তবে এটি কার্যকর হয় না । অতএব, আমি প্রথমে এই শর্তগুলির প্রতিটি কীভাবে দেখছি তা বর্ণনা করার চেষ্টা করব:
abstractions
আমার প্রিয় সংজ্ঞা বিমূর্ত রবার্ট সি মার্টিন এর থেকে প্রাপ্ত করা হয় APPP :
"একটি বিমূর্ততা অপরিহার্য অপরিহার্যকরণ এবং অপ্রাসঙ্গিক নির্মূলকরণ।"
সুতরাং, ইন্টারফেসগুলি নিজের মধ্যে বিমূর্ততা নয় । এগুলি কেবলমাত্র বিমূর্ততা যদি তারা কোন বিষয়টিকে পৃষ্ঠতলে নিয়ে আসে এবং বাকিগুলি লুকিয়ে রাখে।
ছিদ্রময়
ডিপেন্ডেন্সি ইনজেকশন প্রিন্সিপালস, প্যাটার্নস এবং অনুশীলন বইটি নির্ভরতা ইনজেকশন (ডিআই) এর প্রসঙ্গে ফাঁসী বিমূর্ততা শব্দটিকে সংজ্ঞায়িত করে । পলিমারফিজম এবং সলাইড নীতিগুলি এই প্রসঙ্গে একটি বড় ভূমিকা পালন করে।
থেকে নির্ভরতা ইনভার্সান নীতি (চোবান) এটিকে অনুসরণ করে, অনুসরণ করে আবার APPP উদ্ধৃত, যে:
"ক্লায়েন্টরা [...] বিমূর্ত ইন্টারফেসের মালিক"
এর অর্থ হ'ল ক্লায়েন্ট (কলিং কোড) তাদের প্রয়োজনীয় বিমূর্ততাগুলি সংজ্ঞায়িত করে এবং তারপরে আপনি গিয়ে সেই বিমূর্তনটি প্রয়োগ করেন।
একটি দৃak় বিমূর্ততা , আমার দৃষ্টিতে, এটি একটি বিমূর্ততা যা ক্লায়েন্টের প্রয়োজন হয় না এমন কিছু কার্যকারিতা সহ কোনওভাবে ডিআইপি লঙ্ঘন করে ।
সিঙ্ক্রোনাস নির্ভরতা
কোনও ক্লায়েন্ট যা ব্যবসায়ের যুক্তিযুক্ত অংশ প্রয়োগ করে সাধারণত কিছু প্রয়োগকারীর বিবরণ যেমন সাধারণত, ডাটাবেসগুলি থেকে নিজেকে ডিক্লোল করার জন্য ডিআই ব্যবহার করবে।
এমন একটি ডোমেন অবজেক্ট বিবেচনা করুন যা রেস্তোঁরা সংরক্ষণের জন্য একটি অনুরোধ পরিচালনা করে:
public class MaîtreD : IMaîtreD
{
public MaîtreD(int capacity, IReservationsRepository repository)
{
Capacity = capacity;
Repository = repository;
}
public int Capacity { get; }
public IReservationsRepository Repository { get; }
public int? TryAccept(Reservation reservation)
{
var reservations = Repository.ReadReservations(reservation.Date);
int reservedSeats = reservations.Sum(r => r.Quantity);
if (Capacity < reservedSeats + reservation.Quantity)
return null;
reservation.IsAccepted = true;
return Repository.Create(reservation);
}
}
এখানে IReservationsRepository
নির্ভরতা ক্লায়েন্ট, ক্লাস দ্বারা একচেটিয়াভাবে নির্ধারণ করা হয় MaîtreD
:
public interface IReservationsRepository
{
Reservation[] ReadReservations(DateTimeOffset date);
int Create(Reservation reservation);
}
এই ইন্টারফেসটি সম্পূর্ণরূপে সিঙ্ক্রোনাস কারণ ক্লাসটির এটি অ্যাসিঙ্ক্রোনাস হওয়ার দরকারMaîtreD
নেই ।
অ্যাসিনক্রোনাস নির্ভরতা
আপনি ইন্টারফেসটি সহজেই অ্যাসিক্রোনাসে পরিবর্তন করতে পারেন:
public interface IReservationsRepository
{
Task<Reservation[]> ReadReservations(DateTimeOffset date);
Task<int> Create(Reservation reservation);
}
MaîtreD
বর্গ, তবে না প্রয়োজন সেই পদ্ধতি অ্যাসিঙ্ক্রোনাস হতে, তাই এখন চোবান লঙ্ঘন করা হয়। আমি এটিকে একটি ফাঁসী বিমূর্ততা হিসাবে বিবেচনা করি কারণ একটি বাস্তবায়নের বিশদটি ক্লায়েন্টকে পরিবর্তন করতে বাধ্য করে। TryAccept
পদ্ধতি এখন অ্যাসিঙ্ক্রোনাস পরিণত আছে:
public async Task<int?> TryAccept(Reservation reservation)
{
var reservations =
await Repository.ReadReservations(reservation.Date);
int reservedSeats = reservations.Sum(r => r.Quantity);
if (Capacity < reservedSeats + reservation.Quantity)
return null;
reservation.IsAccepted = true;
return await Repository.Create(reservation);
}
ডোমেন যুক্তিকে অ্যাসিক্রোনোনাস হওয়ার কোনও সহজাত যুক্তি নেই, তবে বাস্তবায়নের অ্যাসিনক্রোনিকে সমর্থন করার জন্য, এখন এটি প্রয়োজন required
আরও ভাল বিকল্প
এনডিসি সিডনি 2018 এ আমি এই বিষয়টিতে একটি আলোচনা দিয়েছিলাম । এটিতে, আমি এমন একটি বিকল্পের রূপরেখাও বলি যা ফাঁস হয় না। আমি 2019 সালেও বেশ কয়েকটি সম্মেলনে এই আলোচনা করব, তবে এখন অ্যাসিঙ্ক ইঞ্জেকশনের নতুন শিরোনাম দিয়ে পুনরায় ব্র্যান্ড করা হয়েছে ।
আমি আলাপটি সহ একসাথে ব্লগ পোস্ট প্রকাশ করার পরিকল্পনা করছি। এই নিবন্ধগুলি ইতিমধ্যে আমার নিবন্ধের কাতারে লেখা এবং বসে আছে, প্রকাশের অপেক্ষায়, তাই থাকুন।