প্রাইভেট গেটারদের চেয়ে পাবলিক ফাইনাল ব্যবহার করা


51

আমি দেখতে পেলাম সবচেয়ে অপরিবর্তনীয় POJO গুলি:

public class MyObject {
    private final String foo;
    private final int bar;

    public MyObject(String foo, int bar) {
        this.foo = foo;
        this.bar = bar;
    }

    public String getFoo() {
        return foo;
    }

    public int getBar() {
        return bar;
    }
}

তবুও আমি তাদের এইভাবে লিখতে চাই:

public class MyObject {
    public final String foo;
    public final int bar;

    public MyObject(String foo, int bar) {
        this.foo = foo;
        this.bar = bar;
    }
}

উল্লেখ্য উল্লেখগুলি চূড়ান্ত, সুতরাং অবজেক্টটি এখনও অপরিবর্তনীয়। এটি আমাকে কম কোড লিখতে দেয় এবং সংক্ষিপ্ততর (5 টি অক্ষর দ্বারা: getএবং ()) অ্যাক্সেসের অনুমতি দেয়।

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

আমি কি কোন অসুবিধা মিস করছি?

সম্পাদনা

আমি মনে করি যে অন্য একটি অসুবিধা আমি হারিয়ে যাচ্ছি সেটি হ'ল সিরিয়ালাইজেশন লাইব্রেরিগুলি দিয়ে শুরু হওয়া পদ্ধতিগুলির প্রতিচ্ছবি getবা তার ব্যবহার শুরু করে isতবে এটি একটি দুর্দান্ত ভয়ঙ্কর অনুশীলন ...


কি খারাপ অবস্থা? finalকোনও পরিবর্তনশীল অবজেক্টটিকে পরিবর্তনযোগ্য করে তোলে না। আমি finalকলব্যাক তৈরির আগে আমি ক্ষেত্রগুলি সংজ্ঞায়িত করে এমন একটি নকশা ব্যবহার করি যাতে কলব্যাক সেই ক্ষেত্রগুলিতে অ্যাক্সেস করতে পারে। এটি অবশ্যই কোনও setXপদ্ধতি সহ সমস্ত পদ্ধতি কল করতে পারে ।
টমো জ্যাটো

@ TomášZato কোন setX পদ্ধতি আছে String, intঅথবা MyObject। প্রথম সংস্করণে finalকেবল ক্লাসের মধ্যে নির্মাণকারী ছাড়া অন্য পদ্ধতিগুলি চেষ্টা না করে তা bar = 7;নিশ্চিত করা example দ্বিতীয় সংস্করণে, finalকাজ করা থেকে ভোক্তাদের প্রতিরোধ প্রয়োজনীয়: MyObject x = new MyObject("hi", 5); x.bar = 7;
কোরি কেন্ডল

1
আচ্ছা আপনার " নোটগুলি উল্লেখগুলি চূড়ান্ত, সুতরাং এটি Objectএখনও অপরিবর্তনীয় " "বিভ্রান্তিকর - এমনভাবে মনে হয় যে আপনি মনে করেন যে কোনও final Objectপরিবর্তনযোগ্য, যা তা নয়। ভুল জন্য দুঃখিত.
টমো জাটো

3
যদি অন্তর্নিহিত মানগুলি পরিবর্তনযোগ্য হয় তবে ব্যক্তিগত + অ্যাক্সেসরগুলির রাস্তাও এটি আটকাতে পারে না - myObj.getFoo().setFrob(...)
বেনি চেরনিয়াভস্কি-পাসকিন

উত্তর:


38

