কেবলমাত্র নির্মাণকারী সাবক্লাসগুলি: এটি কি একটি বিরোধী-নিদর্শন?


37

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

আমার স্বজ্ঞাতাকে আরও দৃ concrete়তার সাথে বলতে গেলে, আমি মনে করি যে আমার কাছে যদি এমন একটি সাবক্লাস থাকে যা পিতামাত্ত শ্রেণীর প্রসারিত করে তবে সাবক্লাসকে ওভাররাইড করা একমাত্র কোডটি কনস্ট্রাক্টর (হ্যাঁ, আমি জানি কনস্ট্রাক্টররা সাধারণত "ওভাররাইড" করেন না, আমার সাথে সহ্য করেন) তবে আসলে যা দরকার ছিল তা হেল্পার পদ্ধতি ছিল।

উদাহরণস্বরূপ, এটিকে কিছুটা বাস্তব জীবনের শ্রেণী বিবেচনা করুন:

public class DataHelperBuilder
{
    public string DatabaseEngine { get; set; }
    public string ConnectionString { get; set; }

    public DataHelperBuilder(string databaseEngine, string connectionString)
    {
        DatabaseEngine = databaseEngine;
        ConnectionString = connectionString;
    }

    // Other optional "DataHelper" configuration settings omitted

    public DataHelper CreateDataHelper()
    {
        Type dataHelperType = DatabaseEngineTypeHelper.GetType(DatabaseEngine);
        DataHelper dh = (DataHelper)Activator.CreateInstance(dataHelperType);
        dh.SetConnectionString(ConnectionString);

        // Omitted some code that applies decorators to the returned object
        // based on omitted configuration settings

        return dh;
    }
}

তাঁর দাবি এটি এই যে একটি সাবক্লাস রাখা সম্পূর্ণরূপে উপযুক্ত হবে:

public class SystemDataHelperBuilder
{
    public SystemDataHelperBuilder()
        : base(Configuration.GetSystemDatabaseEngine(),
               Configuration.GetSystemConnectionString())
    {
    }
 }

সুতরাং, প্রশ্ন:

  1. এমন লোকদের মধ্যে যারা নকশার ধরণ সম্পর্কে কথা বলেন, এর মধ্যে কোনটি স্বজ্ঞাত সঠিক? বিরোধী-নিদর্শন উপরে বর্ণিত হিসাবে সাবক্লাসিং করা?
  2. যদি এটি একটি অ্যান্টি-প্যাটার্ন হয় তবে এর নাম কী?

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


2
আমি একটি নাম "সহায়ক" শব্দটিকে অ্যান্টিপ্যাটার্ন হিসাবে বিবেচনা করি। এটি কোনও জিনিস এবং কোনও কিছুর নিয়মিত উল্লেখ সহ একটি প্রবন্ধ পড়ার মতো। এটা কি বলুন হয় । এটা কি কারখানা? রচয়িতা? আমার কাছে এটি অলস চিন্তার প্রক্রিয়াটির মুখোমুখি হয় এবং এটি একক দায়িত্বের নীতির লঙ্ঘনকে উত্সাহ দেয়, কারণ একটি সঠিক শব্দার্থিক নাম এটি পরিচালনা করবে। আমি অন্যান্য ভোটারদের সাথে একমত, এবং আপনার @ lxrec এর উত্তর গ্রহণ করা উচিত। কারখানার পদ্ধতির জন্য একটি সাবক্লাস তৈরি করা সম্পূর্ণ অর্থহীন, যদি না আপনি ডকুমেন্টেশনে বর্ণিত সঠিক যুক্তিগুলি পাস করার জন্য ব্যবহারকারীদের বিশ্বাস করতে না পারেন। যে ক্ষেত্রে, নতুন ব্যবহারকারীদের পান।
অ্যারন হল

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

1
না, আপনি যে উত্তরটি সবচেয়ে মূল্যবান বলে মনে করেন তা গ্রহণ করা আপনার পক্ষে প্রত্যাশিত। সম্প্রদায়টি এখন পর্যন্ত যাকে সবচেয়ে মূল্যবান বলে মনে করে তা হ'ল Ixrec's এর দ্বারা 3 থেকে 1 টিরও বেশি বেশি। সুতরাং তারা আপনাকে এটি গ্রহণ করার প্রত্যাশা করবে। এই সম্প্রদায়টিতে, একজন প্রশ্নকারীর ভুল উত্তর মেনে নেওয়ার ক্ষেত্রে খুব হতাশা প্রকাশ করা হয়েছে, তবে প্রশ্নকারীদের মধ্যে এমন হতাশার প্রকাশ রয়েছে যা কখনই কোনও উত্তর গ্রহণ করে না। নোট করুন যে এখানে গৃহীত উত্তর সম্পর্কে কেউ অভিযোগ করছেন না, পরিবর্তে তারা ভোটদান সম্পর্কে অভিযোগ করেছেন, যা নিজেরাই সঠিক বলে মনে হচ্ছে: stackoverflow.com/q/2052390/541136
অ্যারন হল

