ডক ব্রাউন এর উত্তরটি ল অফ ডিমেটারের একটি ক্লাসিক পাঠ্যপুস্তক বাস্তবায়ন দেখায় - এবং কয়েক ডজন পদ্ধতি যুক্ত করার কারণে বিরক্তি / বিশৃঙ্খলা-কোড-ব্লাট সম্ভবত প্রোগ্রামাররা, আমার অন্তর্ভুক্ত ছিল, প্রায়শই এমনটি করা বিরক্ত করে না, যদিও তাদের করা উচিত।
অবজেক্টের শ্রেণিবিন্যাসকে দ্বিগুণ করার বিকল্প উপায় রয়েছে:
প্রকাশ interfaceধরনের বদলে classধরনের, আপনার পদ্ধতি এবং বৈশিষ্ট্য মাধ্যমে।
অরিজিনাল পোস্টারের ক্ষেত্রে (ওপি'র) এর পরিবর্তে encoder->WaitEncoderFrame()একটি IEncoderFrameপরিবর্তিত ফিরিয়ে দেয় Frameএবং কোন ক্রিয়াকলাপ অনুমোদনযোগ্য তা নির্ধারণ করে।
সমাধান 1
সবচেয়ে সহজ ক্ষেত্রে, Frameএবং Encoderক্লাসগুলি উভয়ই আপনার নিয়ন্ত্রণে থাকে, IEncoderFrameএটি ফ্রেমের ইতিমধ্যে প্রকাশ্যে প্রকাশিত পদ্ধতিগুলির একটি উপসেট এবং Encoderক্লাসটি আসলে সেই বিষয়টির যত্ন নেয় না যে আপনি সেই অবজেক্টটির জন্য কী করেন। তারপরে, বাস্তবায়ন তুচ্ছ ( সি # তে কোড ):
interface IEncoderFrame {
void DoOrGetSomething();
}
class Frame : IEncoderFrame {
// A method that already exists in Frame.
public void DoOrGetSomething() { ... }
}
class Encoder {
private Frame _frame;
public IEncoderFrame TheFrame { get { return _frame; } }
...
}
সমাধান 2
মধ্যবর্তী ক্ষেত্রে, যেখানে Frameসংজ্ঞা আপনার নিয়ন্ত্রণে নেই, বা IEncoderFrameএর পদ্ধতিগুলি যুক্ত করা উপযুক্ত হবে না Frame, তবে একটি ভাল সমাধান হ'ল অ্যাডাপ্টার । এটা কী CandiedOrange এর উত্তর হিসাবে আলোচনা new FrameHandler( frame )। গুরুত্বপূর্ণ: আপনি এই কাজ করতে পারেন, এটি আরো নমনীয় যদি আপনি একটি যেমন এক্সপোজ ইন্টারফেস নয় হিসাবে, বর্গ । Encoderসম্পর্কে জানতে হবে class FrameHandler, কিন্তু ক্লায়েন্টদের কেবল এটি জানা দরকার interface IFrameHandler। বা যেমন আমি এটির নাম দিয়েছি interface IEncoderFrame- এটি নির্দিষ্ট করার জন্য এটি এনকোডারের পিওভি থেকে পাওয়া ফ্রেমের বিশেষত :
interface IEncoderFrame {
void DoOrGetSomething();
}
// Adapter pattern. Appropriate if no access needed to Encoder.
class EncoderFrameWrapper : IEncoderFrame {
Frame _frame;
public EncoderFrameWrapper( Frame frame ) {
_frame = frame;
}
public void DoOrGetSomething() {
_frame....;
}
}
class Encoder {
private Frame _frame;
// Adapter pattern. Appropriate if no access needed to Encoder.
public IEncoderFrame TheFrame { get { return new EncoderFrameWrapper( _frame ); } }
...
}
কাস্ট: বরাদ্দ এবং একটি নতুন অবজেক্টের জিসি, এনকোডার ফ্রেমওয়্যার্পার, প্রতিবার encoder.TheFrameবলা হয়। (আপনি সেই মোড়কটিকে ক্যাশে রাখতে পারেন তবে এটি আরও কোড যুক্ত করে And এবং এনকোডারের ফ্রেম ক্ষেত্রটি কোনও নতুন ফ্রেমের সাথে প্রতিস্থাপন করা না গেলে নির্ভরযোগ্যভাবে কোড করা সহজ))
সমাধান 3
আরও কঠিন ক্ষেত্রে, নতুন মোড়ক দুটি Encoderএবং উভয়েরই সম্পর্কে জানতে হবে Frame। এই অবজেক্টটি নিজেই লোড লঙ্ঘন করবে - এটি এনকোডার এবং ফ্রেমের মধ্যে এমন একটি সম্পর্ককে ম্যানিপুলেট করছে যা এনকোডারের দায়িত্ব হওয়া উচিত - এবং সম্ভবত সঠিকভাবে পেতে ব্যথা হতে পারে। আপনি যদি এই রাস্তাটি শুরু করেন তবে কি ঘটতে পারে তা এখানে:
interface IEncoderFrame {
void DoOrGetSomething();
}
// *** You will end up regretting this. See next code snippet instead ***
class EncoderFrameWrapper : IEncoderFrame {
Encoder _owner;
Frame _frame;
public EncoderFrameWrapper( Encoder owner, Frame frame ) {
_owner = owner; _frame = frame;
}
public void DoOrGetSomething() {
_frame.DoOrGetSomething();
// Hmm, maybe this wrapper class should be nested inside Encoder...
_owner... some work inside owner; maybe should be owner-internal details ...
}
}
class Encoder {
private Frame _frame;
...
}
কুৎসিত হয়েছে। একটি কম-সংশ্লেষিত বাস্তবায়ন হয়, যখন মোড়কটির তার স্রষ্টা / মালিকের বিবরণ স্পর্শ করা প্রয়োজন (এনকোডার):
interface IEncoderFrame {
void DoOrGetSomething();
}
class Encoder : IEncoderFrame {
private Frame _frame;
// HA! Client gets to think of this as "the frame object",
// but its really me, intercepting it.
public IEncoderFrame TheFrame { get { return this; } }
// This is the method that the LoD approach suggests writing,
// except that we are exposing it only when the instance is accessed as an IEncoderFrame,
// to avoid extending Encoder's already large API surface.
public void IEncoderFrame.DoOrGetSomething() {
_frame.DoOrGetSomething();
... make some change within current Encoder instance ...
}
...
}
মঞ্জুর, আমি যদি জানতাম আমি এখানেই শেষ করতাম তবে আমি এটি না করতাম। শুধু লোড পদ্ধতি লিখতে পারে এবং এটি দিয়ে সম্পন্ন করা যায়। একটি ইন্টারফেস সংজ্ঞায়িত করার প্রয়োজন নেই। অন্যদিকে, আমি এটি পছন্দ করি যে ইন্টারফেসটি সম্পর্কিত পদ্ধতিগুলি একসাথে আবৃত করে। ফ্রেমের মতো যা মনে হচ্ছে তার জন্য "ফ্রেমের মতো অপারেশন" করতে কেমন লাগে তা আমার পছন্দ হয়।
শেষ মন্তব্যসমূহ
এটি বিবেচনা করুন: যদি প্রয়োগকারীরা Encoderমনে করেন যে Frame frameতাদের সামগ্রিক আর্কিটেকচারের জন্য এক্সপোজারিং উপযুক্ত ছিল, বা "এলওডি বাস্তবায়নের চেয়ে অনেক সহজ" ছিল, তবে তারা যদি তার পরিবর্তে আমি প্রথম স্নিপেটটি দেখায় তবে এটি আরও নিরাপদ হত - এর একটি সীমাবদ্ধ উপসেটটি উন্মোচন করা হয়েছিল it ফ্রেম, একটি ইন্টারফেস হিসাবে। আমার অভিজ্ঞতায়, এটি প্রায়শই সম্পূর্ণ কার্যক্ষম সমাধান। প্রয়োজন অনুযায়ী ইন্টারফেসে কেবল পদ্ধতিগুলি যুক্ত করুন। (আমি এমন একটি দৃশ্যের কথা বলছি যেখানে আমরা ফ্রেমটির ইতিমধ্যে প্রয়োজনীয় পদ্ধতিগুলি "জানি" আছে বা এটি যুক্ত করা সহজ এবং বিতর্কিত হতে পারে each প্রতিটি পদ্ধতির জন্য "বাস্তবায়ন" কাজ ইন্টারফেস সংজ্ঞাতে একটি লাইন যুক্ত করছে)) জেনে রাখুন যে ভবিষ্যতের সবচেয়ে খারাপ পরিস্থিতিতে এমনকি এপিআই কাজ করা সম্ভব - এখানে,IEncoderFrameFrameEncoder।
আরও মনে রাখবেন যে আপনার যদি যোগ IEncoderFrameকরার অনুমতি না থাকে Frameবা প্রয়োজনীয় পদ্ধতিগুলি সাধারণ Frameশ্রেণীর সাথে উপযুক্ত না খায় এবং সমাধান # 2 আপনার পক্ষে উপযুক্ত নয়, সম্ভবত অতিরিক্ত বস্তু তৈরি এবং ধ্বংসের কারণে, সমাধান # 3 Encoderএটিকে লোড অর্জনের পদ্ধতিগুলি সংগঠিত করার সহজ উপায় হিসাবে দেখা যায় । কয়েক ডজন পদ্ধতিতে কেবল পাস করবেন না। এগুলি একটি ইন্টারফেসে মুড়ে রাখুন এবং "স্পষ্টতাল ইন্টারফেস বাস্তবায়ন" (যদি আপনি সি # তে থাকেন) ব্যবহার করুন, যাতে কেবলমাত্র সেই ইন্টারফেসের মাধ্যমে অবজেক্টটি দেখা গেলেই তাদের অ্যাক্সেস করা যায়।
আমি আরেকটি বিষয় জোর দিতে চাই যে হ'ল একটি ইন্টারফেস হিসাবে কার্যকারিতা প্রকাশ করার সিদ্ধান্ত , উপরে বর্ণিত পরিস্থিতিগুলির সমস্ত 3 পরিচালনা করে। প্রথমত, IEncoderFrameএটি কেবলমাত্র Frameকার্যকারিতার একটি উপসেট । দ্বিতীয়টিতে, IEncoderFrameএকটি অ্যাডাপ্টার। তৃতীয়টি, এর কার্যকারিতা IEncoderFrameমধ্যে একটি পার্টিশন Encoder। এই তিনটি পরিস্থিতির মধ্যে আপনার প্রয়োজনগুলি পরিবর্তিত হয় তা বিবেচ্য নয়: এপিআই একই থাকে।