বিল্ডার প্যাটার্নটি প্রয়োগ করার সময় কেন আমাদের একজন বিল্ডার শ্রেণি প্রয়োজন?


31

আমি বিল্ডার প্যাটার্নের অনেকগুলি বাস্তবায়ন দেখেছি (মূলত জাভাতে)। তাদের সকলের একটি সত্তা শ্রেণি রয়েছে (আসুন একটি Personশ্রেণি বলি ) এবং একটি নির্মাতা শ্রেণি রয়েছে PersonBuilder। নির্মাতা বিভিন্ন ক্ষেত্র "স্ট্যাকস" করে এবং তর্কগুলি new Personপাস করার সাথে একটি ফেরত দেয় । আমাদের কেন নির্মাতাদের ক্লাসের স্পষ্টতই দরকার হয়, পরিবর্তে সমস্ত বিল্ডার পদ্ধতি Personক্লাসে রেখে দেওয়া?

উদাহরণ স্বরূপ:

class Person {

  private String name;
  private Integer age;

  public Person() {
  }

  Person withName(String name) {
    this.name = name;
    return this;
  }

  Person withAge(int age) {
    this.age = age;
    return this;
  }
}

আমি কেবল বলতে পারি Person john = new Person().withName("John");

PersonBuilderক্লাসের দরকার কেন ?

আমি দেখতে পাচ্ছি একমাত্র সুবিধা, আমরা Personক্ষেত্রগুলি যেমন ঘোষণা করতে পারি final, তা হ্রাসযোগ্যতা নিশ্চিত করে।


4
দ্রষ্টব্য: এই প্যাটার্নটির সাধারণ নাম chainable setters: D
মূইং হাঁস

4
একক দায়িত্ব নীতি। যদি আপনি ব্যক্তি শ্রেণিতে যুক্তি রাখেন তবে এটি করার একাধিক কাজ রয়েছে
রেগেইগুইটার

1
আপনার সুবিধাটি যে কোনও উপায়ে করা যেতে পারে: withNameকেবলমাত্র নাম ক্ষেত্র পরিবর্তিত হয়ে আমি সেই ব্যক্তির একটি অনুলিপি ফিরিয়ে দিতে পারি । অন্য কথায়, অপরিবর্তনীয় Person john = new Person().withName("John");এমনকি কাজ করতে পারে Person(এবং এটি কার্যকরী প্রোগ্রামিংয়ের একটি সাধারণ প্যাটার্ন)।
ব্রায়ান ম্যাকচ্যাটন

9
@ মুভিংডাক: এর জন্য অন্য একটি সাধারণ শব্দ একটি সাবলীল ইন্টারফেস
ম্যাক

2
@ ম্যাক আমি মনে করি সাবলীল ইন্টারফেসটি কিছুটা বেশি সাধারণ - আপনি voidপদ্ধতিগুলি এড়িয়ে চলেন । সুতরাং, উদাহরণস্বরূপ যদি Personএমন কোনও পদ্ধতি থাকে যা তাদের নাম প্রিন্ট করে, আপনি এখনও এটি একটি সাবলীল ইন্টারফেসের সাথে চেইন করতে পারেন person.setName("Alice").sayName().setName("Bob").sayName()। যাইহোক, আমি আপনার পরামর্শ সহ জাভডকগুলিতে এনিোটেট @return Fluent interfaceকরি - এটি জেনেরিক এবং যথেষ্ট পরিস্কার যখন এটি return thisকার্যকর করা শেষে যে কোনও পদ্ধতিতে প্রয়োগ করে এবং এটি মোটামুটি পরিষ্কার। সুতরাং, একজন নির্মাতা একটি সাবলীল ইন্টারফেসও করবে।
VLAZ

উত্তর:


27

এটা তোলে যাতে আপনি হতে পারে অপরিবর্তনীয় এবং নামে পরামিতি ভান একই সময়ে।

Person p = personBuilder
    .name("Arthur Dent")
    .age(42)
    .build()
;

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

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

