উচ্চ-বর্ধনযোগ্য ক্লাসে এটি ব্যবহারের জন্য আরও উপযুক্ত করার জন্য কীভাবে ব্লচের বিল্ডার প্যাটার্নটি উন্নত করবেন


34

আমি জোশুয়া ব্লচের কার্যকর জাভা বই (২ য় সংস্করণ) দ্বারা প্রচুরভাবে প্রভাবিত হয়েছি, সম্ভবত আমি যে কোনও প্রোগ্রামিং বই পড়েছি তার চেয়ে বেশি। বিশেষত, তার বিল্ডার প্যাটার্ন (আইটেম 2) সবচেয়ে বেশি প্রভাব ফেলেছে।

ব্লকের নির্মাতা আমার বিগত দশ বছরের প্রোগ্রামিংয়ের তুলনায় কয়েকমাসে আমাকে আরও বেশি দূরে সত্ত্বেও, আমি এখনও নিজেকে একই প্রাচীরের মধ্যে আঘাত করতে দেখছি: স্ব-প্রত্যাবর্তন পদ্ধতি-চেইনগুলির সাথে ক্লাস বাড়ানো সবচেয়ে নিরুত্সাহজনক এবং সবচেয়ে খারাপ একটি স্বপ্নের স্বপ্ন --especially যখন জেনেরিক্স খেলার মধ্যে আসা, এবং বিশেষত সঙ্গে স্ব-উল্লেখ জেনেরিক্স (যেমন Comparable<T extends Comparable<T>>)।

আমার দুটি প্রাথমিক প্রয়োজনীয়তা আছে, কেবলমাত্র দ্বিতীয়টি আমি এই প্রশ্নে ফোকাস করতে চাই:

  1. প্রথম সমস্যাটি হ'ল প্রতিটি ... একক ... শ্রেণিতে পুনরায় প্রয়োগ না করে কীভাবে স্ব-ফেরত পদ্ধতির চেইনগুলি ভাগ করবেন? " যারা কৌতূহলী হতে পারে তাদের জন্য, আমি এই উত্তর-পোস্টের নীচে এই অংশটিকে সম্বোধন করেছি, তবে আমি এখানে ফোকাস করতে চাই তা নয়।

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

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


অ্যাডেন্ডাম
আমার প্রশ্নটি উপরের অংশটি উপর দৃষ্টি নিবদ্ধ করে, তবে আমি কীভাবে এর সাথে মোকাবিলা করেছি তা সহ সমস্যাটি নিয়ে কিছুটা ব্যাখ্যা করতে চেয়েছিলাম:

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

public interface Chainable  {  
    Chainable chainID(boolean b_setStatic, Object o_id);  
    Object getChainID();  
    Object getStaticChainID();  
}
public interface Needable<O,R extends Needer> extends Chainable  {
    boolean isAvailableToNeeder();
    Needable<O,R> startConfigReturnNeedable(R n_eeder);
    R getActiveNeeder();
    boolean isNeededUsable();
    R endCfg();
}
public interface Needer  {
    void startConfig(Class<?> cls_needed);
    boolean isConfigActive();
    Class getNeededType();
    void neeadableSetsNeeded(Object o_fullyConfigured);
}

উত্তর:


21

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

আমি নীচে এই বিকল্পটি পুঙ্খানুপুঙ্খভাবে নথিভুক্ত করেছি, যাকে আমি ব্লাইন্ড বিল্ডার প্যাটার্ন বলি।


ডিজাইনের ধরণ: অন্ধ নির্মাতা

জোশুয়া ব্লচের বিল্ডার প্যাটার্নের বিকল্প হিসাবে (কার্যকর জাভা 2 য় সংস্করণে আইটেম 2), আমি যা "ব্লাইন্ড বিল্ডার প্যাটার্ন" বলি তা তৈরি করেছি, যা ব্লচ বিল্ডারের অনেকগুলি সুবিধা ভাগ করে এবং একক চরিত্রকে বাদ দিয়ে, ঠিক একইভাবে ব্যবহৃত হয়। অন্ধ নির্মাতাদের সুবিধা রয়েছে

  • বৃত্তাকার নির্ভরতা দূর করে, তার বেষ্টনকারী শ্রেণি থেকে বিল্ডারকে ডিকোপলিং,
  • এনকোলেসিং ক্লাসের সোর্স কোডের আকার (যা আর নেই ) হ্রাস করে এবং
  • ToBeBuiltশ্রেণীর বিল্ডার বাড়ানো ছাড়াই বর্ধিত হতে দেয় ।

এই ডকুমেন্টেশনে, আমি ক্লাস-নির্মিত-নির্মিত ToBeBuiltশ্রেণি হিসাবে উল্লেখ করব ।

ব্লচ বিল্ডার সহ একটি ক্লাস প্রয়োগ করা হয়েছে

একটি ব্লচ নির্মাতা public static classশ্রেণীর ভিতরে একটি বিল্ড থাকে যা এটি তৈরি করে। একটি উদাহরণ:

