কনস্ট্রাক্টর বা সেটার পদ্ধতি ব্যবহার করবেন?


16

আমি একটি ইউআই কোড নিয়ে কাজ করছি যেখানে আমার Actionক্লাস রয়েছে, এরকম কিছু -

public class MyAction extends Action {
    public MyAction() {
        setText("My Action Text");
        setToolTip("My Action Tool tip");
        setImage("Some Image");
    }
}

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

public class MyAction extends Action {
    public MyAction(String actionText) {
        setText(actionText);
        setTooltip("My Action tool tip"); 
        setImage("My Image"); 
    }
}

তিনি অবশ্য মনে করেন যেহেতু setText()পদ্ধতিটি বেস শ্রেণীর অন্তর্গত, যেখানেই অ্যাকশন উদাহরণ তৈরি করা হয়েছে সেখানে এটি অ্যাক্সেস টেক্সট পাস করার জন্য নমনীয়ভাবে ব্যবহার করা যেতে পারে। এইভাবে, বিদ্যমান MyActionশ্রেণিটি পরিবর্তন করার দরকার নেই । সুতরাং তার কোডটি দেখতে এরকম কিছু হবে।

MyAction action = new MyAction(); //this creates action instance with the hardcoded text
action.setText("User required new action text"); //overwrite the existing text.

সমস্যাটি মোকাবেলার জন্য যদি এটি সঠিক উপায় হয় তবে আমি নিশ্চিত নই। আমি মনে করি উপরে বর্ণিত কেসটিতে ব্যবহারকারী যেভাবেই টেক্সট পরিবর্তন করতে চলেছে, তাই অ্যাকশনটি নির্মাণের সময় কেন তাকে জোর করবেন না? মূল কোডটি দিয়ে আমি কেবল উপকারটি দেখছি যে ব্যবহারকারী পাঠ্য নির্ধারণের বিষয়ে বেশি চিন্তা না করে অ্যাকশন শ্রেণি তৈরি করতে পারে।


1
আপনি যে ভাষাটি ব্যবহার করছেন সেটি কি ওভারলোডিং নির্মাণকারীর অনুমতি দেয় না?
মাদুর

1
আমি জাভা ব্যবহার করছি। সুতরাং হ্যাঁ, এটির অনুমতি দেয় এবং আমি মনে করি এটি মোকাবেলা করার এক উপায় হতে পারে
zwwap

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

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

উত্তর:


15

মূল কোডটি দিয়ে আমি কেবল উপকারটি দেখছি যে ব্যবহারকারী পাঠ্য নির্ধারণের বিষয়ে বেশি চিন্তা না করে অ্যাকশন শ্রেণি তৈরি করতে পারে।

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

আমি সামনে দুটি পরিষ্কার পথ দেখতে পাচ্ছি:

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

10

কনস্ট্রাক্টর ওভারলোডিং এখানে একটি সহজ এবং সোজা সমাধান হতে পারে:

public class MyAction extends Action {
    public MyAction(String actionText) {
        setText(actionText);
        setTooltip("My Action tool tip"); 
        setImage("My Image"); 
    }
    public MyAction() {
        this("My Action Text");
    }
}

এটি .setTextপরে কল করার চেয়ে ভাল , কারণ এইভাবে কোনও কিছুই ওভাররাইট করার দরকার নেই, actionTextশুরু থেকেই উদ্দেশ্যযুক্ত জিনিস হতে পারে।

আপনার কোডটি বিকশিত হওয়ার সাথে সাথে আপনার আরও নমনীয়তার প্রয়োজন হবে (যা অবশ্যই ঘটবে), আপনি অন্য উত্তর দ্বারা প্রস্তাবিত কারখানা / বিল্ডার প্যাটার্ন থেকে উপকৃত হবেন।


তারা যখন দ্বিতীয় সম্পত্তিটি কাস্টমাইজ করতে চায় তখন কী ঘটে?
কেভিন ক্লাইনে

3
২ য়, ৩ য়, .. সম্পত্তিগুলির জন্য, আপনি একই কৌশলটি প্রয়োগ করতে পারেন, তবে আপনি যত বেশি বৈশিষ্ট্য কাস্টমাইজ করতে চান, এটি তত বেশি অনাবশ্যক হয়ে যায়। এক পর্যায়ে কারখানা / বিল্ডার প্যাটার্ন বাস্তবায়নের জন্য এটি আরও অর্থবোধ তৈরি করবে, পাশাপাশি উত্তরটি দিয়ে @ মাইকেল-কোজরলিং বলেছেন।
janos