খুব ভাল, আমি এটি গ্রহণ করব। আমাকে এখানে সম্প্রদায়ের মান সম্পর্কে শিক্ষিত করতে সময় দেওয়ার জন্য আপনাকে ধন্যবাদ।
হার্ডলিঙ্কনিম

উত্তর:


54

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

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


2
কারখানার পদ্ধতিগুলি আপনাকে আপনার কোডবেসে কিছু নির্দিষ্ট আচরণ (যুক্তি দ্বারা পরিচালিত) প্রয়োগ করতে দেয় না। এবং কখনও কখনও এই শ্রেণি / পদ্ধতি / ক্ষেত্রটি SystemDataHelperBuilderবিশেষভাবে গ্রহণ করে তা স্পষ্টভাবে বর্ণনা করতে কার্যকর হয় ।
টেলাস্টিন

3
আহ, বর্গ বনাম আয়তক্ষেত্র যুক্তি ঠিক আমি যা খুঁজছিলাম তা ছিল, আমার মনে হয়। ধন্যবাদ!
হার্ডলিঙ্কুয়েম

7
অবশ্যই, বর্গক্ষেত্রের আয়তক্ষেত্রের একটি সাবক্লাস হওয়া যদি তারা পরিবর্তনযোগ্য না হয় তবে ঠিক হতে পারে। আপনাকে সত্যিই এলএসপির দিকে নজর দিতে হবে।
ডেভিড কনরাড

10
বর্গ / আয়তক্ষেত্র "সমস্যা" সম্পর্কিত জিনিস হ'ল জ্যামিতিক আকারগুলি স্থায়ী নয়। আয়তক্ষেত্রটি বোঝার জন্য যেখানেই আপনি সর্বদা একটি বর্গ ব্যবহার করতে পারেন তবে আকার পরিবর্তনটি স্কোয়ার বা আয়তক্ষেত্রের কিছু নয়।
ডোভাল

3
@ এনহা এলএসপি = লিসকোভ সাবস্টিটিউশন নীতি
Ixrec

16

এই অন্তর্দৃষ্টি কোনটি সঠিক?

আপনার সহকর্মী সঠিক (মানক প্রকারের সিস্টেমগুলি ধরে নিচ্ছেন)।

এটি সম্পর্কে চিন্তা করুন, ক্লাসগুলি সম্ভাব্য আইনী মূল্যবোধ উপস্থাপন করে। শ্রেণিতে যদি Aএকটি বাইট ক্ষেত্র থাকে তবে Fআপনার মনে হতে পারে যে A256 আইনী মান রয়েছে তবে অন্তর্দৃষ্টিটি ভুল। A"মানগুলির প্রতিটি ক্রমবর্ধমানকে" কখনও সীমাবদ্ধ করে "" ক্ষেত্রটি F0-255 হতে হবে "।

আপনি প্রসারিত তাহলে Aসঙ্গে Bযা অন্য বাইট ক্ষেত্র রয়েছে FF, যে বিধিনিষেধ যোগ । "মান যেখানে Fবাইট হয়" এর পরিবর্তে আপনার কাছে " Fবাইট যেখানে রয়েছে তার মান FFএবং বাইটও রয়েছে"। যেহেতু আপনি পুরানো বিধিগুলি পালন করছেন, বেসটাইপের জন্য কাজ করা সমস্ত কিছুই এখনও আপনার সাব টাইপের জন্য কাজ করে। তবে আপনি যেহেতু নিয়ম যুক্ত করছেন তাই আপনি "কিছু হতে পারে" থেকে দূরে থাকছেন izing

বা এটিকে অন্যভাবে ভাবার জন্য Aধরুন B, এর মধ্যে একগুচ্ছ উপপ্রকার রয়েছে: C,, এবং D। প্রকারের একটি ভেরিয়েবল Aএই সাব- টাইপের যে কোনও হতে পারে, তবে ধরণের ভেরিয়েবল Bআরও নির্দিষ্ট specific এটি (বেশিরভাগ টাইপ সিস্টেমে) একটি Cবা এ হতে পারে না D

