ন্যূনতম জ্ঞানের মূলনীতি


32

আমি ন্যূনতম জ্ঞানের নীতির পিছনে উদ্দেশ্যটি বুঝতে পারি , তবে আমি যদি এটি আমার নকশায় প্রয়োগ করার চেষ্টা করি তবে আমি কিছু অসুবিধাগুলি খুঁজে পাই।

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

তবে মনে হয় কখনও কখনও এ জাতীয় ক্ষমতা ব্যবহার করা খুব প্রয়োজন।

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

streamer ক্লাস কোড

...
frame = encoder->WaitEncoderFrame()
frame->DoOrGetSomething();
....

আপনি দেখতে পাচ্ছেন যে এখানে এই নীতি প্রয়োগ করা হয়নি। এই নীতিটি এখানে প্রয়োগ করা যেতে পারে, বা এই নীতিটি সর্বদা এর মতো ডিজাইনে প্রয়োগ করা যায় না?




4
এটি সম্ভবত কাছাকাছি সদৃশ।
রবার্ট হার্ভে

1
সম্পর্কিত: এই জাতীয় কোড কি "ট্রেনের ধ্বংসস্তূপ" (ডেমিটারের আইন লঙ্ঘন করে)? (সম্পূর্ণ প্রকাশ: এটি আমার নিজের প্রশ্ন)
একটি সিভিএন

উত্তর:


21

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

  {
    frame = encoder->WaitEncoderFrame()
    DoOrGetSomethingForFrame(frame); 
    ...
  }

  void DoOrGetSomethingForFrame(Frame *frame)
  {
     frame->DoOrGetSomething();
  }  

এখন, প্রতিটি ফাংশন কেবল "বন্ধুদের সাথে কথা বলে", "বন্ধুদের বন্ধুদের" সাথে নয়।

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


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

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

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

10
+1: ডেমিটারের আইনটি সত্যই নামকরণের পরামর্শের নামকরণ করা উচিত : ওয়াইএমএমভি
বাইনারি ওয়ারিয়ার

ডিমেটারের আইনটি আর্কিটেকচারাল পছন্দগুলি করার জন্য একটি পরামর্শ, আপনি যখন প্রসাধনী পরিবর্তনের পরামর্শ দেন যাতে মনে হয় আপনি সেই 'আইন' মেনে চলেছেন। এটি একটি ভুল ধারণা হবে, কারণ একটি সিনট্যাক্টিকাল পরিবর্তন মানে হঠাৎ সব কিছু ঠিক হয়ে যায় না। যতদূর আমি জানি ডিমেটারের আইনটি মূলত বোঝানো হয়েছে: আপনি যদি ওওপি করতে চান তবে সর্বত্র গেটর ফাংশন সহ প্রোডেকুরাল কোড লেখা বন্ধ করুন।
ব্যবহারকারী 2180613

39

ন্যূনতম জ্ঞানের নীতিমালা বা লিমিটারের আইন হ'ল আপনার ক্লাসটিকে স্তরগুলির পরে স্তরকে অতিক্রম করে এমন অন্যান্য শ্রেণীর বিবরণ দিয়ে জড়িয়ে দেওয়ার বিরুদ্ধে একটি সতর্কতা। এটি আপনাকে বলে যে কেবলমাত্র আপনার "বন্ধুদের" সাথে কথা বলা ভাল, "বন্ধুদের বন্ধু" এর সাথে নয়।

কল্পনা করুন যে আপনাকে চকচকে প্লেটের বর্মের একটি নাইটের মূর্তির উপরে একটি ঝাল ldালাই করতে বলা হয়েছে। আপনি সাবধানে বাম বাহুতে positionালটি এমনভাবে স্থাপন করুন যাতে এটি প্রাকৃতিক লাগে looks আপনি খেয়াল করতে পারেন বাহুতে তিনটি ছোট জায়গা, কনুই এবং উপরের বাহুতে whereালটি বর্মটিকে স্পর্শ করার জন্য ঘটে। আপনি তিনটি জায়গায় ওয়েল্ড করেছেন কারণ আপনি নিশ্চিত হতে চান যে সংযোগটি শক্তিশালী। এখন ভাবুন আপনার বস পাগল কারণ তিনি তাঁর বর্মের কনুইটি সরাতে পারবেন না। আপনি ধরে নিয়েছেন যে বর্মটি কখনই চলবে না এবং তাই বাহু এবং উপরের বাহুর মধ্যে একটি স্থিতিশীল সংযোগ তৈরি করে। ঝালটি কেবল তার বন্ধু, সামনের বাহির সাথে সংযুক্ত হওয়া উচিত। বন্ধুদের অগ্রিম না। এমনকি তাদের স্পর্শ করতে আপনাকে যদি ধাতুর একটি অংশ যোগ করতে হয় তবে।