পাবলিক ক্লাস ইউজার কনফিগ {
   ব্যক্তিগত ফাইনাল স্ট্রিং sName;
   বেসরকারী চূড়ান্ত int iAge;
   বেসরকারী চূড়ান্ত স্ট্রিং এসএফএলক্লোর;
   সর্বজনীন ব্যবহারকারীকনফাইগ
      // স্থানান্তর
         চেষ্টা করুন
            sName = uc_c.sName;
         } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
            নতুন নালপয়েন্টার এক্সেকশন ("uc_c") নিক্ষেপ করুন;
         }
         iAge = uc_c.iAge;
         sFavColor = uc_c.sFavColor;
      // এখানে সমস্ত ক্ষেত্রকে ভ্যালিডেট করুন
   }
   পাবলিক স্ট্রিং টু স্ট্রিং () {
      "নাম =" + sName + ", বয়স =" + iAge + ", এসএফএভলক্লার =" + এসএফএলক্লোর;
   }
   //builder...START
   পাবলিক স্ট্যাটিক ক্লাস সিএফজি {
      ব্যক্তিগত স্ট্রিং sName;
      প্রাইভেট ইন আইএজি;
      ব্যক্তিগত স্ট্রিং এসএফএলক্লোর;
      পাবলিক সিএফজি (স্ট্রিং s_name) {
         sName = s_name;
      }
      // স্ব-প্রত্যাবর্তনকারী ... START
         পাবলিক সিএফজি বয়স (int i_age) {
            iAge = i_age;
            এটি ফেরত দিন;
         }
         পাবলিক সিএফজি প্রিয় কলার (স্ট্রিং এস_ রঙ) {
            sFavColor = s_color;
            এটি ফেরত দিন;
         }
      // স্ব-প্রত্যাবর্তনকারী ... শেষ END
      সর্বজনীন ব্যবহারকারী কনফিগ বিল্ড () {
         রিটার্ন (নতুন ইউজার কনফিগ (এটি));
      }
   }
   //builder...END
}

একটি ব্লচ নির্মাতার সাথে একটি ক্লাস ইনস্ট্যান্ট করছে

ইউজারকনফিগ ইউসি = নতুন ইউজারকনফিগ.সিএফজি ("কেরিমিট")। বয়স (50)

ব্লাইন্ড বিল্ডার হিসাবে কার্যকর করা একই শ্রেণি

একজন ব্লাইন্ড বিল্ডারের তিনটি অংশ রয়েছে, যার প্রত্যেকটি পৃথক উত্স-কোড ফাইলে রয়েছে:

  1. ToBeBuiltবর্গ (এই উদাহরণে: UserConfig)
  2. এর " Fieldable" ইন্টারফেস
  3. নির্মাতা

1. তৈরি করা বর্গ

বিল্ট-টু বিল্ট বর্গটি তার Fieldableইন্টারফেসটিকে তার একমাত্র নির্মাণকারী প্যারামিটার হিসাবে গ্রহণ করে । নির্মাতা এটি থেকে সমস্ত অভ্যন্তরীণ ক্ষেত্র সেট করে এবং প্রতিটিকে বৈধ করে। সবচেয়ে বড় কথা, এই ToBeBuiltশ্রেণীর এর নির্মাতার সম্পর্কে কোনও জ্ঞান নেই।

পাবলিক ক্লাস ইউজার কনফিগ {
   ব্যক্তিগত ফাইনাল স্ট্রিং sName;
   বেসরকারী চূড়ান্ত int iAge;
   বেসরকারী চূড়ান্ত স্ট্রিং এসএফএলক্লোর;
    সর্বজনীন ব্যবহারকারীকনফিগ (ইউজারকনফিগ_ফিল্ডেবল uc_f) {// রান্নাঘর
      // স্থানান্তর
         চেষ্টা করুন
            sName = uc_f.getName ();
         } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
            নতুন নালপয়েন্টার এক্সেকশন ("uc_f") নিক্ষেপ করুন;
         }
         iAge = uc_f.getAge ();
         এসএফএলক্লোর = uc_f.getFavoriteColor ();
      // এখানে সমস্ত ক্ষেত্রকে ভ্যালিডেট করুন
   }
   পাবলিক স্ট্রিং টু স্ট্রিং () {
      "নাম =" + sName + ", বয়স =" + iAge + ", এসএফএভলক্লার =" + এসএফএলক্লোর;
   }
}

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

2. " Fieldable" ইন্টারফেস

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

নীচের অংশে বর্ণিত হিসাবে, আমি এই ইন্টারফেসে ফাংশনগুলি মোটেও নথিভুক্ত করি না।

সর্বজনীন ইন্টারফেস
   স্ট্রিং getName ();
   int getAge ();
   স্ট্রিং getFavoriteColor ();
}

3. নির্মাতা

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

অবশেষে, Fieldableইন্টারফেসের মতো, আমি এর প্রাপ্তকারীদের কোনও নথি করি না।

