কোনও শ্রেণির পদ্ধতিগুলি কি তার নিজস্ব গেটার এবং সেটটারদের কল করতে পারে?


53

আমি যেখানে কাজ করি সেখানে প্রচুর ক্লাস দেখতে পাই যা এই জাতীয় কাজ করে:

public class ClassThatCallsItsOwnGettersAndSetters {

    private String field;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public void methodWithLogic() {
        setField("value");
        //do stuff
        String localField = getField();
        //do stuff with "localField"
    }
}

আমি যদি এটি স্ক্র্যাচ থেকে লিখি তবে methodWithLogic()পরিবর্তে আমি এ জাতীয়টিই লিখতে চাইতাম :

public class ClassThatUsesItsOwnFields {

    private String field;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public void methodWithLogic() {
        field = "value";
        //do stuff            
        //do stuff with "field"
    }
}

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

প্রথম পদ্ধতিতে কি সুবিধা রয়েছে? প্রথম পদ্ধতিটি কি আসলে আরও ভাল?


আমি যখন কিছু অপরিচিত কোডটি ডিবাগ করছি, তখন কে বলবে যে সেই পদ্ধতিতে বাগ কোনও পার্শ্ব প্রতিক্রিয়া নয়? আপনার ইউনিট পরীক্ষা। :)
জোশুয়া টেলর

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

উত্তর:


46

আমি কোনটি ভাল বা খারাপ এটি বলব না, কারণ এটি আংশিকভাবে আপনার পরিস্থিতির উপর নির্ভর করে (আমার মতে)। তবে বিবেচনা করুন যে আপনার গ্রাহকরা এবং সেটটারগুলি পরে বাস্তবায়ন পরিবর্তন করতে পারে এবং এগুলিকে বাইপাস করলে সেই যুক্তিটি এড়ানো যাবে।

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


তবে আপনি যখন ব্যাকএন্ডে ডেটা শুরু করছেন এবং আপনি কী চান না যে এটি নোংরা হিসাবে ব্যাখ্যা করা উচিত। আপনি যদি setField()প্রথম থেকেই কল করেন তবে আপনি কেবল একটি বাগ প্রবর্তন করেছেন।
ড্যানিয়েল ক্যাপলান

6
ঠিক তাই, আমি বলি এটি আংশিকভাবে পরিস্থিতির উপর নির্ভর করে। হতে পারে আপনার ডেটা ইনিশিয়ালেশনের সেটটারগুলি এড়িয়ে যাওয়া উচিত, তবে অন্যান্য লজিকাল কোডটি করা উচিত নয়। উপযুক্ত যে নিয়ম চয়ন করুন এবং এর সাথে আঁকুন।
ম্যাট এস

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

33

সেটারকে সরাসরি কল করা কোনও সমস্যা এবং নিজেই নয়। প্রশ্নটি আসলেই হওয়া উচিত: কেন আমাদের কোডে সব জায়গায় সেটটার রয়েছে?

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

যদি ক্ষেত্রটি অবশ্যই বাহ্যিকভাবে স্থায়ীভাবে স্থাপন করতে হয় তবে নিজেকে জিজ্ঞাসা করুন যুক্তিযুক্ত পদ্ধতিটি সেখানে থাকা উচিত কিনা। আপনার শ্রেণি নিজেই কি কেবল একটি ডেটা / রাজ্য শ্রেণি? এই শ্রেণীর একাধিক দায়িত্ব আছে কি?

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


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

@ ড্যানিয়েলক্যাপলান: আমি ঠিক তা-ই বলছি। :) আমি উত্তর দিয়েছিলাম এবং এইটির সাথে মন্তব্যের মধ্যে ছিঁড়েছিলাম, তবে আমি সত্যিকার অর্থে অনুভব করি না যে একটি সঠিক উত্তর আছে যা বড় প্রশ্ন জিজ্ঞাসা করে না।
পিডিআর

9

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


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

1
@ ড্যানিয়েলক্যাপলান আমার বক্তব্যটি হ'ল কারণগুলি এক এবং একই। এটি যদি আপনি পরে সেটার যুক্তি যুক্ত করেন তবে এটি অভ্যন্তরীণ কোডকে বহিরাগতের মতোই প্রভাবিত করে।
মাইকেল 22

2
@ মিশেল: ক্লাসের নিজস্ব গেটার / সেটটার ব্যবহার না করার জন্য প্রায়শই ভাল কারণ থাকতে পারে। একটি সাধারণ পরিস্থিতি হ'ল যেখানে ফর্মের অনেকগুলি সেটটার রয়েছে someField=newValue; refresh(); যদি পদ্ধতি একাধিক ক্ষেত্র সেট করার অনুমতি দেয় তবে সেটারগুলিতে সেটিংগুলি কল করতে কল্পনাগুলি রিডানড্যান্ট "রিফ্রেশ" ক্রিয়াকলাপ ঘটায়। সমস্ত ক্ষেত্র লেখা এবং তারপরে refresh()একবার কল করা আরও দক্ষ এবং মসৃণ চেহারার ক্রিয়াকলাপ অর্জন করতে পারে।
সুপারক্যাট