রূপকগুলি দুর্দান্ত তবে আমরা বন্ধু বলতে আসলে কী বোঝি? কোনও বস্তু কীভাবে তৈরি বা সন্ধান করতে জানে তা বন্ধু। বিকল্পভাবে, একটি অবজেক্ট কেবল অন্য জিনিসকে হস্তান্তর করতে বলতে চাইতে পারে , যার মধ্যে এটি কেবল ইন্টারফেসটি জানে। এগুলি বন্ধু হিসাবে গণ্য হয় না কারণ কীভাবে তাদের কীভাবে আরোপ করা যায় তার কোনও প্রত্যাশা নেই। যদি বস্তুটি না জানে যে তারা কোথা থেকে এসেছে কারণ অন্য কোনও কিছু এটি পাস / ইনজেকশন করেছে তবে এটি কোনও বন্ধুর বন্ধু নয়, এমনকি কোনও বন্ধুও নয়। এটি এমন কিছু যা কেবল ব্যবহার করতে জানে। সেটা একটা ভাল জিনিস.

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

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

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

আপনি যদি এই নীতিটি অনুসরণ করার সময় কোনও সমস্যার সমাধান করতে না পারেন তবে সম্ভবত অন্য কোনও দক্ষতা হারাতে পারে।

আপনার নির্দিষ্ট সমস্যার একটি সমাধান হ'ল frameএমন কিছু (একটি শ্রেণি বা পদ্ধতি) যা কীভাবে ফ্রেমে কথা বলতে হয় তা ইনজেকশন করা যাতে আপনার ক্লাসে এই সমস্ত ফ্রেম চ্যাটিংয়ের বিশদটি ছড়িয়ে দিতে হবে না, যা এখন কেবল কীভাবে এবং কখন করতে হবে তা জানে একটি ফ্রেম পেতে

এটি আসলে অন্য একটি নীতি অনুসরণ করে: নির্মাণ থেকে পৃথক ব্যবহার।

frame = encoder->WaitEncoderFrame()

এই কোডটি ব্যবহার করে আপনি কোনওভাবে কোনও অর্জনের জন্য দায়িত্ব নিয়েছেন Frame। ক এর সাথে কথা বলার জন্য আপনি এখনও কোনও দায়বদ্ধতা গ্রহণ করেন নি Frame

frame->DoOrGetSomething(); 

এখন আপনাকে কীভাবে কথা বলতে হয় তা জানতে হবে Frameতবে এটির সাথে প্রতিস্থাপন করুন:

new FrameHandler(frame)->DoOrGetSomething();

এবং এখন আপনাকে কেবল আপনার বন্ধু ফ্রেমহ্যান্ডলারের সাথে কীভাবে কথা বলতে হবে তা জানতে হবে।

এটি অর্জনের অনেকগুলি উপায় রয়েছে এবং এটি সম্ভবত সর্বোত্তম নয় তবে এটি দেখায় যে নীতিটি অনুসরণ করা কীভাবে সমস্যাটিকে অবিশ্বাস্য করে তোলে না। এটি আপনার কাছ থেকে আরও কাজ করার দাবি করছে।