চারটি অসুবিধা যা আমি ভাবতে পারি:

  1. আপনি যদি একই সত্তার পঠনযোগ্য এবং কেবল পরিবর্তনযোগ্য ফর্ম রাখতে চান তবে একটি সাধারণ প্যাটার্নে একটি অপরিবর্তনীয় শ্রেণি সত্তা থাকতে হবে যা সুরক্ষিত সদস্য ভেরিয়েবলগুলি সহ কেবলমাত্র অ্যাক্সেসরগুলিকেই প্রকাশ করে, তারপরে একটি মিউটটেইনটি তৈরি করুন যা এটি প্রসারিত করে এবং সেটটার যুক্ত করে। আপনার সংস্করণ এটি প্রতিরোধ করে।
  2. গেটার্স এবং সিটারগুলির ব্যবহার জাভাবীনের সম্মেলনে মেনে চলে। আপনি যদি জেএসটিএল বা ইএল এর মতো সম্পত্তি-ভিত্তিক প্রযুক্তিগুলিতে শিম হিসাবে আপনার শ্রেণিটি ব্যবহার করতে চান তবে আপনার পাবলিক গেটারদের প্রকাশ করতে হবে।
  3. আপনি যদি কখনও মানগুলি অর্জন করতে বা ডাটাবেসে সেগুলি সন্ধান করতে বাস্তবায়ন পরিবর্তন করতে চান তবে আপনাকে ক্লায়েন্ট কোডটি রিফেক্টর করতে হবে। অ্যাক্সেসর / মিউটর পদ্ধতির সাহায্যে আপনি কেবলমাত্র প্রয়োগটি পরিবর্তন করতে পারবেন।
  4. সর্বনিম্ন বিস্ময় - আমি যখন জনসাধারণের উদাহরণের পরিবর্তনশীলগুলি দেখি, তখনই আমি ততক্ষণে সন্ধান করি যে কে এটি পরিবর্তন করছে এবং চিন্তিত যে আমি পান্ডোরার বাক্সটি খুলছি কারণ এনক্যাপসুলেশন হারিয়ে গেছে। http://en.wikipedia.org/wiki/Principle_of_least_astonishment

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


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

2
৫) আপনি সহজাতভাবে পরিবর্তনযোগ্য শ্রেণি / প্রকারগুলি - অ্যারের মতো নিরাপদে প্রকাশ করতে পারবেন না। নিরাপদ উপায় হ'ল প্রতিবার একজন গেটের কাছ থেকে একটি অনুলিপি ফিরে আসা।
ক্লকওয়ার্ক-মিউজিক

@ ক্লকওয়ার্ক-মিউজিক আপনি পারবেন, যদি ধরে নেন লোকেরা বোকা না। SomeObj.thisList.add () এ অ্যাক্সেস করার সময় এটা স্পষ্ট হয় যে আপনি কিছু অন্যান্য অবজেক্টের স্থিতি পরিবর্তন করছেন। SomeObj.getThisList () দিয়ে যোগ করুন () এটি অজানা। আপনাকে ডকুমেন্টেশন জিজ্ঞাসা করতে হবে বা উত্সটি সন্ধান করতে হবে, তবে একমাত্র পদ্ধতি ঘোষণার মাধ্যমে এটি বলা অসম্ভব।
kritzikratzi

2
@ প্রকৃতিজিক্রতজি - সমস্যা হ'ল আপনি গ্যারান্টি দিতে পারবেন না যে আপনার কোড ইডিয়টস হিসাবে চলবে না। এক পর্যায়ে এটি হবে (যা এমনকি নিজের হয়ে উঠতে পারে!), এবং আশ্চর্য একটি বিশাল সমস্যা হতে পারে।
ক্লকওয়ার্ক-মিউজিক

1
ঠিক আছে, কোনও পরিবর্তনযোগ্য প্রকারকে অপরিবর্তনীয় টাইপের উত্তরাধিকার সূত্রে দেওয়া ভুলভাবে ভুল। মনে রাখবেন যে একটি অপরিবর্তনীয় ধরণের গ্যারান্টি দেয় "আমি কখনও পরিবর্তন করি না Ever"
উত্সাহক

26