এটি কি একটি বিরোধী নিদর্শন?

Enh? বিশেষায়িত বস্তু থাকা কার্যকর এবং কোডের জন্য স্পষ্টত ক্ষতিকারক নয়। সাব টাইপিং ব্যবহার করে ফলাফলটি অর্জন করা সম্ভবত কিছুটা প্রশ্নবিদ্ধ, তবে আপনার কাছে কী কী সরঞ্জাম রয়েছে তা নির্ভর করে। এমনকি উন্নত সরঞ্জামগুলির সাথেও এই বাস্তবায়নটি সহজ, সরল ও দৃ .়।

আমি এটিকে একটি বিরোধী-প্যাটার্ন হিসাবে বিবেচনা করব না কারণ এটি কোনও পরিস্থিতিতে পরিষ্কার এবং ভুল এবং খারাপ নয়।


5
"আরও বিধিগুলির অর্থ কম সম্ভাব্য মান, যার অর্থ আরও সুনির্দিষ্ট।" আমি সত্যিই এই অনুসরণ না। টাইপ byte and byteস্পষ্টভাবে শুধু টাইপ চেয়ে আরো মান আছে byte; 256 বার হিসাবে অনেক। এটিকে বাদ দিয়ে, আমি মনে করি না যে আপনি সংখ্যক উপাদানের (বা আপনি সঠিক হতে চাইলে কার্ডিনালিটি) বিধি বিধান করতে পারেন। আপনি অসীম সেট বিবেচনা করলে এটি ভেঙে যায়। পূর্ণসংখ্যা যেমন রয়েছে তেমন অনেকগুলি সংখ্যা রয়েছে, তবে যে সংখ্যাটি সমান, তা জেনে রাখা এখনও একটি সীমাবদ্ধতা / কেবলমাত্র এটি একটি পূর্ণসংখ্যার জেনার চেয়ে আমাকে আরও তথ্য দেয়! প্রাকৃতিক সংখ্যার জন্য একই কথা বলা যেতে পারে।
ডোভাল

6
@ টেলাস্টিন আমরা অফ-টপিক পাচ্ছি, তবে এটি প্রমাণযোগ্য যে এমনকি পূর্ণসংখ্যার সেটের কার্ডিনালিটি (আলগাভাবে "আকার") সমস্ত সংখ্যার সেট এমনকি সমস্ত যৌক্তিক সংখ্যার সমান। এটা সত্যিই দুর্দান্ত জিনিস। Math.grinnell.edu/~miletijo/museum/infinite.html
হার্ডলিঙ্কনিম

2
সেট থিয়োরিটি বেশ অনিচ্ছুক। আপনি পূর্ণসংখ্যার এবং সন্নিবেশগুলিকে এক-এক-এক চিঠিপত্রের মধ্যে রাখতে পারেন (উদাহরণস্বরূপ ফাংশনটি ব্যবহার করে n -> 2n)। এটি সর্বদা সম্ভব নয়; আপনি বাস্তবগুলির সাথে পূর্ণসংখ্যার মানচিত্র তৈরি করতে পারবেন না, সুতরাং বাস্তবগুলির সেটটি পূর্ণসংখ্যার চেয়ে "বড়"। তবে আপনি (বাস্তব) ব্যবধানটি [0, 1] কে সমস্ত বাস্তবের সেটে মানচিত্র করতে পারেন, যাতে এটি তাদের একই "আকার" করে তোলে। সাবসেটগুলি "প্রতিটি উপাদানও Aএকটি উপাদান হিসাবে নির্ধারিত হয়" Bঅবিকল কারণ আপনার সেটগুলি অসীম হয়ে উঠলে, এটি একই কার্ডিনালিটি হয়ে গেলেও বিভিন্ন উপাদান থাকতে পারে।
ডোভাল

1
হাতে থাকা বিষয়ের সাথে আরও সম্পর্কিত, আপনি যে উদাহরণটি দিয়েছেন তা হ'ল একটি প্রতিবন্ধকতা যা অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ের ক্ষেত্রে, একটি অতিরিক্ত ক্ষেত্রের ক্ষেত্রে প্রকৃতপক্ষে - কার্যকারিতা বাড়িয়ে তোলে। আমি এমন সাবক্লাসের কথা বলছি যা কার্যকারিতা বাড়ায় না - যেমন বৃত্ত-উপবৃত্ত সমস্যা।
হার্ডলিঙ্কুয়েম