প্রতিটি ভাল নিয়মের ব্যতিক্রম রয়েছে। আমার জানা সেরা উদাহরণগুলি হ'ল অভ্যন্তরীণ ডোমেন নির্দিষ্ট ভাষা । একটি ডিএসএল এর পদ্ধতি চেইনআপনি সর্বদা ডেমিটারের আইনটিকে আপত্তিজনক বলে মনে করছেন কারণ আপনি ক্রমাগত এমন পদ্ধতিগুলি কল করে যা বিভিন্ন ধরণের ফিরে আসে এবং সেগুলি সরাসরি ব্যবহার করে। কেন এই ঠিক আছে? কারণ ডিএসএল-এ ফিরে আসা সমস্ত কিছু হ'ল সতর্কতার সাথে ডিজাইন করা বন্ধু যা আপনাকে সরাসরি কথা বলার জন্য বোঝানো হয়। ডিজাইন অনুসারে, আপনাকে কোনও ডিএসএলের মেথড চেইনটি পরিবর্তন না হওয়ার আশা করার অধিকার দেওয়া হয়েছে। আপনি যদি এলোমেলোভাবে কোড বেজে অনুসন্ধান করেন তবে যা কিছু খুজে পেয়েছেন তা একসাথে শৃঙ্খলাবদ্ধ করে ফেললে আপনার সেই অধিকার নেই। সেরা ডিএসএল হ'ল খুব কম পাতলা উপস্থাপনা বা অন্যান্য অবজেক্টের ইন্টারফেস যা আপনার সম্ভবত কোনওটিই বোধ করা উচিত নয়। আমি কেবল এটি উল্লেখ করেছি কারণ আমি যখন জানতে পেরেছিলাম যে ডিএসএলগুলি কেন একটি ভাল নকশা learned কিছু ডিএসএল এমনকি ডেমিটারের আসল আইন লঙ্ঘন করে না বলে এতদূর যায়।

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

কঠিন নীতির বড় বেশী আমি অনুসরণ করার চেষ্টা হয়। এখানে দু'জনকে সম্মানিত করা হ'ল একক দায়িত্ব এবং নির্ভরতা বিপরীতমুখী মূলনীতি। এই দু'টিকে সম্মান করা এবং এখনও ডেমিটারের আইন লঙ্ঘন করা সত্যই কঠিন।

ডেমিটার লঙ্ঘন করার মানসিকতা হ'ল বুফে রেস্তোরাঁয় খাওয়ার মতো যেখানে আপনি যা খুশি তাই ধরুন। সামান্য কাজ করার সাথে আপনি নিজেকে একটি মেনু এবং এমন একটি সার্ভার সরবরাহ করতে পারেন যা আপনার পছন্দসই কিছু আনবে। ফিরে বসুন, শিথিল করুন, এবং ভাল টিপস।


2
"এটি আপনাকে বলে যে কেবলমাত্র আপনার" বন্ধুদের "সাথে কথা বলা ভাল," বন্ধুদের বন্ধু "এর সাথে নয়" ++
রাবারডাক

1
দ্বিতীয় অনুচ্ছেদ, এটি কোথাও থেকে চুরি হয়েছে, বা আপনি এটি তৈরি করেছেন? এটি আমাকে পুরোপুরি ধারণাটি বুঝতে পেরেছিল । এটি "বন্ধুদের বন্ধুবান্ধব" কী এবং খুব বেশি ক্লাস (জয়েন্টগুলি) জড়িয়ে যাওয়ার ক্ষেত্রে কী কী ত্রুটি রয়েছে তা স্পষ্ট করে তোলে। এ + উক্তি
মর মাউস

2
@ ডিমাউস যদি আমি কোথাও থেকে shাল অনুচ্ছেদটি চুরি করি তবে এর উত্সটি আমার মাথা থেকে বেরিয়ে এসেছে। এ সময় আমার মস্তিষ্ক কেবল ভেবেছিল এটি চালাক। আমার যা মনে আছে তা হ'ল আমি এটিকে অনেকগুলি উত্সাহের পরে যুক্ত করেছি তাই এটির বৈধতা দেখে ভাল লাগল। এটা খুশী হয়েছে।
candied_orange

19

কার্যনির্বাহী নকশা কি বস্তু-ভিত্তিক নকশার চেয়ে ভাল? এটা নির্ভর করে.

এমভিভিএম কি এমভিসির চেয়ে ভাল? এটা নির্ভর করে.

আমোস অ্যান্ডি বা মার্টিন এবং লুইস? এটা নির্ভর করে.

এটি কিসের উপর নির্ভর করে? আপনি যে পছন্দগুলি করেন তার উপর নির্ভর করে প্রতিটি কৌশল বা প্রযুক্তি আপনার সফ্টওয়্যারটির কার্যকরী এবং অ-কার্যকরী প্রয়োজনীয়তাগুলি কীভাবে পূরণ করে, আপনার নকশা, কর্মক্ষমতা এবং রক্ষণাবেক্ষণের লক্ষ্যগুলি পর্যাপ্তভাবে সন্তুষ্ট করার সময়।