অবশ্যই আপনি অন্য ক্লাস ব্যবহার না করে আপনার অবজেক্টটি তৈরি করতে পারেন। তবে আপনাকে বেছে নিতে হবে। আপনি হয় ভাষাগুলিতে নামযুক্ত পরামিতিগুলি সিমুলেট করার দক্ষতা হারাবেন (জাভা এর মতো) অথবা আপনি সারাজীবন অবজেক্টগুলিতে অপরিবর্তনীয় থাকার ক্ষমতা হারাবেন।

অপরিবর্তনীয় উদাহরণ, পরামিতিগুলির কোনও নাম নেই

Person p = new Person("Arthur Dent", 42);

এখানে আপনি একক সাধারণ কন্সট্রাক্টর দিয়ে সবকিছু নির্মাণ করছেন। এটি আপনাকে অপরিবর্তনীয় থাকতে দেয় তবে আপনি নামযুক্ত পরামিতিগুলির সিমুলেশনটি আলগা করেন। যে অনেক পরামিতি সঙ্গে পড়া কঠিন। কম্পিউটারগুলি যত্ন করে না তবে এটি মানুষের পক্ষে শক্ত।

Traditionalতিহ্যবাহী সেটটারগুলির সাথে নামযুক্ত প্যারামিটার উদাহরণ সিমুলেটেড। অপরিবর্তনীয় নয়।

Person p = new Person();
p.name("Arthur Dent");
p.age(42);

এখানে আপনি সেটার দিয়ে সমস্ত কিছু তৈরি করছেন এবং নামযুক্ত প্যারামিটারগুলি সিমুলেট করছেন তবে আপনি আর অক্ষর নন। একটি সেটারের প্রতিটি ব্যবহার বস্তুর স্থিতি পরিবর্তন করে।

ক্লাস যুক্ত করে আপনি যা পান তা আপনি উভয়ই করতে পারেন।

build()যদি আপনার জন্য অনুপস্থিত বয়সের ক্ষেত্রের জন্য রানটাইম ত্রুটি যথেষ্ট হয় তবে বৈধতা সম্পাদন করা যেতে পারে । আপনি এটি আপগ্রেড করতে পারেন এবং প্রয়োগ করতে পারেন age()যা একটি সংকলক ত্রুটিযুক্ত বলে। শুধু জোশ ব্লচ নির্মাতা প্যাটার্ন দিয়ে নয়।

তার জন্য আপনার একটি অভ্যন্তরীণ ডোমেন নির্দিষ্ট ভাষা (আইডিএসএল) প্রয়োজন।

এটি আপনাকে কল করার আগে age()এবং কল name()করার আগে দাবি করতে দেয় build()। তবে আপনি কেবল thisপ্রতিবার ফিরে এসে এটি করতে পারবেন না । প্রতিটি জিনিস যা প্রত্যাবর্তন করে তা আলাদা জিনিস ফেরত দেয় যা আপনাকে পরের জিনিসটিকে কল করতে বাধ্য করে।

ব্যবহার এর মতো দেখতে পারে:

Person p = personBuilder
    .name("Arthur Dent")
    .age(42)
    .build()
;

কিন্তু এই:

Person p = personBuilder
    .age(42)
    .build()
;

একটি সংকলক ত্রুটির কারণ ঘটায় age()কেবল তার দ্বারা কল করা বৈধ name()

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


3
এবং তারপরে কেউ জিজ্ঞাসা করেছেন যে আপনাকে বয়সের আগে নামটি কেন সরবরাহ করতে হবে , এবং এর একমাত্র উত্তর "কারণ সম্মিলিত বিস্ফোরণ"। আমি মোটামুটি নিশ্চিত যে কারও কাছে সি ++ এর মতো যথাযথ টেম্পলেট থাকলে বা সমস্ত কিছুর জন্য ভিন্ন ধরণের ব্যবহার করা ফিরে যেতে পারে তবে তারা উত্সটিকে এড়িয়ে যেতে পারে।
Deduplicator