1
@ ডোভাল: "কম" এর একাধিক সম্ভাব্য অর্থ রয়েছে - অর্থাত্ সেটগুলিতে একাধিক অর্ডারের সম্পর্ক। "সম্পর্কের একটি উপসেট" সেটগুলিতে সুসংজ্ঞাযুক্ত (আংশিক) অর্ডার দেয়। তদুপরি, "আরও বিধিগুলি" বোঝাতে "সেটটির সমস্ত উপাদান আরও বেশি (যেমন একটি সুপারসেট) প্রস্তাবগুলি পূরণ করে (একটি নির্দিষ্ট সেট থেকে)" বোঝাতে পারে। এই সংজ্ঞা সহ, "আরও নিয়ম" এর অর্থ "কম মান"। এটি, মোটামুটিভাবে বলতে গেলে কম্পিউটার প্রোগ্রামগুলির বেশ কয়েকটি অর্থগত মডেল, যেমন স্কট ডোমেনগুলি গ্রহণ করেছে।
স্মারক

12

না, এটি কোনও অ্যান্টি-প্যাটার্ন নয়। আমি এর জন্য ব্যবহারিক ব্যবহারের বেশ কয়েকটি ক্ষেত্রে ভাবতে পারি:

  1. আপনি যদি কম্পাইল টাইম চেকিং ব্যবহার করতে চান তবে নিশ্চিত হয়ে নিন যে অবজেক্টগুলির সংগ্রহ কেবল একটি নির্দিষ্ট সাবক্লাসের সাথে সঙ্গতিপূর্ণ। উদাহরণস্বরূপ, যদি আপনার সিস্টেমে থাকে MySQLDaoএবং SqliteDaoতবে কোনও কারণে আপনি নিশ্চিত করতে চান যে কোনও সংকলনে কেবলমাত্র একটি উত্স থেকে ডেটা রয়েছে, আপনি যদি বর্ণনা হিসাবে সাবক্ল্যাস ব্যবহার করেন তবে আপনার এই সংযোজকটি এই নির্দিষ্ট সঠিকতা যাচাই করতে পারবেন। অন্যদিকে, আপনি যদি ডেটা উত্সটিকে ক্ষেত্র হিসাবে সঞ্চয় করেন তবে এটি রান-টাইম চেক হয়ে যাবে।
  2. আমার বর্তমান অ্যাপ্লিকেশনটির AlgorithmConfiguration+ ProductClassএবং এর মধ্যে একটির মধ্যে একটির সম্পর্ক রয়েছে AlgorithmInstance। অন্য কথায়, যদি আপনাকে কনফিগার FooAlgorithmজন্য ProductClassবৈশিষ্ট্যাবলী ফাইলে, আপনি শুধুমাত্র একটি পেতে পারেন FooAlgorithmসেই পণ্যের বর্গ জন্য। FooAlgorithmপ্রদত্ত দুটির জন্য একমাত্র উপায় ProductClassএকটি সাবক্লাস তৈরি করা FooBarAlgorithm। এটি ঠিক আছে, কারণ এটি বৈশিষ্ট্য ফাইলটি ব্যবহার করা সহজ করে তোলে (বৈশিষ্ট্যগুলির ফাইলের একটি বিভাগে বিভিন্ন আলাদা কনফিগারেশনের জন্য সিনট্যাক্সের প্রয়োজন নেই) এবং প্রদত্ত পণ্য শ্রেণীর জন্য একাধিক উদাহরণ থাকবে এটি খুব বিরল।
  3. @ টেলাস্টিনের উত্তরটি আরও একটি ভাল উদাহরণ দেয়।

নীচের লাইন: এটি করার আসলে কোনও ক্ষতি নেই। একটি অ্যান্টি-প্যাটার্নটিকে সংজ্ঞায়িত করা হয়:

একটি অ্যান্টি-প্যাটার্ন (বা অ্যান্টিপ্যাটার্ন) একটি পুনরাবৃত্তি সমস্যাটির একটি সাধারণ প্রতিক্রিয়া যা সাধারণত অকার্যকর এবং উচ্চ ঝুঁকির কারণে ঝুঁকি থাকে।

এখানে অত্যন্ত পাল্টা উত্পাদক হওয়ার ঝুঁকি নেই, তাই এটি কোনও বিরোধী-নিদর্শন নয়।


