জোশুয়া ব্লচের বিল্ডার ডিজাইন প্যাটার্নের উন্নতি?


12

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

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

সুতরাং ... আমি একটি ধারণা ছিল। প্রথম, জোশুয়া ব্লচের স্টাইলে একটি উদাহরণ অবজেক্ট:

জোশ ব্লচের স্টাইল:

public class OptionsJoshBlochStyle {

    private final String option1;
    private final int option2;
    // ...other options here  <<<<

    public String getOption1() {
        return option1;
    }

    public int getOption2() {
        return option2;
    }

    public static class Builder {

        private String option1;
        private int option2;
        // other options here <<<<<

        public Builder option1(String option1) {
            this.option1 = option1;
            return this;
        }

        public Builder option2(int option2) {
            this.option2 = option2;
            return this;
        }

        public OptionsJoshBlochStyle build() {
            return new OptionsJoshBlochStyle(this);
        }
    }

    private OptionsJoshBlochStyle(Builder builder) {
        this.option1 = builder.option1;
        this.option2 = builder.option2;
        // other options here <<<<<<
    }

    public static void main(String[] args) {
        OptionsJoshBlochStyle optionsVariation1 = new OptionsJoshBlochStyle.Builder().option1("firefox").option2(1).build();
        OptionsJoshBlochStyle optionsVariation2 = new OptionsJoshBlochStyle.Builder().option1("chrome").option2(2).build();
    }
}

এখন আমার "উন্নত" সংস্করণ:

public class Options {

    // note that these are not final
    private String option1;
    private int option2;
    // ...other options here

    public String getOption1() {
        return option1;
    }

    public int getOption2() {
        return option2;
    }

    public static class Builder {

        private final Options options = new Options();

        public Builder option1(String option1) {
            this.options.option1 = option1;
            return this;
        }

        public Builder option2(int option2) {
            this.options.option2 = option2;
            return this;
        }

        public Options build() {
            return options;
        }
    }

    private Options() {
    }

    public static void main(String[] args) {
        Options optionsVariation1 = new Options.Builder().option1("firefox").option2(1).build();
        Options optionsVariation2 = new Options.Builder().option1("chrome").option2(2).build();

    }
}

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

রক্ষণাবেক্ষণের এই উন্নতির সত্যিই কি কোনও খারাপ দিক রয়েছে? একটি কারণ থাকতে হবে যা তিনি নীড় শ্রেণীর মধ্যে থাকা বৈশিষ্ট্যগুলি পুনরাবৃত্তি করেছিলেন যা আমি দেখছি না?


এটি খুবই C # রচয়িতা প্যাটার্ন আমার নিন অনুরূপ বলে মনে হয় এখানে
ম্যাটডেভি

উত্তর:


12

আপনার প্রকরণটি বেশ সুন্দর। তবে এটি ব্যবহারকারীদের এটি করতে দেয়:

Options.Builder builder = new Options.Builder().option1("firefox").option2(1);
Options optionsVariation1 = builder.build();
assert optionsVariation1.getOption1().equals("firefox");
builder.option1("chrome");
assert optionsVariation1.getOption1().equals("firefox"); // FAILURE!

যা বরং বস্তুকে পরাস্ত করে।

এটি buildকরার জন্য আপনি পদ্ধতিটি পরিবর্তন করতে পারেন:

public Options build() {
    Options options = this.options;
    this.options = null;
    return options;
}

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


1
আমি 2nd লাইন পরিবর্তন হবে build()না: this.options = new Options();। এইভাবে, বিকল্পগুলির দৃষ্টান্তগুলি নিরাপদে অপরিবর্তনীয় হবে, এবং একই সাথে নির্মাতা পুনরায় ব্যবহারযোগ্য হবে।
ন্যাটিক্স

5

"বেশিরভাগ ক্ষেত্রে" একইরকম অবজেক্ট তৈরি করতে ব্লচের ধাঁচে নির্মাতা বহুবার ব্যবহৃত হতে পারে। অতিরিক্তভাবে, অপরিবর্তনীয় অবজেক্টস (সমস্ত ক্ষেত্র চূড়ান্ত এবং তারা অপরিবর্তনীয়) থ্রেড সুরক্ষা সুবিধা রয়েছে যা আপনার পরিবর্তনগুলি পরাজিত করতে পারে।


0

যদি বিকল্পগুলি কার্যকরভাবে ক্লোনযোগ্য হয় (তবে ক্লোনযোগ্য ইন্টারফেস নির্বিশেষে), আপনি প্রোটোটাইপ প্যাটার্ন ব্যবহার করতে পারেন - বিল্ডারে একটি থাকুন এবং এটি বিল্ডে ক্লোন করুন ()।

আপনি যদি ক্লোনযোগ্য ইন্টারফেস ব্যবহার না করেন তবে আপনাকে প্রতিটি ক্ষেত্রটি অনুলিপি করতে হবে, যাতে এটি যুক্ত করার দরকার হলে এটি অন্য কোনও জায়গা যুক্ত করতে পারে, তাই কমপক্ষে কমপক্ষে সাধারণ ক্ষেত্রগুলির জন্য ক্লোনেবল ব্যবহার করে যথাযথভাবে ধারণা করা ভাল good

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