1
কীভাবে এটি ব্যবহার করতে হয় তা জানতে একটি ফাঁস বিমূর্তকরণের জন্য অন্তর্নিহিত জটিলতার জ্ঞান প্রয়োজন। এটাই আমি এখানে দেখছি। কীভাবে নিজেকে তৈরি করতে হবে না জানার যে কোনও শ্রেণীর অবশ্যই নির্মাতার সাথে আরও নির্ভরতা রয়েছে (যেমন বিল্ডারের ধারণার উদ্দেশ্য এবং প্রকৃতি) to একটি সময় (ব্যান্ড ক্যাম্পে নয়) কেবল এমন ক্লাস্টার ফ্রেইকটিকে পূর্বাবস্থায় ফেলার জন্য 3 মাসের প্রয়োজনের কোনও জিনিস ইনস্ট্যান্ট করার একটি সাধারণ প্রয়োজন। আমি আপনার সাথে ঠাট্টা করছি না.
রাডারবব

শ্রেণিগুলির একটি সুবিধা যা তাদের কোনও নির্মাণ বিধি জানে না তা হ'ল rules নিয়মগুলি যখন পরিবর্তন হয় তখন তাদের যত্ন করে না। আমি কেবল একটি যুক্ত করতে পারি AnonymousPersonBuilderযার বিধিগুলির নিজস্ব সেট রয়েছে।
candied_orange

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

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

57

কেন কোনও বিল্ডার শ্রেণি ব্যবহার / সরবরাহ করুন:

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

4
শেষ বুলেট পয়েন্ট সম্পর্কিত। তাই ধারণা করা হচ্ছে যে একটি PersonBuilderকোন getters আছে, এবং একমাত্র উপায় বর্তমান মান পরিদর্শন থেকে কল হল .Build()একটি ফিরতে Person। এইভাবে। বিল্ড একটি সঠিকভাবে নির্মিত অবজেক্টকে বৈধতা দিতে পারে, সঠিক? অর্থাত্ এই "প্রক্রিয়াধীন" অবজেক্টের ব্যবহার রোধ করার প্রক্রিয়াটি কী?
অ্যারোনলএস

অ্যারোনএলএস, হ্যাঁ, অবশ্যই; Buildখারাপ ও / বা আন্ডার-বিল্ডড অবজেক্টগুলিকে প্রতিরোধ করার জন্য জটিল বৈধতা কোনও অপারেশনে রাখা যেতে পারে ।
এরিক tদ

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

2
অ্যারোনএলএস @ একজন নির্মাতার গ্রাহকরা থাকতে পারেন; ঐটা আসল কথা না. এটির দরকার নেই, তবে কোনও বিল্ডার যদি গ্রাহক থাকে তবে আপনাকে সচেতন হতে হবে যে যখন এই সম্পত্তিটি নির্দিষ্ট করে না দেয় তখন getAgeবিল্ডারকে ডেকে আনা যেতে পারে null। বিপরীতে, Personশ্রেণি আক্রমণকারীটিকে কার্যকর করতে পারে যে বয়স কখনই হতে পারে না null, যা অসম্ভব যখন বিল্ডার এবং প্রকৃত বস্তু মিশ্রিত হয়, যেমন ওপি'র new Person() .withName("John")উদাহরণের সাথে, যা সুখের সাথে Personকোনও বয়স ছাড়াই একটি সৃষ্টি করে । এটি এমনকি পরিবর্তনীয় শ্রেণিতেও প্রযোজ্য, কারণ সেটাররা আক্রমণকারীদের কার্যকর করতে পারে, তবে প্রাথমিক মানগুলি প্রয়োগ করতে পারে না।
হলগার

1
@ আপনার পয়েন্টগুলি সঠিক, তবে মূলত এই যুক্তিটি সমর্থন করুন যে কোনও বিল্ডার গেটসগুলি এড়ানো উচিত।
user949300

21

একটি কারণ হ'ল এটি নিশ্চিত করা যে সমস্ত পাস-ইন করা ডেটা ব্যবসায়ের নিয়মকে অনুসরণ করে।

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

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


7
প্রশ্নের উদাহরণটি একটি সাধারণ নিয়ম লঙ্ঘন সরবরাহ করে: এর জন্য কোনও বয়স দেওয়া হয়নিjohn
ক্লেথ

6
+1 এবং বিল্ডার ক্লাস ছাড়া একসাথে দুটি ক্ষেত্রের জন্য নিয়ম করা খুব কঠিন (ক্ষেত্রের এক্স + ওয়াই 10 এর চেয়ে বেশি হতে পারে না)।
রেজিনাল্ড ব্লু