2
হ্যাঁ, আমি মনে করি যদি আমাকে আবার প্রশ্নটির বাক্যাংশটি লিখতে হয় তবে আমি "কোড গন্ধ" বলতাম। যুব বিকাশকারীদের পরবর্তী প্রজন্মকে এড়ানোর জন্য সতর্কবার্তা দেওয়ার পক্ষে এটি যথেষ্ট খারাপ নয়, তবে এটি এমন কিছু যা আপনি যদি এটি দেখেন তবে এটি ইঙ্গিত করতে পারে যে অতিরিক্ত নকশায় সমস্যা রয়েছে তবে শেষ পর্যন্ত সঠিকও হতে পারে।
হার্ডলিঙ্কুয়েম

পয়েন্ট 1 সঠিক লক্ষ্য। আমি 2 পয়েন্টটি সত্যই বুঝতে পারি নি তবে আমি নিশ্চিত যে এটি ঠিক ততটাই ভাল ... :)
ফিল

9

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

আমি আপনাকে কিছু কোডের একটি গল্প বলি যা আমি অনেক আগে লিখেছিলাম ...

এটি এলপিসি নামক একটি ভাষায় ছিল এবং একটি গেমটিতে মন্ত্র কাস্ট করার জন্য একটি কাঠামো প্রয়োগ করে। আপনার কাছে একটি স্পেল সুপারক্লাস ছিল, যার একটি যুদ্ধক্ষেত্রের একটি সাবক্লাস ছিল যা কিছু চেক পরিচালনা করেছিল এবং তারপরে একক লক্ষ্য প্রত্যক্ষ ক্ষতির মন্ত্রগুলির জন্য একটি সাবক্লাস ছিল, যা তখন পৃথক স্পেলগুলিতে সাবস্ক্লাস করা হয়েছিল - যাদু মিসাইল, বজ্রপাত এবং এর মতো।

এলপিসি কীভাবে কাজ করেছিল তার প্রকৃতিটি হ'ল আপনার একটি মাস্টার অবজেক্ট ছিল যা সিঙ্গলটন। আপনি 'ইও সিঙ্গেলটন' যাওয়ার আগে - এটি ছিল এবং এটি মোটেও "ইওউ" ছিল না। কেউ বানানের অনুলিপি তৈরি করেনি, বরং মন্ত্রগুলিতে (কার্যকরভাবে) স্থির পদ্ধতিগুলি আহ্বান করেছিল। ম্যাজিক ক্ষেপণাস্ত্রের কোডটি দেখে মনে হয়েছিল:

inherit "spells/direct";

void init() {
  ::init();
  damage = 10;
  cost = 3;
  delay = 1.0;
  caster_message = "You cast a magic missile at ${target}";
  target_message = "You are hit with a magic missile cast by ${caster}";
}

এবং আপনি দেখতে পাচ্ছেন? এটি একটি নির্মাণকারী একমাত্র ক্লাস। এটি এমন কিছু মান সেট করেছে যা তার পিতামাতার বিমূর্ত শ্রেণিতে ছিল (না, এটি সেটারগুলি ব্যবহার করা উচিত নয় - এটি একটি অপরিবর্তনীয়) এবং এটি ছিল। এটা ঠিক কাজ করে । এটি কোড করা সহজ, প্রসারিত সহজ এবং বোধগম্য ছিল।

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

এটি কোনও খারাপ জিনিস নয় এবং এটি অবশ্যই কোনও অ্যান্টি-প্যাটার্ন নয় (এবং কিছু ভাষায় এটি নিজেই একটি প্যাটার্নও হতে পারে)।


2

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

আমরা এটি করি কারণ ব্যতিক্রমগুলি তাদের ধরণের পরীক্ষা করে ধরা পড়ে। সুতরাং, আমাদের ধরণটির বিশেষায়িতকরণটি এনকোড করা দরকার যাতে কেউ কেবল ReadErrorসমস্ত না ধরেই ধরতে পারে IOError, তারা চাইলে।

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