পাবলিক ক্লাস ইউজার কনফিগ_সিএফজি ইউজার কনফিগ_ফিল্ডেবল প্রয়োগ করে {
   পাবলিক স্ট্রিং sName;
   পাবলিক ইন আইএজি;
    পাবলিক স্ট্রিং এসএফএলক্লোর;
    সর্বজনীন ব্যবহারকারীকনফিগ_সিএফজি (স্ট্রিং এর_নাম) {
       sName = s_name;
    }
    // স্ব-প্রত্যাবর্তনকারী ... START
       সর্বজনীন ব্যবহারকারীকনফিগ_সিএফজি বয়স (ইন্টি আই_এজ) {
          iAge = i_age;
          এটি ফেরত দিন;
       }
       পাবলিক ইউজার কনফিগ_সিএফজি ফেভারিট কালার (স্ট্রিং s_color) {
          sFavColor = s_color;
          এটি ফেরত দিন;
       }
    // স্ব-প্রত্যাবর্তনকারী ... শেষ END
    //getters...START
       পাবলিক স্ট্রিং getName () {
          রিটার্ন sName;
       }
       পাবলিক ইন্ট getAge () {
          রিটার্ন আইএজ;
       }
       পাবলিক স্ট্রিং get ফেভারিট কালার () {
          রিটার্ন এসএফএলক্লোর;
       }
    //getters...END
    সর্বজনীন ব্যবহারকারী কনফিগ বিল্ড () {
       রিটার্ন (নতুন ইউজার কনফিগ (এটি));
    }
}

ব্লাইন্ড বিল্ডার দিয়ে ক্লাস ইনস্ট্যান্ট করছে

ইউজারকনফিগ uc = নতুন ইউজারকনফিগ_সিএফজি ("কেরমিট")। বয়স (50)

পার্থক্যটি " UserConfig_Cfg" এর পরিবর্তে " UserConfig.Cfg"

নোট

অসুবিধা:

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

ব্লাইন্ড বিল্ডার সংকলন সোজা-এগিয়ে রয়েছে:

  1. ToBeBuilt_Fieldable
  2. ToBeBuilt
  3. ToBeBuilt_Cfg

Fieldableইন্টারফেস সম্পূর্ণরূপে ঐচ্ছিক

ToBeBuiltকয়েকটি প্রয়োজনীয় ক্ষেত্রের সাথে শ্রেণীর জন্য - যেমন এই UserConfigউদাহরণ বর্গ হিসাবে , নির্মাতা সহজেই হতে পারে