7
@ রেজিনাল্ড ব্লু যদি তারা "x + y সমান" দ্বারা আবদ্ধ হয় তবে আরও শক্ত er (0,0) সহ আমাদের প্রাথমিক অবস্থা ঠিক আছে, রাজ্য (1,1 )ও ঠিক আছে, তবে একক ভেরিয়েবল আপডেটের ক্রম নেই যা উভয়ই রাষ্ট্রকে বৈধ রাখে এবং আমাদের (0,0) থেকে (1) পেয়ে যায় , 1)।
মাইকেল অ্যান্ডারসন

আমি বিশ্বাস করি এটিই সবচেয়ে বড় সুবিধা। বাকিরা সকলেই সুন্দর-সুন্দর।
গিয়াকোমো আলজেটা

5

অন্যান্য উত্তরে আমি যা দেখছি তার থেকে এটিতে একটু আলাদা কোণ।

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

class Person {
  private final String name;
  private final Integer age;

  private Person(String name, String age) {
    this.name = name;
    this.age = age;
  }  

  public Person() {
    this.name = null;
    this.age = null;
  }

  Person withName(String name) {
    return new Person(name, this.age);
  }

  Person withAge(int age) {
    return new Person(this.name, age);
  }
}

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

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


2

ইতিমধ্যে এখানে ইতিমধ্যে স্পষ্টভাবে উল্লেখ করা হয়নি যে, কারণটি হ'ল build()পদ্ধতিটি যাচাই করতে পারে যে সমস্ত ক্ষেত্রের ক্ষেত্রে বৈধ মান রয়েছে (হয় সরাসরি সেট করা হয়, বা অন্যান্য ক্ষেত্রের অন্যান্য মান থেকে নেওয়া হয়), সম্ভবত এটি সম্ভবত ব্যর্থতা মোড যে অন্যথায় ঘটতে হবে।

আরেকটি সুবিধা হ'ল আপনার Personঅবজেক্টটি আরও সাধারণ জীবনকাল এবং একটি সহজ সেট অফেরেন্টের সমাপ্ত হবে। তুমি জানো একবার আপনি একটি আছে Person p, আপনি একটি আছে p.nameও একটি বৈধ p.age। "বয়স নির্ধারিত তবে নাম না থাকলে বা নামটি যদি সেট না হয় তবে বয়স না হয়" এর মতো পরিস্থিতি পরিচালনা করার জন্য আপনার কোনও পদ্ধতিরই ডিজাইন করতে হবে না? এটি শ্রেণীর সামগ্রিক জটিলতা হ্রাস করে।


"[...] যাচাই করতে পারে যে সমস্ত ক্ষেত্র সেট করা আছে [...]" বিল্ডার প্যাটার্নের মূল বিষয়টি হ'ল আপনাকে নিজের জন্য সমস্ত ক্ষেত্র সেট করতে হবে না এবং আপনি বুদ্ধিমান ডিফল্টে ফিরে যেতে পারেন। আপনার যদি যাইহোক সমস্ত ক্ষেত্র সেট করার প্রয়োজন হয়, সম্ভবত আপনার সেই প্যাটার্নটি ব্যবহার করা উচিত নয়!
ভিনসেন্ট সাভার্ড

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

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

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

পছন্দ করুন তবে তারা বিভিন্ন জিনিসকে বৈধতা দেয়। অনেক ক্ষেত্রে আমি বিল্ডার ইন ব্যবহার করেছি, বিল্ডারের কাজ ছিল ইনপুটগুলি তৈরি করা যা শেষ পর্যন্ত কন্সট্রাক্টরকে দেওয়া হয়। উদাহরণস্বরূপ, বিল্ডারটি ক URI, ক File, বা ক দিয়ে কনফিগার করা হয়েছে FileInputStreamএবং যা অর্জনের জন্য যা সরবরাহ করা হয়েছিল তা ব্যবহার করে যা FileInputStreamশেষ পর্যন্ত কন্সট্রাক্টর কলটিতে যায় আরগ হিসাবে
আলেকজান্ডার - পুনরায় ইনস্টল করুন মনিকা

2

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


2

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