এটি এখনও কার্যকর হতে পারে, উদাহরণস্বরূপ যদি এই ধরণের নামটি অবজেক্টের লগ করা স্ট্রিং ফর্মটিতে উপস্থিত হয়: এটি ভাষা এবং সম্ভবত ফ্রেমওয়ার্ক নির্দিষ্ট। আপনি নীতিগতভাবে ক্লাসে একটি পদ্ধতি একটি কল, যে ক্ষেত্রে আমরা তেমন কোন ব্যবস্থা চালু টাইপ নাম প্রতিস্থাপন করতে পারে হবে ওভাররাইড মাত্র কন্সট্রাকটর চেয়ে বেশি SystemDataHelperBuilder, আমরা ওভাররাইড চাই loggingname()। সুতরাং আপনার সিস্টেমে যদি এরকম কোনও লগইন থাকে তবে আপনি কল্পনা করতে পারেন যে যদিও আপনার শ্রেণিটি আক্ষরিকভাবে কেবল নির্মাণকারীকেই অগ্রাহ্য করে, "নৈতিকভাবে" এটি শ্রেণীর নামটিকেও ওভাররাইড করে, এবং তাই ব্যবহারিক উদ্দেশ্যে এটি কেবল নির্মাণকারী-কেবল সাবক্লাস নয়। এর পছন্দসই ভিন্ন আচরণ রয়েছে, এটি '

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

যাইহোক, বিশেষ ক্ষেত্রে জন্য ধরনের ব্যবহার করে, কিছু বিভ্রান্তি হতে যেহেতু যদি না ImmutableRectangle(1,1)এবং ImmutableSquare(1)ভিন্নভাবে আচরণ কোন ভাবেই তারপর অবশেষে কেউ আশ্চর্য যাচ্ছে কেন এবং সম্ভবত ইচ্ছা হয়নি। ব্যতিক্রম শ্রেণিবিন্যাসের বিপরীতে, আপনি পরীক্ষা করে পরীক্ষা করে একটি আয়তক্ষেত্রটি বর্গক্ষেত্র কিনা height == width, তা পরীক্ষা করে দেখুন instanceof। আপনার উদাহরণে, ঠিক একই যুক্তি দিয়ে তৈরি করা একটি SystemDataHelperBuilderএবং এর মধ্যে পার্থক্য রয়েছে DataHelperBuilderএবং এতে সমস্যা হওয়ার সম্ভাবনা রয়েছে। সুতরাং, "ডান" টি যুক্তি দিয়ে তৈরি করা কোনও বস্তুর ফিরিয়ে ফাংশনটি আমার কাছে সাধারণত সঠিক জিনিস বলে মনে হয়: সাবক্লাসটি "একই" জিনিসটির দুটি পৃথক উপস্থাপনার ফলস্বরূপ এবং এটি কেবল তখনই সহায়তা করে যদি আপনি কিছু করছেন if সাধারণত না করার চেষ্টা করবে।

মনে রাখবেন যে আমি নকশার নিদর্শন এবং অ্যান্টি-নিদর্শনগুলির ক্ষেত্রে কথা বলছি না , কারণ আমি বিশ্বাস করি না যে কোনও প্রোগ্রামার কখনও ভেবে দেখেছেন এমন ভাল এবং খারাপ ধারণাগুলির একটি শ্রেণীবদ্ধ প্রদান সম্ভব। সুতরাং, প্রতিটি ধারণা একটি নিদর্শন বা অ্যান্টি-প্যাটার্ন নয়, এটি কেবল তখনই ঘটে যখন কেউ সনাক্ত করে যে এটি বিভিন্ন প্রসঙ্গে বারবার ঘটে এবং এর নাম দেয় ;-) আমি এই ধরণের সাবক্লাসিংয়ের জন্য কোনও বিশেষ নাম সম্পর্কে অবগত নই।


আমি এর জন্য ব্যবহারগুলি দেখতে পেতাম ImmutableSquareMatrix:ImmutableMatrix, তবে যদি সম্ভব হয় তবে ImmutableMatrixএর বিষয়বস্তুটিকে ImmutableSquareMatrixযদি একটি রেন্ডার করতে বলার দক্ষ উপায় ছিল । এমনকি যদি ImmutableSquareMatrixমূলত এমন একজনও ছিলেন ImmutableMatrixযার নির্মাণকারীর সেই উচ্চতা এবং প্রস্থের ম্যাচ প্রয়োজন ছিল এবং যার AsSquareMatrixপদ্ধতিটি কেবল নিজেরাই ফিরে আসবে (উদাহরণস্বরূপ ImmutableSquareMatrixএকই ব্যাকিং অ্যারেটি আবৃত করে এমন একটি নির্মাণ করা) তবে এই জাতীয় নকশার জন্য স্কয়ারের প্রয়োজনীয় পদ্ধতিগুলির জন্য কমপাইল-টাইম প্যারামিটার বৈধতা মঞ্জুর করা হত ম্যাট্রিক্স
সুপারক্যাট

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