সর্বজনীন ব্যবহারকারী কনফিগ (স্ট্রিং s_ নাম, অন্তর্নিহিত i_age, স্ট্রিং s_favColor) {

এবং সাথে নির্মাতাকে ডেকে আনে

সর্বজনীন ব্যবহারকারী কনফিগ বিল্ড () {
   রিটার্ন (নতুন ইউজারকনফিগ (getName (), getAge (), getFoiceiteColor ()));
}

বা এমনকি প্রাপ্তি (বিল্ডারে) পুরোপুরি বাদ দিয়ে:

   রিটার্ন (নতুন ইউজারকনফিগ (sName, iAge, sFavoriteColor));

সরাসরি ক্ষেত্রগুলি পার করার মাধ্যমে, ToBeBuiltশ্রেণিটি Fieldableইন্টারফেসের মতোই "অন্ধ" (তার নির্মাতাকে অজানা) is তবে, যে ToBeBuiltক্লাসগুলির জন্য এবং "বহুবার বাড়ানো এবং উপ-বর্ধিত" হওয়ার উদ্দেশ্যে করা হয়েছে (যা এই পোস্টের শিরোনামে রয়েছে), যে কোনও ক্ষেত্রে কোনও পরিবর্তন প্রতিটি উপ-শ্রেণিতে, প্রতিটি বিল্ডার এবং ToBeBuiltকনস্ট্রাক্টরের পরিবর্তনের প্রয়োজন । ক্ষেত্র এবং উপ-শ্রেণীর সংখ্যা বাড়ার সাথে সাথে এটি বজায় রাখা অবৈধ হয়ে ওঠে।

(প্রকৃতপক্ষে, কয়েকটি প্রয়োজনীয় ক্ষেত্রের সাথে, কোনও বিল্ডারকে ব্যবহার করা মোটামুটি অতিরিক্ত পরিমাণে হতে পারে those আগ্রহীদের জন্য, এখানে আমার ব্যক্তিগত লাইব্রেরির কয়েকটি বৃহত্তর ফিল্ডেবল ইন্টারফেসের নমুনা is

সাব-প্যাকেজে মাধ্যমিক ক্লাস

আমি সমস্ত নির্মাতা এবং Fieldableক্লাসগুলি, সমস্ত ব্লাইন্ড বিল্ডারদের, তাদের ToBeBuiltশ্রেণীর উপ-প্যাকেজে রাখতে পছন্দ করি । সাব-প্যাকেজটির নাম সর্বদা " z" রাখা হয়। এটি এই মাধ্যমিক শ্রেণিকে জাভাডক প্যাকেজ তালিকার বিশৃঙ্খলা থেকে বাধা দেয়। উদাহরণ স্বরূপ

  • library.class.my.UserConfig
  • library.class.my.z.UserConfig_Fieldable
  • library.class.my.z.UserConfig_Cfg

বৈধতা উদাহরণ

উপরে উল্লিখিত হিসাবে, সমস্ত বৈধতা ToBeBuiltএর নির্মাণকারীর মধ্যে ঘটে । উদাহরণস্বরূপ বৈধকরণ কোড সহ এখানে আবার নির্মাতা রয়েছে:

সর্বজনীন ব্যবহারকারী কনফিগ (ইউজারকনফিগ_ ফিল্ডেবল uc_f) {
   // স্থানান্তর
      চেষ্টা করুন
         sName = uc_f.getName ();
      } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
         নতুন নালপয়েন্টার এক্সেকশন ("uc_f") নিক্ষেপ করুন;
      }
      iAge = uc_f.getAge ();
      এসএফএলক্লোর = uc_f.getFavoriteColor ();
   // বৈধতা (নিখরচায় প্রাক-সংকলন করা উচিত ...)
      চেষ্টা করুন
         যদি (! প্যাটার্ন.কম) ফাইল ("\\ ডাব্লু +")। ম্যাচার (এস নাম)। ম্যাচগুলি ())
            নতুন অবৈধআরগমেন্টএক্সেপশন নিক্ষেপ করুন ("uc_f.getName () (\" "+ sName +" not ") খালি নাও থাকতে পারে এবং কেবলমাত্র অক্ষরের অঙ্ক এবং আন্ডারস্কোর থাকতে হবে;");
         }
      } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
         নতুন নালপয়েন্টারএক্সসেপশন ("uc_f.getName ()") নিক্ষেপ করুন;
      }
      যদি (iAge <0)
         নতুন অবৈধআরগমেন্টএক্সেপশন ("uc_f.getAge () (" + iAge + ") শূন্যের চেয়ে কম।");
      }
      চেষ্টা করুন
         যদি (! প্যাটার্ন.কম) ফাইল ("(?: লাল | নীল | সবুজ | গরম গোলাপী)") mat ম্যাচার (এসএফএলক্লোর) mat ম্যাচগুলি ())
            নতুন অবৈধ অরগমেন্টএক্সেপশন ("uc_f.getF मनগতে রঙিন) (" \ "" + uc_f.getFLiveite Color () + "\") লাল, নীল, সবুজ, বা গরম গোলাপী নয় throw ");
         }
      } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
         নতুন নালপয়েন্টারএক্সসেপশন ("uc_f.getF मनঘাটিত কলর ()") নিক্ষেপ করুন;
      }
}

ডকুমেন্টিং বিল্ডার

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

প্রাপ্তি: ToBeBuiltকেবলমাত্র ক্লাসে

প্রাপ্তরা কেবল ToBeBuiltক্লাসে নথিভুক্ত হয় । উভয় শ্রেণী _Fieldableএবং_Cfg শ্রেণিতে সমতুল্য প্রাপ্তরা উপেক্ষা করা হয়। আমি এগুলি মোটেও নথিভুক্ত করি না।

/ **
   <P> ব্যবহারকারীর বয়স </ </ p>
   @ রিটার্ন একটি ব্যবহারকারীর বয়সের প্রতিনিধিত্ব করে int
   @see ইউজার কনফিগ_সিএফজি # বয়স (পূর্ববর্তী)
   @see getName ()
 ** /
পাবলিক ইন্ট getAge () {
   রিটার্ন আইএজ;
}

প্রথমটি @seeতার সেটারের একটি লিঙ্ক, যা বিল্ডার শ্রেণিতে রয়েছে।

সেটটার্স: বিল্ডার-ক্লাসে

সেটার নথিভুক্ত করা যেমন যদি এটা হয় ToBeBuiltবর্গ , এবং এছাড়াও হিসাবে যদি এটি বৈধতা (যা সত্যিই দ্বারা সম্পন্ন করা হয় না ToBeBuiltএর কন্সট্রাকটর)। তারকাচিহ্ন (" *") একটি ভিজ্যুয়াল ক্লু যা ইঙ্গিত করে যে লিঙ্কটির লক্ষ্য অন্য শ্রেণিতে রয়েছে।