6

একটি সাবলীল 'সেটটেক্সট' পদ্ধতি যুক্ত করুন:

public class MyAction ... {
  ...
  public MyAction setText(String text) { ... ; return this; }
}

MyAction a = new MyAction().setText("xxx");

এর থেকে পরিষ্কার আর কী হতে পারে? আপনি যদি অন্য কাস্টমাইজযোগ্য সম্পত্তি যুক্ত করার সিদ্ধান্ত নেন তবে কোনও সমস্যা নেই।


+1, আমি সম্মত হই এবং আরও সম্পত্তি যুক্ত করে অন্য একটি উত্তর যুক্ত করেছি। আমি মনে করি আপনার যখন উদাহরণ হিসাবে 1 টিরও বেশি একক সম্পত্তি থাকবে তখন প্রবাহিত এপিআই আরও স্পষ্ট।
মাচাডো

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

1

ঠিক যেমন কেভিন স্লাইন তার উত্তরে বলেছিল, আমার মনে হয় যাওয়ার পথটি একটি সাবলীল এপিআই তৈরি করা । আমি কেবল যুক্ত করতে চাই যে আপনার যখন একাধিক সম্পত্তি ব্যবহার করতে পারেন তখন ফ্লুয়েন্ট এপিআই আরও ভাল কাজ করে।

এটি আপনার কোডটি আরও পঠনযোগ্য এবং আমার দৃষ্টিকোণ থেকে আরও সহজ এবং আহম , "সেক্সি" লিখতে সক্ষম করবে।

আপনার ক্ষেত্রে এটি এরকম হবে (যে কোনও টাইপের জন্য দুঃখিত, আমি আমার শেষ জাভা প্রোগ্রামটি লিখেছি এক বছর হয়ে গেছে):

 public class MyAction extends Action {
    private String _text     = "";
    private String _tooltip  = "";
    private String _imageUrl = "";

    public MyAction()
    {
       // nothing to do here.
    }

    public MyAction text(string value)
    {
       this._text = value;
       return this;
    }

    public MyAction tooltip(string value)
    {
       this._tooltip = value;
       return this;
    }

    public MyAction image(string value)
    {
       this._imageUrl = value;
       return this;
    }
}

এবং ব্যবহারটি এরকম হবে:

MyAction action = new MyAction()
    .text("My Action Text")
    .tooltip("My Action Tool tip")
    .image("Some Image");

খারাপ ধারণা, তারা যদি পাঠ্য বা কোনও গুরুত্বপূর্ণ জিনিস সেট করতে ভুলে যায় তবে কী।
প্রখর

1

কনস্ট্রাক্টর বা বিল্ডারদের ব্যবহারের পরামর্শটি সাধারণভাবে ঠিক আছে, তবে আমার অভিজ্ঞতা অনুসারে অ্যাকশনের জন্য কিছু মূল বিষয় মিস করেছে, যা

  1. সম্ভবত আন্তর্জাতিককরণের প্রয়োজন
  2. শেষ মুহুর্তে বিপণনের পরিবর্তন হওয়ার সম্ভাবনা রয়েছে।

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

File.open.name=Open
File.open.tooltip=Open a file
File.open.icon=somedir/open.jpg

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

এটি কেবল একটি মোটামুটি রূপরেখা, পাঠকের কাছে অনেক কিছুই বাকী রয়েছে ... ইন্টার্নেশনের অন্যান্য উদাহরণ দেখুন Look


0

কনস্ট্রাক্টরের অভ্যন্তরে সেটটেক্সট (অ্যাকশনটেক্সট) বা সেটটুলটিপ ("আমার অ্যাকশন সরঞ্জামের টিপ") কল করা অযথা; এটি সহজ (এবং আপনি আরও বেশি পারফরম্যান্স অর্জন করতে পারেন) যদি আপনি কেবল সংশ্লিষ্ট ক্ষেত্রটি সরাসরি সরাসরি শুরু করেন:

    public MyAction(String actionText) {
        this.actionText = actionText;
    }