6

আপনার প্রশ্নের উত্তর এক কথায় দিতে, হ্যাঁ।

একটি শ্রেণি থাকার কারণে তার নিজস্ব গেটার এবং সেটটারগুলি এক্সটেনসিবিলিটি যুক্ত করে এবং ভবিষ্যতের কোডের জন্য আরও ভাল বেস সরবরাহ করে।

বলুন আপনার কাছে এরকম কিছু রয়েছে:

public class Vehicle
{
    private int year;
    private String make;

    public Vehicle(int year, String make)
    {
        setYear(year);
        setMake(make);
    }

    public void setYear(int year)
    {
        this.year = year;
    }

    public void setMake(String make)
    {
        this.make = make;
    }
}

বছরের জন্য সেটারগুলিকে কল করা এবং বর্তমানে করা কোনও কার্যকারিতা যুক্ত নাও করতে পারে তবে আপনি যদি সেটারগুলিতে ইনপুট বৈধতার মতো কিছু যুক্ত করতে চান তবে কি হবে?

public class Vehicle
{
    private int year;
    private String make;

    public Vehicle(int year, String make)
    {
        setYear(year);
        setMake(make);
    }

    public void setYear(int year)
    {
        if(year > 0)
        {
            this.year = year;
        }
        else
        {
            System.out.println(year + " is not a valid year!");
        }
    }

    public void setMake(String make)
    {
        this.make = make;
    }
}

5

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


3

আপনি যদি সর্বজনীন ইন্টারফেস দ্বারা সরবরাহিত কোনও কিছু সম্পাদন করার চেষ্টা করছেন, তবে গেটার / সেটার ব্যবহার করুন।

তবে, শ্রেণীর মালিক / বিকাশকারী হিসাবে, আপনাকে আপনার কোডের ব্যক্তিগত বিভাগগুলি অ্যাক্সেস করার অনুমতি দেওয়া হয়েছে (অবশ্যই শ্রেণীর মধ্যে থেকেই) তবে আপনি ঝুঁকিগুলি হ্রাস করার জন্যও দায়বদ্ধ।

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

public class MyClass
{
    private int i;
    private List<string> list;
    public string getNextString()
    {
        i++;
        return list[i];
    }

    private void getString()
    {
        // Do not increment
        string currentString = list[i];

        // Increment
        string nextString = getNextString();
    }
}

আপনি কি এর জন্য যুক্তি দিতে পারেন?
ড্যানিয়েল ক্যাপলান

1

হ্যাঁ. গেটার্স এবং সেটটাররা রাষ্ট্রের প্রতিনিধিত্ব করে, সুতরাং এই প্রশ্নটি ঘুরিয়ে দিন - আপনি কি না চাইলে কোনও জিনিস অবধি একইভাবে পরিবর্তন করার একাধিক উপায়ের ট্র্যাক রাখতে চান?

আপনার যত কম জিনিস ট্র্যাক রাখতে হবে - এজন্য অপরিবর্তনীয় জিনিসগুলি মোকাবেলা করা সহজ।

বিবেচনা করুন, আপনাকে সর্বজনীন ক্ষেত্র এবং পাবলিক গেটার / সেটার উভয়ই হতে বাধা দিচ্ছে না - তবে আপনি কী অর্জন করবেন?

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


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

@ ড্যানিয়েলক্যাপলান: আমি এটি বুঝতে পেরেছি এবং আমি যা বলছি তা হ'ল বাস্তব হিসাবে আপনারা তাদের সাথে একই আচরণ করা উচিত।
jmoreno

@ ড্যানিয়েলক্যাপলান: আপনার একটি বেসরকারী সেটার এবং একটি পাবলিক সেটার থাকতে পারে, কমপক্ষে মুহুর্তের জন্য একই ফলাফল (সমস্ত পার্শ্ব প্রতিক্রিয়া একই) হতে পারে তবে জিনিসগুলি অপসারণের সম্ভাবনা বাদে আর কী লাভ হবে? এই দৃশ্যের এবং আপনি যা বর্ণনা করছেন তার মধ্যে পার্থক্য হ'ল আপনি গেটার / সেটটারগুলির বাইরে রাজ্যে অ্যাক্সেস করতে সক্ষম হওয়া এড়াতে পারবেন না , তবে আপনি বাস্তবে এটি এড়াতে পারবেন। আপনার কোডটি জটিল না করুন যদি না আপনার প্রয়োজন হয়।
jmoreno

1

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

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


1

আমি বলব না ..

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

জেভিএম গ্রাহকরা / সেটটারগুলিতে ঘন ঘন কলগুলি ইনলাইন করবে। সুতরাং, এটি কখনই কোনও পারফরম্যান্স ইস্যু নয়। ভেরিয়েবলগুলি ব্যবহার করার সুবিধাটি পঠনযোগ্যতা এবং আইএমএইচও, আমি এটির জন্য যাব।

আশাকরি এটা সাহায্য করবে..

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