/ **
   <P> ব্যবহারকারীর বয়স নির্ধারণ করুন </ </ p>
   @ পরিমাপিকা i_age শূন্যের চেয়ে কম নাও হতে পারে। {@ কোড ইউজারকনফিগ # getName () getName ()} * সাথে পান।
   নিবন্ধন করুন
 ** /
সর্বজনীন ব্যবহারকারীকনফিগ_সিএফজি বয়স (ইন্টি আই_এজ) {
   iAge = i_age;
   এটি ফেরত দিন;
}

আরো তথ্য

এগুলি একসাথে রেখে: অন্ধ নির্মাতার সম্পূর্ণ উত্স, সম্পূর্ণ ডকুমেন্টেশন সহ

UserConfig.java

আমদানি java.util.regex.Pattern;
/ **
   <P> একজন ব্যবহারকারী সম্পর্কে তথ্য - <আই> [নির্মাতা: ইউজারকনফিগ_সিএফজি] </ i> </P>
   <P> সমস্ত ক্ষেত্রের বৈধকরণ এই শ্রেণীর নির্মাণকারীতে ঘটে। তবে প্রতিটি বৈধতার প্রয়োজনীয়তা কেবলমাত্র বিল্ডারের সেটার ফাংশনে ডকুমেন্ট। </ P>
   <P> {@ কোড জাভা xbn.z.xmpl.lang.builder.finalv.UserConfig} </P>
 ** /
পাবলিক ক্লাস ইউজার কনফিগ {
   সর্বজনীন স্ট্যাটিক চূড়ান্ত শূন্যস্থানীয় প্রধান (স্ট্রিং [] উপেক্ষা)
      ইউজারকনফিগ uc = নতুন ইউজারকনফিগ_সিএফজি ("কেরমিট")। বয়স (50)
      System.out.println (UC);
   }
   ব্যক্তিগত ফাইনাল স্ট্রিং sName;
   বেসরকারী চূড়ান্ত int iAge;
   বেসরকারী চূড়ান্ত স্ট্রিং এসএফএলক্লোর;
   / **
      <P> একটি নতুন উদাহরণ তৈরি করুন। এটি সমস্ত ক্ষেত্র সেট করে এবং বৈধ করে। </ P>
      @param uc_f {@ কোড নাল not নাও হতে পারে}
    ** /
   সর্বজনীন ব্যবহারকারী কনফিগ (ইউজারকনফিগ_ ফিল্ডেবল uc_f) {
      // স্থানান্তর
         চেষ্টা করুন
            sName = uc_f.getName ();
         } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
            নতুন নালপয়েন্টার এক্সেকশন ("uc_f") নিক্ষেপ করুন;
         }
         iAge = uc_f.getAge ();
         এসএফএলক্লোর = uc_f.getFavoriteColor ();
      // বৈধকরণ
         চেষ্টা করুন
            যদি (! প্যাটার্ন.কম) ফাইল ("\\ ডাব্লু +")। ম্যাচার (এস নাম)। ম্যাচগুলি ())
               নতুন অবৈধআরগমেন্টএক্সেপশন নিক্ষেপ করুন ("uc_f.getName () (\" "+ sName +" not ") খালি নাও থাকতে পারে এবং কেবলমাত্র অক্ষরের অঙ্ক এবং আন্ডারস্কোর থাকতে হবে;");
            }
         } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
            নতুন নালপয়েন্টারএক্সসেপশন ("uc_f.getName ()") নিক্ষেপ করুন;
         }
         যদি (iAge <0)
            নতুন অবৈধআরগমেন্টএক্সেপশন ("uc_f.getAge () (" + iAge + ") শূন্যের চেয়ে কম।");
         }
         চেষ্টা করুন
            যদি (! প্যাটার্ন.কম) ফাইল ("(?: লাল | নীল | সবুজ | গরম গোলাপী)") mat ম্যাচার (এসএফএলক্লোর) mat ম্যাচগুলি ())
               নতুন অবৈধ অরগমেন্টএক্সেপশন ("uc_f.getF मनগতে রঙিন) (" \ "" + uc_f.getFLiveite Color () + "\") লাল, নীল, সবুজ, বা গরম গোলাপী নয় throw ");
            }
         } ধরা (নালপয়েন্টারএক্সপশন আরএক্স) {
            নতুন নালপয়েন্টারএক্সসেপশন ("uc_f.getF मनঘাটিত কলর ()") নিক্ষেপ করুন;
         }
   }
   //getters...START
      / **
         <P> ব্যবহারকারীর নাম </ </ p>
         @ রিটার্ন এ অ - code @ কোড নাল}, খালি নয় স্ট্রিং।
         @see ইউজারকনফিগ_সিএফজি # ইউজারকনফিগ_সিএফজি (স্ট্রিং)
         @see #getAge ()
         নিবন্ধন করুন
       ** /
      পাবলিক স্ট্রিং getName () {
         রিটার্ন sName;
      }
      / **
         <P> ব্যবহারকারীর বয়স </ </ p>
         @ রিটার্ন শূন্যের চেয়ে বড় বা সমান একটি সংখ্যা greater
         @see ইউজার কনফিগ_সিএফজি # বয়স (পূর্ববর্তী)
         @see #getName ()
       ** /
      পাবলিক ইন্ট getAge () {
         রিটার্ন আইএজ;
      }
      / **
         <P> ব্যবহারকারীর প্রিয় রঙ </ </ p>
         @ রিটার্ন এ অ - code @ কোড নাল}, খালি নয় স্ট্রিং।
         @see ইউজার কনফিগ_সিএফজি # বয়স (পূর্ববর্তী)
         @see #getName ()
       ** /
      পাবলিক স্ট্রিং get ফেভারিট কালার () {
         রিটার্ন এসএফএলক্লোর;
      }
   //getters...END
   পাবলিক স্ট্রিং টু স্ট্রিং () {
      "getName () =" + getName () + ", getAge () =" + getAge () + ", getFoiceiteColor () =" + getFavoriteColor () পান;
   }
}