[কিছু বই] বলেছে যে [কিছু জিনিস] ভুল।

আপনি যখন এটি কোনও বই বা ব্লগে পড়েন, দাবিটির যোগ্যতার ভিত্তিতে মূল্যায়ন করুন; যে, কেন জিজ্ঞাসা করুন। সফ্টওয়্যার বিকাশে কোনও সঠিক বা ভুল কৌশল নেই, কেবলমাত্র "এই কৌশলটি আমার লক্ষ্যগুলি কতটা ভালভাবে পূরণ করে? এটি কার্যকর বা অকার্যকর? এটি কী একটি সমস্যার সমাধান করে তবে একটি নতুন সমাধান তৈরি করে? এটি কী পুরোটি দ্বারা ভালভাবে বোঝা যায়? উন্নয়ন দল, নাকি এটি খুব অস্পষ্ট? "

এই বিশেষ ক্ষেত্রে - অন্য পদ্ধতির দ্বারা প্রত্যাবর্তিত কোনও জিনিসে কোনও পদ্ধতি কল করার কাজ - যেহেতু প্রকৃত নকশার প্যাটার্ন রয়েছে যা এই অনুশীলনকে (কারখানার) মঞ্জুরি দেয়, সুতরাং এটি ধারণা করা কঠিন যে কেউ কীভাবে দৃ as়ভাবে এই দাবিটি তৈরি করতে পারে? ভুল।

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


2

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

অবজেক্টের শ্রেণিবিন্যাসকে দ্বিগুণ করার বিকল্প উপায় রয়েছে:

প্রকাশ 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এই তিনটি পরিস্থিতির মধ্যে আপনার প্রয়োজনগুলি পরিবর্তিত হয় তা বিবেচ্য নয়: এপিআই একই থাকে।


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

@ পেরিটাব্রেট্টা - আমি অবশ্যই এর সাথে একমত হতে পারি না এবং করতে পারি না। তবে আমি একটি বিষয় উল্লেখ করতে চাই: সংজ্ঞা অনুসারে একটি ইন্টারফেস , দুটি শ্রেণীর সীমানায় যা জানা দরকার তা উপস্থাপন করে । যদি এটি "পরিবর্তিত হওয়া দরকার", তবে এটি মৌলিক - কোনও বিকল্প পদ্ধতির কোনওভাবে যাদুতে প্রয়োজনীয় কোডিংটি এড়ানো যেত না। আমি বর্ণিত তিনটি পরিস্থিতির মধ্যে যে কোনও একটি করেই তার বৈসাদৃশ্য করুন, তবে ইন্টারফেসটি ব্যবহার না করে- পরিবর্তে একটি কংক্রিট ক্লাস ফিরিয়ে দিন। 1-এ ফ্রেম, 2-এ, এনকোডার ফ্রেমওয়্যার্পার, 3-এ, এনকোডার। আপনি নিজেকে এই পদ্ধতির মধ্যে লক করুন । ইন্টারফেসটি তাদের সকলের সাথে খাপ খাইয়ে নিতে পারে।
টুলমেকারস্টেভ

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

@ পেরিটাব্রেট্টা - এবং যখন আমি বলি "ইন্টারফেসটি তাদের সকলের সাথে খাপ খাইয়ে নিতে পারে", আমি "আহহহ" বলছি না, এই এক ভাষার বৈশিষ্ট্যটি এই বিভিন্ন কেসকে আবরণ করতে পারে এটি দুর্দান্ত। আমি বলছি যে সংজ্ঞায়িত ইন্টারফেসগুলি আপনার করা পরিবর্তনগুলি হ্রাস করতে পারে। সর্বোত্তম ক্ষেত্রে, নকশাটি সহজতম কেস (সমাধান 1) থেকে সব থেকে জটিল ক্ষেত্রে (সমাধান 3) সমস্ত উপায় পরিবর্তন করতে পারে, ইন্টারফেসটি একেবারে পরিবর্তিত না করে - কেবল নির্মাতার অভ্যন্তরীণ চাহিদা আরও জটিল হয়ে উঠেছে। এমনকি যখন পরিবর্তনের প্রয়োজন হয় তখনও তারা কম বিস্তৃত হয়, আইএমএইচও।
টুলমেকারস্টেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.