আপনি যদি MyAction সম্পর্কিত অবজেক্টের লাইফ টাইমের সময় অ্যাকশনটেক্সট পরিবর্তন করেন তবে আপনার একটি সেটার পদ্ধতি স্থাপন করা উচিত; যদি কোনও সেটার পদ্ধতি না দিয়ে কেবল কনস্ট্রাক্টারে ক্ষেত্রটি আরম্ভ না করে।

যেহেতু টুলটিপ এবং চিত্রটি ধ্রুবক, তাই তাদের ধ্রুবক হিসাবে গণ্য করুন; ক্ষেত্র আছে:

private (or even public) final static String TOOLTIP = "My Action Tooltip";

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


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

0

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


আমি মনে করি ওভারলোডেড কনস্ট্রাক্টরের এখনও সমস্যাটি সমাধান করা উচিত। সমস্ত "10%" ক্ষেত্রে, আপনি প্রথমে ডিফল্ট পাঠ্য সহ একটি ক্রিয়া তৈরি করবেন এবং তারপরে "সেটটেক্সট ()" পদ্ধতিটি ব্যবহার করে ক্রিয়া পাঠ্য পরিবর্তন করবেন। ক্রিয়াটি নির্মাণের সময় কেন উপযুক্ত পাঠ্য সেট করা হয় না।
zswap

0

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

উদাহরণস্বরূপ, যদি মায়াকশন ক্লাসটি নির্মাণের পরে (এবং সম্ভবত অন্য সূচনা) অপরিবর্তনীয় বলে মনে করা হয়, তবে এটির সেটার পদ্ধতি থাকা উচিত নয়। যদি বেশিরভাগ সময় এটি ডিফল্ট "মাই অ্যাকশন পাঠ্য" ব্যবহার করে, সেখানে প্যারামিটারলেস কনস্ট্রাক্টর, প্লাস এমন একটি কনস্ট্রাক্টর থাকতে হবে যা একটি alচ্ছিক পাঠ্যকে অনুমতি দেয়। এখন ব্যবহারকারীর 90% সময় সঠিকভাবে ক্লাসটি ব্যবহার করার কথা ভাবার দরকার নেই। ব্যবহারকারী সাধারণত তাহলে কর্তব্য টেক্সট কিছু চিন্তার দিতে parameterless কন্সট্রাকটর লাফালাফি। এখন ব্যবহারকারী যখন প্রয়োজন তখন ভাবতে বাধ্য হয় এবং প্রয়োজনীয় পদক্ষেপটি উপেক্ষা করতে পারে না।

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

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


0

নিম্নলিখিত প্রস্তাবিত সমাধানে, সুপারক্লাস বিমূর্ত এবং তিনটি সদস্যই একটি ডিফল্ট মান হিসাবে সেট করেছেন।

সাবক্লাসে আলাদা আলাদা কনস্ট্রাক্টর রয়েছে যাতে প্রোগ্রামার এটি ইনস্ট্যান্ট করতে পারে।

যদি প্রথম কনস্ট্রাক্টর ব্যবহার করা হয় তবে সমস্ত সদস্যের ডিফল্ট মান থাকবে।

যদি দ্বিতীয় কনস্ট্রাক্টর ব্যবহার করা হয় তবে আপনি অ্যাকশনটেক্সট সদস্যকে একটি প্রাথমিক মান দেন অন্য দুটি সদস্যকে ডিফল্ট মান দিয়ে রেখে ...

যদি তৃতীয় কনস্ট্রাক্টর ব্যবহার করা হয় তবে আপনি এটিকে অ্যাকশনটেক্সট এবং টুলটিপের জন্য একটি নতুন মান দিয়ে ইনস্ট্যান্ট করবেন, ডিফল্ট মানের সাথে চিত্র url রেখে ...

ইত্যাদি।

public abstract class Action {
    protected String text = "Default action text";
    protected String toolTip = "Default action tool tip";
    protected String imageURl = "http://myserver.com/images/default.png";

    .... rest of code, I guess setters and getters
}

public class MyAction extends Action {


    public MyAction() {

    }

    public MyAction(String actionText) {
        setText(actionText);
    }

    public MyAction(String actionText, String toolTip_) {
        setText(actionText);
        setToolTip(toolTip_);   
    }

    public MyAction(String actionText, String toolTip_; String imageURL_) {
        setText(actionText);
        setToolTip(toolTip_);
        setImageURL(imageURL_);
    }


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