UserConfig_Fieldable.java

/ **
   <P> l @ লিঙ্ক ইউজার কনফিগ} {@ কোড ইউজারকনফিগ # ইউজারকনফিগ (ইউজারকনফিগ_ফিল্ডেবল) কনস্ট্রাক্টর Requ দ্বারা প্রয়োজনীয় </ </ p>
 ** /
সর্বজনীন ইন্টারফেস
   স্ট্রিং getName ();
   int getAge ();
   স্ট্রিং getFavoriteColor ();
}

UserConfig_Cfg.java

আমদানি java.util.regex.Pattern;
/ **
   <P> er @ লিঙ্ক ইউজার কনফিগ for এর জন্য নির্মাতা </ </ p>
   <P> সমস্ত ক্ষেত্রের বৈধতা <CODE> ইউজার কনফিগ </CODE> কনস্ট্রাক্টরে ঘটে। তবে, প্রতিটি বৈধতার প্রয়োজনীয়তা কেবলমাত্র এই শ্রেণীর সেটার ফাংশনে ডকুমেন্ট। </ P>
 ** /
পাবলিক ক্লাস ইউজার কনফিগ_সিএফজি ইউজার কনফিগ_ফিল্ডেবল প্রয়োগ করে {
   পাবলিক স্ট্রিং sName;
   পাবলিক ইন আইএজি;
   পাবলিক স্ট্রিং এসএফএলক্লোর;
   / **
      <P> ব্যবহারকারীর নামের সাথে একটি নতুন উদাহরণ তৈরি করুন </ </ p>
      @ পরিম s_name {@ কোড নাল} বা খালি নাও হতে পারে এবং এতে কেবল অক্ষর, সংখ্যা এবং আন্ডারস্কোর থাকতে হবে। সঙ্গে পান {@code UserConfig # getName () getName ()} {@ কোড ()} ।
    ** /
   সর্বজনীন ব্যবহারকারীকনফিগ_সিএফজি (স্ট্রিং এর_নাম) {
      sName = s_name;
   }
   // স্ব-প্রত্যাবর্তনকারী ... START
      / **
         <P> ব্যবহারকারীর বয়স নির্ধারণ করুন </ </ p>
         @param i_age শূন্যের চেয়ে কম নাও হতে পারে। সঙ্গে পান {@code UserConfig # getName () getName ()} {@ কোড ()} ।
         নিবন্ধন করুন
       ** /
      সর্বজনীন ব্যবহারকারীকনফিগ_সিএফজি বয়স (ইন্টি আই_এজ) {
         iAge = i_age;
         এটি ফেরত দিন;
      }
      / **
         <P> ব্যবহারকারীর প্রিয় রঙ সেট করুন </ </ p>
         @param s_color অবশ্যই {@ কোড "লাল"}, {@ কোড "নীল"}, {@ কোড সবুজ}, বা {@ কোড "গরম গোলাপী"} হতে হবে} C @ কোড ইউজারকনফিগ # getName () getName ()} {@ কোড ()} * এর সাথে পান।
         @see #age (int)
       ** /
      পাবলিক ইউজার কনফিগ_সিএফজি ফেভারিট কালার (স্ট্রিং s_color) {
         sFavColor = s_color;
         এটি ফেরত দিন;
      }
   // স্ব-প্রত্যাবর্তনকারী ... শেষ END
   //getters...START
      পাবলিক স্ট্রিং getName () {
         রিটার্ন sName;
      }
      পাবলিক ইন্ট getAge () {
         রিটার্ন আইএজ;
      }
      পাবলিক স্ট্রিং get ফেভারিট কালার () {
         রিটার্ন এসএফএলক্লোর;
      }
   //getters...END
   / **
      <পি> কনফিগার করা হয়েছে এমনভাবে ইউজার কনফিগ তৈরি করুন </ </ p>
      @ পুনর্বারণ <CODE> (নতুন {@ লিঙ্ক ইউজারফনফিং # ইউজারকনফিগ (ইউজারকনফিগ_ফিল্ডেবল) ইউজারকনফিগ this (এটি)) </ code>
    ** /
   সর্বজনীন ব্যবহারকারী কনফিগ বিল্ড () {
      রিটার্ন (নতুন ইউজার কনফিগ (এটি));
   }
}


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

3
আপনার যদি ইতিমধ্যে না থাকে তবে আপনার সত্যিই এই সম্পর্কে ব্লগ করা উচিত, অ্যালগরিদম ডিজাইনের চমৎকার টুকরো! আমি এখন এটি ভাগ করে নিচ্ছি :-)।
মার্টিজন ভার্গবার্গ

4
সদয় শব্দগুলির জন্য আপনাকে ধন্যবাদ। এটি এখন আমার নতুন ব্লগে প্রথম পোস্ট: aliteralmind.wordpress.com/2014/02/14/blind_builder
aliteralmind

যদি বিল্ডার এবং বিল্ট অবজেক্ট উভয়ই ফিল্ডেবল প্রয়োগ করে তবে প্যাটার্নটি আমি রিডেবলফু / মিউটেবলফু / ইমিউটেবলফু হিসাবে উল্লেখ করেছি তার সাথে সাদৃশ্য হতে শুরু করে, যদিও পরিবর্তিত জিনিস তৈরির পদ্ধতিটি না করে বিল্ডারের "বিল্ড" সদস্য হতে হবে, আমি এটিকে কল করুন asImmutableএবং এটিকে ReadableFooইন্টারফেসে অন্তর্ভুক্ত করুন [সেই দর্শনটি ব্যবহার করে, buildএকটি অপরিবর্তনীয় বস্তুর উপর কল করা কেবল একই বস্তুর একটি রেফারেন্স ফিরিয়ে আনতে পারে]।
সুপারক্যাট

1
@ থমাসএন আপনার এতে *_Fieldableনতুন গেটারগুলি প্রসারিত এবং যুক্ত করতে হবে, এবং এটিতে প্রসারিত করতে হবে এবং এতে *_Cfgনতুন সেটটার যুক্ত করতে হবে, তবে আপনাকে কেন বিদ্যমান গেটার এবং সেটটারগুলি পুনরুত্পাদন করতে হবে তা আমি দেখতে পাচ্ছি না। এগুলি উত্তরাধিকারসূত্রে প্রাপ্ত এবং যদি না তাদের আলাদা কার্যকারিতা প্রয়োজন হয় তবে এগুলি পুনরায় তৈরি করার দরকার নেই।
aliteralmind

13

আমি মনে করি যে এখানে প্রশ্নটি প্রমানের চেষ্টা না করে শুরু থেকেই কিছু অনুমান করে, যে নির্মাতা প্যাটার্নটি সহজাতভাবে ভাল।

tl; dr আমি মনে করি বিল্ডার প্যাটার্নটি যদি খুব ভাল ধারণা হয় তবে খুব কমই হয়


নির্মাতা প্যাটার্ন উদ্দেশ্য

বিল্ডার প্যাটার্নের উদ্দেশ্য হ'ল দুটি নিয়ম বজায় রাখা যা আপনার শ্রেণিকে গ্রাস করা সহজ করে তুলবে:

  1. অসম্পূর্ণ / অপ্রয়োজনীয় / অবৈধ অবস্থায় অবজেক্টগুলি নির্মাণ করা উচিত নয়।

    • এটি এমন পরিস্থিতিগুলিকে বোঝায় যেখানে উদাহরণস্বরূপ কোনও Personবস্তুটি Idভরাট না করেই তৈরি করা যেতে পারে , অন্যদিকে কোডের সমস্ত টুকরা যাতে সেই অবজেক্টটি ব্যবহার করে কেবল সেই সাথে সঠিকভাবে কাজ করার প্রয়োজন হতে পারে ।IdPerson
  2. অবজেক্ট কনস্ট্রাক্টরগুলির জন্য খুব বেশি পরামিতি প্রয়োজন হবে না ।

সুতরাং নির্মাতা প্যাটার্নের উদ্দেশ্যটি অ-বিতর্কিতভাবে ভাল। আমি মনে করি এটির অনেক আকাঙ্ক্ষা এবং ব্যবহার মূলত বিশ্লেষণের ভিত্তিতে তৈরি হয়েছে যা মূলত এই পর্যন্ত চলে গেছে: আমরা এই দুটি বিধি চাই, এটি এই দুটি নিয়ম দেয় - যদিও আমি মনে করি যে এই দুটি নিয়ম সম্পাদন করার অন্যান্য উপায়গুলি তদন্ত করার পক্ষে এটি মূল্যবান worth


কেন অন্যান্য পদ্ধতির দিকে তাকিয়ে বিরক্ত করবেন?

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


অন্যান্য পন্থা

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

নির্মাণে কোনও অবজেক্টকে সমস্ত প্রয়োজনীয় তথ্য দেওয়ার একটি উপায় হ'ল কেবল নির্মাণকারীর সাথে পরামিতি যুক্ত করা। যদি সেই তথ্য নির্মাণকারীর দ্বারা দাবি করা হয়, আপনি এই সমস্ত তথ্য ছাড়াই এই অবজেক্টটি তৈরি করতে সক্ষম হবেন না, সুতরাং এটি একটি বৈধ অবস্থায় পরিণত হবে will তবে যদি অবজেক্টটির বৈধ হওয়ার জন্য প্রচুর তথ্য প্রয়োজন হয়? ওহ ডাং, যদি এমন হয় তবে এই পদ্ধতির উপরের # 2 নিয়মটি ভঙ্গ হবে

ঠিক আছে আর কি আছে? ভাল আপনি সহজেই সেই সমস্ত তথ্য নিতে পারেন যা আপনার অবজেক্টের জন্য একটি সামঞ্জস্যপূর্ণ অবস্থায় থাকতে পারে এবং এটি অন্য কোনও বস্তুর মধ্যে বান্ডিল করতে পারে যা নির্মাণের সময় নেওয়া হয়। আপনার বিল্ডার প্যাটার্নের পরিবর্তে উপরের কোডটি হ'ল:

//DTO...START
public class Cfg  {
   public String sName    ;
   public int    iAge     ;
   public String sFavColor;
}
//DTO...END

public class UserConfig  {
   private final String sName    ;
   private final int    iAge     ;
   private final String sFavColor;
   public UserConfig(Cfg uc_c)  {
      ...
   }

   public String toString()  {
      return  "name=" + sName + ", age=" + iAge + ", sFavColor=" + sFavColor;
   }
}

এটি বিল্ডার প্যাটার্ন থেকে কোনও বড় বিষয় নয়, যদিও এটি সামান্য সরল এবং সবচেয়ে গুরুত্বপূর্ণ আমরা এখন নিয়ম # 1 এবং নিয়ম # 2 কে সন্তুষ্ট করছি

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

public class NetworkAddress {
   public String Ip;
   public int Port;
   public NetworkAddress Proxy;
}

public class SocketConnection {
   public SocketConnection(NetworkAddress address) {
      ...
   }
}

public class FtpClient {
   public FtpClient(NetworkAddress address) {
      ...
   }
}

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

public class SslCert {
   public NetworkAddress Authority;
   public byte[] PrivateKey;
   public byte[] PublicKey;
}

public class FtpsClient extends FtpClient {
   public FtpsClient(NetworkAddress address, SslCert cert) {
      super(address);
      ...
   }
}

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


কিভাবে বিল্ডার প্যাটার্ন উন্নত করা যায়

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


যখন এটি একটি ভাল ধারণা

একপাশে ভাড়া, বিল্ডার প্যাটার্নের কুলুঙ্গি রয়েছে । আমরা সবাই এটি জানি কারণ আমরা সকলেই এই নির্দিষ্ট নির্মাতাকে এক পর্যায়ে বা অন্য সময়ে শিখেছি:StringBuilder - এখানে উদ্দেশ্যটি সাধারণ নির্মাণ নয়, কারণ স্ট্রিংগুলি নির্মাণ করা এবং সংমিশ্রণ করা সহজ হতে পারে না। এটি দুর্দান্ত নির্মাতা কারণ এটির কার্যকারিতা সুবিধা রয়েছে ।

পারফরম্যান্স সুবিধাটি হ'ল: আপনার কাছে একগুচ্ছ বস্তু রয়েছে, সেগুলি এক পরিবর্তনযোগ্য প্রকারের you আপনি যদি এটি ক্রমবর্ধমানভাবে করেন তবে আপনি এখানে অনেক মধ্যস্থতাকারী বস্তু তৈরি করেছেন, সুতরাং এটি একবারে করা আরও বেশি পারফরম্যান্ট এবং আদর্শ।

সুতরাং আমি মনে করি এটি যখন ভাল ধারণা হয় তখন এর মূল সমস্যাটি এই সমস্যাটির ডোমেনে থাকে StringBuilder: একাধিক ঘটনাক্রমে অপরিবর্তনীয় প্রকারকে এক অপরিবর্তনীয় ধরণের একক দৃষ্টান্তে রূপান্তরিত করা দরকার


আমি মনে করি না যে আপনার প্রদত্ত উদাহরণটি কোনও নিয়মকে সন্তুষ্ট করে। আমাকে একটি অবৈধ অবস্থায় সিএফজি তৈরি করতে বাধা দেওয়ার কিছুই নেই, এবং প্যারামিটারগুলি কর্টর থেকে সরিয়ে নিয়ে যাওয়ার সাথে সাথে তারা কেবলমাত্র একটি স্বল্প আইডিয়াটিক এবং আরও ভার্জিক জায়গায় স্থানান্তরিত হয়েছে। fooBuilder.withBar(2).withBang("Hello").withBaz(someComplexObject).build()বিল্ডিং foos জন্য একটি সংক্ষিপ্ত এপিআই প্রস্তাব এবং বিল্ডার নিজেই প্রকৃত ত্রুটি পরীক্ষা করতে পারে। নির্মাতা ব্যতীত অবজেক্টটিকে নিজেই তার ইনপুটগুলি পরীক্ষা করে দেখতে হবে, যার অর্থ আমরা আগের চেয়ে ভাল আর নেই।
ফোশি

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

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

+1 এবং এমন একটি শ্রেণীর যার নির্মাণকারীর মধ্যে অনেকগুলি নির্ভরশীলতা রয়েছে তা অবশ্যই সংঘবদ্ধ নয় এবং এটি আরও ছোট শ্রেণিতে পুনঃসংশ্লিষ্ট হওয়া উচিত।
বাসিলিভস

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