টিএল; ডিআর: এনামগুলির সংকলনটি ব্যবহার করা সাধারণত একটি খারাপ ধারণা কারণ এটি প্রায়শই খারাপ ডিজাইনের দিকে পরিচালিত করে। এনামগুলির একটি সংকলন সাধারণত নির্দিষ্ট যুক্তিযুক্ত স্বতন্ত্র সিস্টেম সত্তাদের জন্য আহ্বান জানায়।
এনামের কয়েকটি ব্যবহারের ক্ষেত্রে এটির মধ্যে পার্থক্য করা প্রয়োজন। এই তালিকাটি কেবল আমার মাথার শীর্ষে রয়েছে যাতে আরও কিছু মামলা হতে পারে ...
উদাহরণগুলি সমস্ত সি # তে রয়েছে, আমি অনুমান করি আপনার পছন্দের ভাষার সাথে একই রকমের গঠন বা তার পক্ষে নিজেকে প্রয়োগ করা সম্ভব হবে।
1. শুধুমাত্র একক মান বৈধ
এই ক্ষেত্রে, মানগুলি একচেটিয়া, যেমন
public enum WorkStates
{
Init,
Pending,
Done
}
উভয় Pending
এবং উভয়ই এমন কিছু কাজ করা অবৈধ Done
। সুতরাং এই মানগুলির মধ্যে একটিই বৈধ। এটি এনামের ভাল ব্যবহারের ক্ষেত্রে।
2. মানগুলির সংমিশ্রণ বৈধ হয়
এই [Flags]
কেসটিকে পতাকাও বলা হয়, সি # এগুলির সাথে কাজ করার জন্য এনাম অ্যাট্রিবিউট সরবরাহ করে। ধারণাটি প্রতিটি এনাম সদস্যের সাথে সংশ্লিষ্ট প্রতিটি bool
বা bit
গুলিগুলির সেট হিসাবে তৈরি করা যেতে পারে । প্রতিটি সদস্যের দু'জনের পাওয়ার মান হওয়া উচিত। বিটওয়াইজ অপারেটরগুলি ব্যবহার করে সংমিশ্রণগুলি তৈরি করা যেতে পারে:
[Flags]
public enum Flags
{
None = 0,
Flag0 = 1, // 0x01, 1 << 0
Flag1 = 2, // 0x02, 1 << 1
Flag2 = 4, // 0x04, 1 << 2
Flag3 = 8, // 0x08, 1 << 3
Flag4 = 16, // 0x10, 1 << 4
AFrequentlyUsedMask = Flag1 | Flag2 | Flag4,
All = ~0 // bitwise negation of zero is all ones
}
এনাম সদস্যদের সংগ্রহ ব্যবহার করা যেমন একটি ক্ষেত্রে ওভারকিল কারণ প্রতিটি এনাম সদস্য কেবল একটি বিট উপস্থাপন করেন যা হয় সেট করা বা আনসেট করা হয় না। আমার ধারণা, বেশিরভাগ ভাষা এই জাতীয় নির্মাণকে সমর্থন করে। অন্যথায় আপনি একটি তৈরি করতে পারেন (উদাহরণস্বরূপ এটি ব্যবহার bool[]
এবং ঠিকানা (1 << (int)YourEnum.SomeMember) - 1
)।
ক) সমস্ত সংমিশ্রণগুলি বৈধ
এগুলি কিছু সাধারণ ক্ষেত্রে ঠিক থাকলেও অবজেক্টের সংগ্রহ আরও উপযুক্ত হতে পারে কারণ আপনার প্রায়শই ধরণের উপর ভিত্তি করে অতিরিক্ত তথ্য বা আচরণের প্রয়োজন হয়।
[Flags]
public enum Flavors
{
Strawberry = 1,
Vanilla = 2,
Chocolate = 4
}
public class IceCream
{
private Flavors _scoopFlavors;
public IceCream(Flavors scoopFlavors)
{
_scoopFlavors = scoopFlavors
}
public bool HasFlavor(Flavors flavor)
{
return _scoopFlavors.HasFlag(flavor);
}
}
(দ্রষ্টব্য: এটি ধরে নিয়েছে যে আপনি কেবল আইসক্রিমের স্বাদ সম্পর্কেই যত্নশীল - আপনাকে আইসক্রিমকে স্কুপ এবং শঙ্কু সংগ্রহ হিসাবে মডেল করার দরকার নেই)
খ) মানগুলির কয়েকটি সমন্বয় বৈধ এবং কিছু নয়
এটি একটি ঘন ঘন দৃশ্য। কেসটি প্রায়শই এমন হতে পারে যে আপনি একটি এনামে দুটি আলাদা জিনিস রাখছেন। উদাহরণ:
[Flags]
public enum Parts
{
Wheel = 1,
Window = 2,
Door = 4,
}
public class Building
{
public Parts parts { get; set; }
}
public class Vehicle
{
public Parts parts { get; set; }
}
এখন যখন এটি উভয়ের জন্য সম্পূর্ণরূপে বৈধ নয় Vehicle
এবং Building
আছে Door
s এবং Window
গুলি, তাই না খুব স্বাভাবিক জন্য Building
গুলি আছে Wheel
সে।
এক্ষেত্রে, # 1 বা # 2a কেস অর্জনের জন্য এনামগুলি অংশগুলিতে বিভক্ত করা এবং / অথবা বস্তুক্রমক্রমকে সংশোধন করা ভাল।
ডিজাইন বিবেচ্য বিষয়
একরকম, এনামগুলি OO- এ ড্রাইভিং উপাদান হিসাবে বিবেচনা করে না, কারণ কোনও সত্তার ধরণটি সাধারণত একটি এনাম দ্বারা সরবরাহ করা তথ্যের অনুরূপ বিবেচনা করা যেতে পারে।
উদাহরণস্বরূপ IceCream
# 2 থেকে নমুনা নিন , IceCream
সত্তার পতাকার পরিবর্তে Scoop
বস্তুগুলির সংগ্রহ থাকবে ।
Scoop
কোনও Flavor
সম্পত্তি থাকার জন্য কম পিউরিস্ট পদ্ধতির পক্ষে হবে approach প্রকৃতিবাদী পদ্ধতির হতে জন্য হবে Scoop
একটি বিমূর্ত বেস বর্গ হতে VanillaScoop
, ChocolateScoop
... শ্রেণীর পরিবর্তে।
নীচের লাইনটি হ'ল:
১. যে কোনও কিছু "প্রকারের কিছু" হিসাবে এনামের দরকার
হয় না some
এখন আপনার উদাহরণের জন্য (সামান্য পরিবর্তিত):
public enum Role
{
User,
Admin
}
public class User
{
public List<Role> Roles { get; set; }
}
আমি মনে করি এই সঠিক কেসটি মডেল করা উচিত (দ্রষ্টব্য: সত্যই এক্সটেনসিবল নয়!):
public class User
{
public bool IsAdmin { get; set; }
}
অন্য কথায় - এটা অন্তর্নিহিত হয়, যে User
একটি হল User
, অতিরিক্ত তথ্য কিনা সে একটি হল Admin
।
আপনি একাধিক ভূমিকাগুলি দেখে একচেটিয়া নয় আছে পেলে (যেমন User
হতে পারে Admin
, Moderator
, VIP
, ... একই সময়ে), যে হয় পতাকার enum ব্যবহার করার জন্য একটি ভাল সময় অথবা একটি abtract বেস বর্গ বা ইন্টারফেস হবে।
কোনও শ্রেণি ব্যবহার করে Role
নেতৃত্বের প্রতিনিধিত্ব করার জন্য দায়িত্বের আরও ভাল বিভাজনের দিকে পরিচালিত হয় যেখানে Role
কোনও প্রদত্ত ক্রিয়াটি করতে পারে কিনা তা সিদ্ধান্ত নেওয়ার দায়িত্ব একজনের নিতে পারে।
একটি এনামের সাথে আপনার সমস্ত ভূমিকার জন্য যুক্তি যুক্ত করতে হবে। যা ওওর উদ্দেশ্যকে পরাস্ত করে এবং আপনাকে অত্যাবশ্যকীয় দিকে ফিরিয়ে আনে।
কল্পনা করুন যে একটিতে Moderator
সম্পাদনা করার অধিকার রয়েছে এবং Admin
এতে সম্পাদনা এবং মুছুন উভয়ই অধিকার রয়েছে।
এনাম এপ্রোচ ( Permissions
ভূমিকা এবং অনুমতিগুলিকে মিশ্রিত না করার জন্য ডাকা হয়):
[Flags]
public enum Permissions
{
None = 0
CanEdit = 1,
CanDelete = 2,
ModeratorPermissions = CanEdit,
AdminPermissions = ModeratorPermissions | CanDelete
}
public class User
{
private Permissions _permissions;
public bool CanExecute(IAction action)
{
if (action.Type == ActionType.Edit && _permissions.HasFlag(Permissions.CanEdit))
{
return true;
}
if (action.Type == ActionType.Delete && _permissions.HasFlag(Permissions.CanDelete))
{
return true;
}
return false;
}
}
শ্রেণি পদ্ধতির (এটি নিখুঁত থেকে অনেক দূরে, আদর্শভাবে, আপনি IAction
একটি দর্শনার্থীর প্যাটার্নে এটি দেখতে চাই তবে এই পোস্টটি ইতিমধ্যে প্রচুর ...):
public interface IRole
{
bool CanExecute(IAction action);
}
public class ModeratorRole : IRole
{
public virtual bool CanExecute(IAction action)
{
return action.Type == ActionType.Edit;
}
}
public class AdminRole : ModeratorRole
{
public override bool CanExecute(IAction action)
{
return base.CanExecute(action) || action.Type == ActionType.Delete;
}
}
public class User
{
private List<IRole> _roles;
public bool CanExecute(IAction action)
{
_roles.Any(x => x.CanExecute(action));
}
}
এনাম ব্যবহার করা একটি গ্রহণযোগ্য পদ্ধতির হতে পারে যদিও (উদাহরণস্বরূপ কর্মক্ষমতা)। এখানে সিদ্ধান্ত মডেলিং সিস্টেমের প্রয়োজনীয়তার উপর নির্ভর করে।