... সুতরাং আমি অনুমান করি যে আমি যা বলেছিলাম তা পুরোপুরি সত্য নয় , "আপনি পরীক্ষা করে একটি আয়তক্ষেত্রটি বর্গক্ষেত্র কিনা height == width, তা পরীক্ষা করে পরীক্ষা করে দেখুন না instanceof"। আপনি স্ট্যাটিকালি দৃ as়ভাবে কিছু বলতে পছন্দ করতে পারেন।
স্টিভ জেসোপ

আমি আশা করি এমন একটি ব্যবস্থা ছিল যা কনস্ট্রাক্টর সিনট্যাক্সের মতো কোনও কিছুর স্থিতিশীল কারখানার পদ্ধতি চালু করার অনুমতি দেয়। মত প্রকাশের foo=new ImmutableMatrix(someReadableMatrix)ধরণটি someReadableMatrix.AsImmutable()এমনকি বা এমনকি এর চেয়ে পরিষ্কার ImmutableMatrix.Create(someReadableMatrix), তবে পরবর্তী রূপগুলি প্রাক্তন অভাবের জন্য দরকারী শব্দার্থক সম্ভাবনাগুলি সরবরাহ করে; যদি কনস্ট্রাক্টর বলতে পারেন যে ম্যাট্রিক্সটি বর্গক্ষেত্রের, তার ধরণের প্রতিবিম্ব রয়েছে যা একটি নতুন অবজেক্ট উদাহরণ তৈরির জন্য একটি বর্গ ম্যাট্রিক্সের প্রয়োজন বর্ধিত কোড ডাউন স্ট্রিম প্রয়োজনের চেয়ে পরিষ্কার হতে পারে।
সুপারক্যাট

@ সুপের্যাট: পাইথন সম্পর্কে একটি ছোট জিনিস যা আমি পছন্দ করি তা হ'ল newঅপারেটরের অনুপস্থিতি । একটি শ্রেণি কেবল কলযোগ্য, যখন যখন এটি ডেকে আনা হয় (ডিফল্টরূপে) নিজেই একটি ঘটনা ফিরে আসে। সুতরাং আপনি যদি ইন্টারফেসের ধারাবাহিকতা সংরক্ষণ করতে চান তবে কারখানার ফাংশনটি লিখতে পুরোপুরি সম্ভব যার নাম মূলধন দিয়ে শুরু হয়, সুতরাং এটি দেখতে কেবল কনস্ট্রাক্টর কলের মতো দেখাচ্ছে। আমি ফ্যাক্টরি ফাংশন দিয়ে এটি নিয়মিত করি না এমন নয়, তবে আপনার যখন প্রয়োজন হবে তখন এটি সেখানে।
স্টিভ জেসপ

2

সাবক্লাস সম্পর্কের সবচেয়ে কঠোর অবজেক্ট ওরিয়েন্টেড সংজ্ঞাটি «ইজ-এ» হিসাবে পরিচিত » বর্গক্ষেত্র এবং একটি আয়তক্ষেত্রের theতিহ্যগত উদাহরণ ব্যবহার করে একটি বর্গক্ষেত্র «হয়-একটি ct আয়তক্ষেত্র।

এটির দ্বারা আপনার যে কোনও পরিস্থিতিতে আপনার কোডের জন্য একটি অর্থপূর্ণ সম্পর্ক মনে হয় এমন কোনও পরিস্থিতির জন্য আপনার সাবক্লাসিং ব্যবহার করা উচিত।

আপনার নির্মাণকারক ব্যতীত সাবক্লাসের নির্দিষ্ট ক্ষেত্রে, আপনার এটি একটি «ইস-এ» দৃষ্টিকোণ থেকে বিশ্লেষণ করা উচিত। এটি স্পষ্ট যে একটি সিস্টেমডাটাহেলপারবিল্ডার a একটি-একটি »ডেটাহেল্পবিল্ডার, তাই প্রথম পাসটি এটি একটি বৈধ ব্যবহার বলে প্রস্তাব করে।

আপনার যে প্রশ্নের উত্তর দেওয়া উচিত তা হ'ল অন্য কোডগুলির মধ্যে কোনওটি এই «-এ-এ» সম্পর্ককে উপস্থাপন করে কিনা। অন্য কোনও কোড কি সিস্টেমডাটাহেলপারবিল্ডারদের ডেটাহেলপারবিল্ডারগুলির সাধারণ জনসংখ্যার থেকে আলাদা করার চেষ্টা করে? যদি তা হয় তবে সম্পর্কটি বেশ যুক্তিসঙ্গত, এবং আপনার সাবক্লাসটি রাখা উচিত।

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


