" একটি পাসওয়ার্ড পুনরায় সেট করতে পারে " এর এই নির্দিষ্ট উদাহরণের জন্য , আমি উত্তরাধিকারের উপর রচনাটি ব্যবহার করার পরামর্শ দেব (এই ক্ষেত্রে, কোনও ইন্টারফেস / চুক্তির উত্তরাধিকার)। কারণ, এটি করে:
class Foo : IResetsPassword {
//...
}
আপনি অবিলম্বে নির্দিষ্ট করে দিচ্ছেন (সংকলনের সময়) যে আপনার ক্লাসটি ' পাসওয়ার্ড পুনরায় সেট করতে পারে '। তবে, যদি আপনার দৃশ্যে, সামর্থ্যের উপস্থিতি শর্তযুক্ত এবং অন্যান্য বিষয়ের উপর নির্ভর করে, তবে আপনি আর সংকলনের সময় জিনিসগুলি নির্দিষ্ট করতে পারবেন না। তারপরে, আমি এটি করার পরামর্শ দিচ্ছি:
class Foo {
PasswordResetter passwordResetter;
}
এখন, রানটাইমে, আপনি myFoo.passwordResetter != null
এই অপারেশনটি করার আগে পরীক্ষা করতে পারেন । আপনি যদি আরও বেশি জিনিস ডিকুয়াল করতে চান (এবং আপনি আরও অনেক ক্ষমতা যুক্ত করার পরিকল্পনা করেন), আপনি করতে পারেন:
class Foo {
//... foo stuff
}
class PasswordResetOperation {
bool Execute(Foo foo) { ... }
}
class SendMailOperation {
bool Execute(Foo foo) { ... }
}
//...and you follow this pattern for each new capability...
হালনাগাদ
আমি ওপি থেকে কিছু অন্যান্য উত্তর এবং মন্তব্য পড়ার পরে বুঝতে পেরেছিলাম যে প্রশ্নটি কম্পোজিশনাল সমাধান সম্পর্কে নয়। সুতরাং আমি মনে করি যে প্রশ্নটি নীচে যেমন একটি দৃশ্যে সাধারণভাবে অবজেক্টগুলির দক্ষতা কীভাবে আরও ভালভাবে চিহ্নিত করতে হয় সে সম্পর্কে:
class BaseAccount {
//...
}
class GuestAccount : BaseAccount {
//...
}
class UserAccount : BaseAccount, IMyPasswordReset, IEditPosts {
//...
}
class AdminAccount : BaseAccount, IPasswordReset, IEditPosts, ISendMail {
//...
}
//Capabilities
interface IMyPasswordReset {
bool ResetPassword();
}
interface IPasswordReset {
bool ResetPassword(UserAccount userAcc);
}
interface IEditPosts {
bool EditPost(long postId, ...);
}
interface ISendMail {
bool SendMail(string from, string to, ...);
}
এখন, আমি উল্লিখিত সমস্ত বিকল্প বিশ্লেষণ করার চেষ্টা করব:
ওপি দ্বিতীয় উদাহরণ:
if (account.CanResetPassword)
((IResetsPassword)account).ResetPassword();
else
Print("Not allowed to reset password with this account type!");
ধরা যাক এই কোডটি কিছু বেস অ্যাকাউন্ট ক্লাস গ্রহণ করছে (যেমন: BaseAccount
আমার উদাহরণে); এটি বেস ক্লাসে বুলিয়ানগুলি tingোকানো হচ্ছে, কোড সহ এটি দূষিত করছে যা এটির কোনও কারণই বোধ করে না this
ওপি প্রথম উদাহরণ:
if (account is IResetsPassword)
((IResetsPassword)account).ResetPassword();
else
Print("Not allowed to reset password with this account type!");
প্রশ্নের উত্তর দিতে, এটি পূর্ববর্তী বিকল্পের চেয়ে বেশি উপযুক্ত, তবে বাস্তবায়নের উপর নির্ভর করে এটি শক্তির এল নীতিটি ভেঙে দেবে, এবং সম্ভবত এই জাতীয় চেকগুলি কোডের মাধ্যমে ছড়িয়ে দেওয়া হবে এবং আরও রক্ষণাবেক্ষণকে আরও কঠিন করে তুলবে।
ক্যান্ডিডআরঞ্জের আনসার:
account.ResetPassword(authority);
যদি এই ResetPassword
পদ্ধতিটি BaseAccount
ক্লাসে সন্নিবেশ করা হয় , তবে এটি অপের দ্বিতীয় উদাহরণের মতো অনুপযুক্ত কোড সহ বেস শ্রেণিকেও দূষিত করছে
স্নোম্যানের উত্তর:
AccountManager.resetPassword(otherAccount, adminAccount.getAccessToken());
এটি একটি ভাল সমাধান, তবে এটি বিবেচনা করে যে ক্ষমতাগুলি গতিশীল (এবং সময়ের সাথে সাথে এটি পরিবর্তিত হতে পারে)। যাইহোক, আমি ওপি থেকে বেশ কয়েকটি মন্তব্য পড়ার পরে অনুমান করি যে এখানে আলাপটি বহুমুখীতা এবং স্থিতিশীলভাবে সংজ্ঞায়িত শ্রেণিবদ্ধ সম্পর্কিত (যদিও অ্যাকাউন্টগুলির উদাহরণ স্বজ্ঞাতভাবে গতিশীল দৃশ্যের দিকে নির্দেশ করে)। ইজি: এই AccountManager
উদাহরণে অনুমোদনের জন্য চেক করা হবে ডিবি-র প্রশ্নসমূহ; ও.পি. প্রশ্নে চেকগুলি বস্তুগুলি castালাই দেওয়ার চেষ্টা করা হয়।
আমার আরেকটি পরামর্শ:
উচ্চ স্তরের শাখার জন্য টেম্পলেট পদ্ধতি প্যাটার্ন ব্যবহার করুন। উল্লিখিত শ্রেণি শ্রেণিবিন্যাসটি যেমন রয়েছে তেমন রাখা হয়; বেস ক্লাসকে কলুষিত করার জন্য ক্যাস্ট এবং অনুপযুক্ত বৈশিষ্ট্য / পদ্ধতিগুলি এড়াতে আমরা কেবলমাত্র অবজেক্টগুলির জন্য আরও উপযুক্ত হ্যান্ডলার তৈরি করি।
//Template method
class BaseAccountOperation {
BaseAccount account;
void Execute() {
//... some processing
TryResetPassword();
//... some processing
TrySendMail();
//... some processing
}
void TryResetPassword() {
Print("Not allowed to reset password with this account type!");
}
void TrySendMail() {
Print("Not allowed to reset password with this account type!");
}
}
class UserAccountOperation : BaseAccountOperation {
UserAccount userAccount;
void TryResetPassword() {
account.ResetPassword(...);
}
}
class AdminAccountOperation : BaseAccountOperation {
AdminAccount adminAccount;
override void TryResetPassword() {
account.ResetPassword(...);
}
void TrySendMail() {
account.SendMail(...);
}
}
আপনি ডিকশনারি / হ্যাশটেবল ব্যবহার করে যথাযথ অ্যাকাউন্ট শ্রেণিতে অপারেশনকে আবদ্ধ করতে পারেন, বা এক্সটেনশন পদ্ধতিগুলি ব্যবহার করে রান-টাইম ক্রিয়াকলাপগুলি ব্যবহার করতে পারেন, dynamic
কীওয়ার্ডটি ব্যবহার করতে পারেন বা শেষ বিকল্প হিসাবে অ্যাকাউন্টের অবজেক্টটি অপারেশনটিতে পাস করার জন্য কেবলমাত্র একটি কাস্ট ব্যবহার করুন (এতে এই ক্ষেত্রে কাস্টের সংখ্যা কেবলমাত্র এক, অপারেশন শুরুতে)।