আমরা যদি বিল্ডার ক্লাসটি ব্যবহার না করি এবং সরাসরি সমস্ত বিল্ডার শ্রেণির পদ্ধতিগুলি নিজেই ব্যক্তি শ্রেণিতে স্থাপন করি তবে আমাদের প্রথমে অবজেক্টটি তৈরি করতে হবে এবং তারপরে তৈরি বস্তুর উপর সেটার পদ্ধতিগুলি গ্রহণ করতে হবে যা সৃষ্টির মধ্যবর্তী অবজেক্টের অসামঞ্জস্যপূর্ণ অবস্থার দিকে পরিচালিত করবে will বস্তু এবং বৈশিষ্ট্য নির্ধারণ।

এইভাবে বিল্ডার শ্রেণি (যেমন ব্যক্তি শ্রেণি ব্যতীত অন্য কোনও বাহ্যিক সত্তা) ব্যবহার করে আমরা নিশ্চিত করে দেখি যে বস্তুটি কখনই বেমানান অবস্থায় থাকবে না।


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

2

বিল্ডার অবজেক্টটি পুনরায় ব্যবহার করুন

অন্যরা যেমন উল্লেখ করেছে, অপরিবর্তনযোগ্যতা এবং সমস্ত ক্ষেত্রের ব্যবসায়িক যুক্তি যাচাইকরণের জন্য যাচাই করা পৃথক বিল্ডার অবজেক্টের প্রধান কারণ।

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


1

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

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

অবশ্যই, এর অর্থ হল আপনার কাছে অনেকগুলি নতুন অবজেক্ট থাকবে এবং আপনার জিনিসগুলি তৈরি করা ব্যয়বহুল হলে আপনার এটি করা উচিত নয়।

আমি আমার ব্যবসায়িক সামগ্রীর জন্য হামক্রস্ট ম্যাচচার তৈরি করার জন্য পরীক্ষার কোডটিতে এটি ব্যবহার করেছি। আমি সঠিক কোডটি মনে করতে পারি না তবে এটি দেখতে কিছুটা এমন (সরলীকৃত):

public class CustomerMatcher extends TypeSafeMatcher<Customer> {
    private final Matcher<? super String> nameMatcher;
    private final Matcher<? super LocalDate> birthdayMatcher;

    @Override
    protected boolean matchesSafely(Customer c) {
        return nameMatcher.matches(c.getName()) &&
               birthdayMatcher.matches(c.getBirthday());
    }

    private CustomerMatcher(Matcher<? super String> nameMatcher,
                            Matcher<? super LocalDate> birthdayMatcher) {
        this.nameMatcher = nameMatcher;
        this.birthdayMatcher = birthdayMatcher;
    }

    // builder methods from here on

    public static CustomerMatcher isCustomer() {
        // I could return a static instance here instead
        return new CustomerMatcher(Matchers.anything(), Matchers.anything());
    }

    public CustomerMatcher withBirthday(Matcher<? super LocalDate> birthdayMatcher) {
        return new CustomerMatcher(this.nameMatcher, birthdayMatcher);
    }

    public CustomerMatcher withName(Matcher<? super String> nameMatcher) {
        return new CustomerMatcher(nameMatcher, this.birthdayMatcher);
    }
}

আমি আমার ইউনিট পরীক্ষায় এটির মতো এটি ব্যবহার করব (উপযুক্ত স্ট্যাটিক আমদানি সহ):

assertThat(result, is(customer().withName(startsWith("Paŭlo"))));

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

@ বিল্ক সত্য - মূলত অপরিবর্তনীয় সেটটারযুক্ত একটি বস্তু (যা প্রতিবার নতুন বস্তু ফেরত দেয়) এর অর্থ হ'ল প্রতিটি বস্তু বৈধ হওয়া উচিত। আপনি যদি অবৈধ অবজেক্টগুলি (যেমন, তবে ব্যক্তি nameতবে না age) ফিরিয়ে দিচ্ছেন তবে ধারণাটি কার্যকর হয় না। ঠিক আছে, আপনি আসলে এমন কিছু ফিরিয়ে দিতে পারেন PartiallyBuiltPersonযখন এটি বৈধ নয় তবে এটি বিল্ডারকে মাস্ক করার মতো একটি হ্যাকের মতো বলে মনে হচ্ছে।
VLAZ

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