কেন কনস্ট্রাক্টরে সেটটার ব্যবহার করা সাধারণ প্যাটার্ন হয়ে উঠেনি?


23

অ্যাকসেসর এবং সংশোধক (ওরফে সেটটার এবং গেটার) তিনটি মূল কারণে কার্যকর:

  1. তারা ভেরিয়েবলগুলিতে অ্যাক্সেসকে সীমাবদ্ধ করে।
    • উদাহরণস্বরূপ, একটি ভেরিয়েবল অ্যাক্সেস করা যেতে পারে, তবে পরিবর্তিত হয়নি।
  2. তারা প্যারামিটারগুলি বৈধতা দেয়।
  3. তারা কিছু পার্শ্ব প্রতিক্রিয়া হতে পারে।

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

public class Cat {
    private int age;

    public int getAge() {
        return this.age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

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

/**
 * Sets the age for the current cat
 * @param age an integer with the valid values between 0 and 25
 * @return true if value has been assigned and false if the parameter is invalid
 */
public boolean setAge(int age) {
    //Validate your parameters, valid age for a cat is between 0 and 25 years
    if(age > 0 && age < 25) {
        this.age = age;
        return true;
    }
    return false;
}

তবে তারপরেও, আমি কখনই কোনও কনস্ট্রাক্টরের কাছ থেকে সংশোধককে কল করা দেখতে পাই না, তাই আমি যে সাধারণ শ্রেণির মুখোমুখি হচ্ছি তার মধ্যে সবচেয়ে সাধারণ উদাহরণ হ'ল:

public class Cat {
    private int age;

    public Cat(int age) {
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }

    /**
     * Sets the age for the current cat
     * @param age an integer with the valid values between 0 and 25
     * @return true if value has been assigned and false if the parameter is invalid
     */
    public boolean setAge(int age) {
        //Validate your parameters, valid age for a cat is between 0 and 25 years
        if(age > 0 && age < 25) {
            this.age = age;
            return true;
        }
        return false;
    }

}

তবে কেউ ভাবেন যে এই দ্বিতীয় পদ্ধতিটি অনেক বেশি নিরাপদ:

public class Cat {
    private int age;

    public Cat(int age) {
        //Use the modifier instead of assigning the value directly.
        setAge(age);
    }

    public int getAge() {
        return this.age;
    }

    /**
     * Sets the age for the current cat
     * @param age an integer with the valid values between 0 and 25
     * @return true if value has been assigned and false if the parameter is invalid
     */
    public boolean setAge(int age) {
        //Validate your parameters, valid age for a cat is between 0 and 25 years
        if(age > 0 && age < 25) {
            this.age = age;
            return true;
        }
        return false;
    }

}

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


1
@stg, আপনাকে ধন্যবাদ, আকর্ষণীয় পয়েন্ট! আপনি কি এটির প্রসার ঘটাতে এবং কোনও খারাপ জিনিসের উদাহরণ দিয়ে একটি উত্তরে রেখে দিতে পারেন যা ঘটতে পারে?
ভ্লাদ স্প্রে


8
@stg প্রকৃতপক্ষে, এটি কনস্ট্রাক্টরে অতিরিক্ত কর্মযোগ্য পদ্ধতি ব্যবহার করা একটি অ্যান্টি-প্যাটার্ন এবং অনেকগুলি কোড মানের সরঞ্জাম এটিকে ত্রুটি হিসাবে চিহ্নিত করবে। আপনি জানেন না যে ওভাররাইড করা সংস্করণটি কী করবে এবং এটি কন্সট্রাক্টর শেষ হওয়ার আগে "এই" পলায়ন করার মতো বাজে কাজ করতে পারে যা সমস্ত ধরণের অদ্ভুত সমস্যার কারণ হতে পারে।
মিচা কোসমুলস্কি

1
@ গ্যাनेट: আমি বিশ্বাস করি না এটি এটির একটি সদৃশ যা কোনও শ্রেণীর পদ্ধতিগুলি কি তার নিজস্ব গ্রাহক এবং সেটটারকে কল করতে পারে? , সম্পূর্ণরূপে তৈরি না হওয়া কোনও সামগ্রীতে কনস্ট্রাক্টর কলগুলির অনুরোধ জানানো হয়েছে।
গ্রেগ বার্গার্ড্ট

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

উত্তর:


37

খুব সাধারণ দার্শনিক যুক্তি

সাধারণত, আমরা জিজ্ঞাসা করি যে কোনও নির্মাণকারী (নির্মিত-শর্ত হিসাবে) নির্মিত অবজেক্টের অবস্থা সম্পর্কে কিছু গ্যারান্টি সরবরাহ করে।

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

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

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

নির্দিষ্ট উদাহরণ

  1. এটিকে আপনার কীভাবে দেখা উচিত বলে আপনার নিজের উদাহরণটি নিজেই ভুল:

    public Cat(int age) {
        //Use the modifier instead of assigning the value directly.
        setAge(age);
    }

    এটি থেকে ফেরতের মান চেক করে না setAge। স্পষ্টতই সেটারকে কল করা সর্বোপরি নির্ভুলতার কোনও গ্যারান্টি নয়।

  2. প্রারম্ভিক ক্রমের উপর নির্ভর করে খুব সহজ ভুল যেমন:

    class Cat {
      private Logger m_log;
      private int m_age;
    
      public void setAge(int age) {
        // FIXME temporary debug logging
        m_log.write("=== DEBUG: setting age ===");
        m_age = age;
      }
    
      public Cat(int age, Logger log) {
        setAge(age);
        m_log = log;
      }
    };

    যেখানে আমার অস্থায়ী লগিং সবকিছু ভেঙে দিয়েছে। উপস!

সি ++ এর মতো ভাষাও রয়েছে যেখানে কনস্ট্রাক্টর থেকে একটি সেটার কল করার অর্থ একটি নষ্ট ডিফল্ট সূচনা (যা কিছু সদস্য ভেরিয়েবলের জন্য অন্তত এড়ানো উচিত)

একটি সহজ প্রস্তাব

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

class Cat {
  private int m_age;
  private static void checkAge(int age) {
    if (age > 25) throw CatTooOldError(age);
  }

  public void setAge(int age) {
    checkAge(age);
    m_age = age;
  }

  public Cat(int age) {
    checkAge(age);
    m_age = age;
  }
};

বা আরও ভাল, যদি সম্ভব হয়: সম্পত্তি ধরণের ক্ষেত্রে সীমাবদ্ধতা এনকোড করুন এবং কার্যভারের ক্ষেত্রে এটির নিজস্ব মানটি বৈধকরণ করুন:

class Cat {
  private Constrained<int, 25> m_age;

  public void setAge(int age) {
    m_age = age;
  }

  public Cat(int age) {
    m_age = age;
  }
};

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

template <typename T, T MAX, T MIN=T{}>
class Constrained {
    T val_;
    static T validate(T v) {
        if (MIN <= v && v <= MAX) return v;
        throw std::runtime_error("oops");
    }
public:
    Constrained() : val_(MIN) {}
    explicit Constrained(T v) : val_(validate(v)) {}

    Constrained& operator= (T v) { val_ = validate(v); return *this; }
    operator T() { return val_; }
};

ঠিক আছে, এটি সত্যিই সম্পূর্ণ নয়, আমি বিভিন্ন অনুলিপি রেখেছি এবং কনস্ট্রাক্টর এবং অ্যাসাইনমেন্টগুলি রেখেছি।


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

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

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

13

যখন কোনও বস্তুটি নির্মাণ করা হচ্ছে, এটি সংজ্ঞায়িতভাবে সম্পূর্ণরূপে গঠিত হয় না। আপনি কীভাবে সেটার সরবরাহ করেছেন সেটিকে বিবেচনা করুন:

public boolean setAge(int age) {
    //Validate your parameters, valid age for a cat is between 0 and 25 years
    if(age > 0 && age < 25) {
        this.age = age;
        return true;
    }
    return false;
}

যদি বৈধতার অংশটিতে সম্পত্তিটির setAge()বিরুদ্ধে কোনও চেক অন্তর্ভুক্ত করা ageহয় তবে তা নিশ্চিত করতে হবে যে অবজেক্টটি কেবল বয়স বাড়তে পারে? এই অবস্থাটি দেখতে দেখতে পারে:

if (age > this.age && age < 25) {
    //...

এটি দেখতে বেশ নিরীহ পরিবর্তনের মতো বলে মনে হচ্ছে, কারণ বিড়ালরা কেবল সময়ের মধ্য দিয়ে এক দিকে যেতে পারে। একমাত্র সমস্যা হ'ল আপনি এটির প্রাথমিক মান সেট করতে ব্যবহার করতে পারবেন না this.ageকারণ এটি ধরে নিয়েছে যে this.ageইতিমধ্যে একটি বৈধ মান রয়েছে।

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


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

কোনও সমস্যা নেই, যেমন জাভা / সি # তে সমস্ত ক্ষেত্র নির্মাতা-প্রার্থনার আগে শূন্য।
ডিডুকিপেটর

2
হ্যাঁ, কনস্ট্রাক্টরদের কাছ থেকে কল করার উদাহরণগুলি সম্পর্কে যুক্তিযুক্ত হতে পারে এবং এটি সাধারণত পছন্দ হয় না। এখন, আপনি যদি নিজের বৈধতা যুক্তিটিকে একটি ব্যক্তিগত, চূড়ান্ত শ্রেণি / স্থির পদ্ধতিতে সরিয়ে নিতে চান এবং এটি কনস্ট্রাক্টর এবং সেটার উভয়ের কাছ থেকে কল করতে পারেন তবে তা ঠিক আছে be
3145

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

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

6

এখানে ইতিমধ্যে কিছু ভাল উত্তর রয়েছে, তবে এখনও অবধি কেউই খেয়াল করেনি আপনি এখানে দুটি বিষয়ে জিজ্ঞাসা করছেন যা কিছু বিভ্রান্তির কারণ হয়ে দাঁড়িয়েছে। আপনার পোস্টটি সেরা দুটি পৃথক প্রশ্ন হিসাবে দেখা হয় :

  1. যদি কোনও সেটারে কোনও বাধার বৈধতা থাকে, তবে এটিও বাইপাস করা যায় না তা নিশ্চিত করার জন্য এটি কি ক্লাসের নির্মাতার মধ্যে থাকা উচিত নয়?

  2. কেন কনস্ট্রাক্টরের কাছ থেকে এই উদ্দেশ্যে সিটারকে সরাসরি কল করা হবে না?

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

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


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

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

ঠিক আছে, আমি এখন আরও কম বিশ্বাস করছি! তবে, আমাকে অন্য উত্তরের দিকে নির্দেশ করার জন্য ধন্যবাদ ...
এসভিডজেন

2
দ্বারা একটি যুক্তিসঙ্গত অনুক্রমে আপনি কি বলতে চান একটি ভঙ্গুর সঙ্গে, অদৃশ্য ক্রম নির্ভরতা সহজে নির্দোষ সুদর্শন পরিবর্তন দ্বারা ভাঙ্গা , ডান?
অচল

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

2

এখানে জাভা কোডের একটি নির্বোধ বিট যা আপনার নির্মাতার অ চূড়ান্ত পদ্ধতি ব্যবহার করে আপনি যে ধরণের সমস্যাগুলি চালাতে পারেন তা প্রদর্শন করে:

import java.util.regex.Pattern;

public class Problem
{
  public static final void main(String... args)
  {
    Problem problem = new Problem("John Smith");
    Problem next = new NextProblem("John Smith", " ");

    System.out.println(problem.getName());
    System.out.println(next.getName());
  }

  private String name;

  Problem(String name)
  {
    setName(name);
  }

  void setName(String name)
  {
    this.name = name;
  }

  String getName()
  {
    return name;
  }
}

class NextProblem extends Problem
{
  private String firstName;
  private String lastName;
  private final String delimiter;

  NextProblem(String name, String delimiter)
  {
    super(name);

    this.delimiter = delimiter;
  }

  void setName(String name)
  {
    String[] parts = name.split(Pattern.quote(delimiter));

    this.firstName = parts[0];
    this.lastName = parts[1];
  }

  String getName()
  {
    return firstName + " " + lastName;
  }
}

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

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

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


খারাপভাবে বাস্তবায়িত উত্তরাধিকারের সমস্যার পরিবর্তে কনস্ট্রাক্টরে সেটটার ব্যবহার করার এটি কীভাবে ??? অন্য কথায়, যদি আপনি কার্যকরভাবে বেস কনস্ট্রাক্টরকে অবৈধ করে দিচ্ছেন তবে আপনি কেন এটি কল করবেন !?
এসভিডজেন

1
আমি মনে করি যে বিন্দুটি হ'ল সেটারকে ওভাররাইড করা, কনস্ট্রাক্টরকে অবৈধ করা উচিত নয়।
ক্রিস ওহলার্ট 13

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

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

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

1

এটা নির্ভর করে!

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

যাইহোক , যদি কোনও নির্দিষ্ট সেটার (বা দুটি!) সাফল্যের সাথে সম্পাদন করতে পারে তার আগে অবজেক্টটি সাজানোর জন্য আপনার যদি জটিল অপারেশন করা দরকার হয় তবে সেটারটি ব্যবহার করবেন না।

এবং উভয় ক্ষেত্রে, পরীক্ষার মামলা আছে । আপনি যে পথে যাবেন তা নির্বিশেষে, যদি আপনার ইউনিট পরীক্ষা করা হয় তবে আপনার উভয় বিকল্পের সাথে সম্পর্কিত সমস্যাগুলি প্রকাশ করার ভাল সুযোগ থাকবে।


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

যদি আমার অনুমান করতে হয় তবে আমি একটি "ক্লিন কোড" মেমোটি মিস করেছি যা এমন কোনও নির্দিষ্ট বাগ সনাক্ত করেছে যা কোনও কনস্ট্রাক্টরে সেটটার ব্যবহার করে উত্পন্ন হতে পারে। তবে, আমার পক্ষে, আমি এই জাতীয় কোনও বাগের শিকার হই নি ...

সুতরাং, আমি যুক্তি দিয়ে বলছি যে এই বিশেষ সিদ্ধান্তটি পরিষ্কার এবং কৌতুকপূর্ণ হওয়ার দরকার নেই।

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