ভিজিটর / সেটারগুলি থেকেও মুক্তি পান এবং আপনি ভাল আছেন!

এটি জাভা প্রোগ্রামারদের মধ্যে একটি অত্যন্ত বিতর্কিত বিষয়।

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

  1. সর্বজনীন চূড়ান্ত আমার কাছে এই সংকেতগুলি কেবলমাত্র একজন প্রাপ্তির চেয়ে অনেক ভাল I'm বেশিরভাগ আইডিই অটো-সমাপ্তির সময় 'এফ' দিয়ে চূড়ান্ত সংশোধককে নির্দেশ করবে। গিটার / সেটটারগুলির সাথে ভিন্ন নয়, যেখানে আপনাকে সেট এক্সএক্সএক্সএক্সের অনুপস্থিতি সন্ধান করতে হবে।
  2. সর্বজনীন অ চূড়ান্ত আমি ডেটা ক্লাসের জন্য এটি পছন্দ করি। আমি কেবল সমস্ত ক্ষেত্র প্রকাশ্যে প্রকাশ করি। কোনও গেটার, সেটটার, কনস্ট্রাক্টর নেই। না কিছুনা. পোজোর চেয়েও কম। আমার কাছে এটি তাত্ক্ষণিকভাবে ইঙ্গিত দেয় "দেখুন, আমি বোবা। আমি ডেটা ধরে রেখেছি, এটাই সব। আমার ভিতরে সঠিক তথ্য স্থাপন করা আপনার কাজ"। Gson / JAXB / ইত্যাদি। এই ক্লাস ঠিক ঠিক পরিচালনা করুন। তারা লিখতে পরিতোষ। তাদের উদ্দেশ্য বা ক্ষমতা সম্পর্কে কোনও সন্দেহ নেই। এবং সর্বাগ্রে গুরুত্বপূর্ণ: আপনি যখন জানেন যে কোনও পরিবর্তনশীল পরিবর্তন করবেন তখন কোনও পার্শ্ব প্রতিক্রিয়া নেই। IMHO এটি খুব সংক্ষিপ্ত বিবরণ সহ খুব সংক্ষিপ্ত ডেটা মডেলগুলির ফলাফল করে, যেখানে গেটার্স এবং সেটটারদের এই বিশাল সমস্যা হয় যেখানে কখনও কখনও যাদুগুলির মধ্যে ঘটে যায়।

5
কিছুক্ষণ একবারে কিছুটা স্যানিটি দেখে ভাল লাগল :)
নবীন

2
এমন দিন না আসা পর্যন্ত যেখানে আপনার মডেলটি বিকশিত হয় এবং পুরানো ক্ষেত্রগুলির একটি এখন অন্য থেকে নেওয়া যায়। যেহেতু আপনি পিছনের সামঞ্জস্য বজায় রাখতে চান তবে পুরানো ক্ষেত্রটি অবশ্যই রয়ে যাবে তবে কেবলমাত্র গেটর এবং সেটার কোড পরিবর্তন করার পরিবর্তে আপনাকে অন্য যে কোনও জায়গায় পরিবর্তন করতে হবে যেখানে এই পুরানো ক্ষেত্রটি নতুন মডেলের উপস্থাপনা অনুসরণ করে তা নিশ্চিত করার জন্য ব্যবহৃত হয়েছিল। সহজেই লিখতে হবে ... হ্যাঁ নিশ্চিত ... দীর্ঘকাল ধরে রাখার জন্য দুঃস্বপ্ন ... এজন্য আমাদের সি # সম্পত্তি অ্যাক্সেসরে আরও ভাল / সেটটার বা আরও ভাল রয়েছে।
নিউটোপিয়ান

9

সাধারণ মানুষের কথায়:

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

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

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

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

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

3
@ user949300 কোনটি আমাকে বলুন তাই আমি শিখতে পারি।
তুলাইনস কর্ডোভা

6

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

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