1

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

এটি প্রদত্ত, আপনার তৈরি সাবক্লাসগুলি সম্ভবত ভুল নয় (যেহেতু তারা ঠিক কী করে তা আমি জানি না, তাই আমি নিশ্চিতভাবে বলতে পারি না)) ভঙ্গুর বেস শ্রেণীর সমস্যা থেকে আপনাকে সতর্ক হওয়া দরকার এবং আপনাকেও করতে হবে interfaceকোনও আপনার উপকারে আসবে কিনা তা বিবেচনা করুন , কিন্তু উত্তরাধিকারের সমস্ত ব্যবহারের ক্ষেত্রে এটি সত্য।


1

আমি মনে করি এই প্রশ্নের উত্তরের মূল চাবিকাঠিটি এটির বিশেষ ব্যবহারের দৃশ্যের দিকে নজর দেওয়া।

উত্তরাধিকার সংযোগ স্ট্রিংয়ের মতো ডাটাবেস কনফিগারেশন বিকল্পগুলি প্রয়োগ করতে ব্যবহৃত হয়।

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


1

আমি বিভিন্ন ধারণার প্রকাশের জন্য কেবল নিয়মিত কেবল সাবক্ল্যাস ব্যবহার করি।

উদাহরণস্বরূপ, নিম্নলিখিত শ্রেণীর বিবেচনা করুন:

public class Outputter
{
    private readonly IOutputMethod outputMethod;
    private readonly IDataMassager dataMassager;

    public Outputter(IOutputMethod outputMethod, IDataMassager dataMassager)
    {
        this.outputMethod = outputMethod;
        this.dataMassager = dataMassager;
    }

    public MassageDataAndOutput(string data)
    {
        this.outputMethod.Output(this.dataMassager.Massage(data));
    }
}

তারপরে আমরা একটি সাবক্লাস তৈরি করতে পারি:

public class CapitalizeAndPrintOutputter : Outputter
{
    public CapitalizeAndPrintOutputter()
        : base(new PrintOutputMethod(), new Capitalizer())
    {
    }
}

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

এই নিদর্শনটি ব্যবহার করা আসলেই বেশ নমনীয় এবং দরকারী। হ্যাঁ, আপনি একই জিনিসটি করতে কারখানার পদ্ধতি ব্যবহার করতে পারেন তবে তারপরে (কমপক্ষে সি # তে) আপনি টাইপ সিস্টেমের কিছুটা শক্তি হারিয়ে ফেলেন এবং অবশ্যই ডিআই পাত্রে ব্যবহার করা আরও জটিল হয়ে উঠবে।


1

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

সাবক্লাসের একটি উদাহরণ কেবল একটি ডাউনকাস্ট ব্যবহার করে আলাদা করা যায়।

এখন, আপনার যদি এমন কোনও নকশা থাকে যেখানে সাবক্লাস দ্বারা সম্পত্তি DatabaseEngineএবং ConnectionStringবৈশিষ্ট্যগুলি পুনরায় Configurationপ্রয়োগ করা হয়েছিল , যা এটি অ্যাক্সেস করেছে, তারপরে আপনার একটি সীমাবদ্ধতা রয়েছে যা সাবক্লাসটি আরও উপলব্ধি করে।

এই বলে যে, "স্বাদবিরোধী" খুব স্বাদযুক্ত; এখানে আসলে কিছুই ভুল নেই।


0

আপনি যে উদাহরণ দিয়েছেন তাতে আপনার সঙ্গী ঠিক আছে। দুটি ডেটা হেল্পার নির্মাতা কৌশল are একটি অন্যের তুলনায় আরও নির্দিষ্ট, তবে একবারে আরম্ভ হয়ে গেলে তারা উভয়ই বিনিময়যোগ্য।

মূলত ডেটাহেল্পবিল্ডারের কোনও ক্লায়েন্ট যদি সিস্টেমডেটাহেল্পবিল্ডার গ্রহণ করে তবে কিছুই ভাঙবে না। আরেকটি বিকল্প হ'ল ডেটাহেলপারবিল্ডার শ্রেণীর স্ট্যাটিক দৃষ্টান্ত হিসাবে সিস্টেমডেটহেল্পবিল্ডারটি থাকত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.