জাভা সংস্কৃতি সম্পর্কে প্রচুর পরিমাণে বলা যেতে পারে, তবে আমি মনে করি যে এই মুহূর্তে আপনার মুখোমুখি হচ্ছেন, সেখানে কয়েকটি উল্লেখযোগ্য দিক রয়েছে:
- লাইব্রেরির কোডটি একবার লেখা থাকলেও প্রায়শই ব্যবহৃত হয়। লাইব্রেরিটি লেখার ওভারহেড হ্রাস করতে খুব ভাল লাগলেও লাইব্রেরি ব্যবহারের ওভারহেডকে ছোট করে এমনভাবে লিখতে দীর্ঘমেয়াদে এটি সম্ভবত আরও সার্থক।
- এর অর্থ হ'ল স্ব-ডকুমেন্টিংয়ের ধরণগুলি দুর্দান্ত: পদ্ধতির নামগুলি এটি স্পষ্ট করতে সহায়তা করে যা ঘটছে এবং আপনি কোন বস্তু থেকে কী নিচ্ছেন।
- নির্দিষ্ট শ্রেণীর ত্রুটিগুলি দূর করার জন্য স্ট্যাটিক টাইপিং একটি খুব দরকারী সরঞ্জাম। এটি অবশ্যই সবকিছু সংশোধন করে না (লোকেরা হাস্কেল সম্পর্কে রসিকতা করতে পছন্দ করে যে একবার আপনার কোডটি গ্রহণ করার জন্য টাইপ সিস্টেমটি পেয়ে গেলে এটি সম্ভবত সঠিক)) তবে কিছু ধরণের ভুল জিনিসকে অসম্ভব করে দেওয়া খুব সহজ করে তোলে।
- গ্রন্থাগার কোড লিখন চুক্তি নির্দিষ্টকরণ সম্পর্কে। আপনার যুক্তি এবং ফলাফলের ধরণের জন্য ইন্টারফেসগুলি সংজ্ঞায়িত করা আপনার চুক্তির সীমানা আরও স্পষ্টভাবে সংজ্ঞায়িত করে। যদি কোনও জিনিস গৃহীত হয় বা একটি টিউপল উত্পন্ন করে, তবে এটি আসলেই বলা যায় না যে এটি আসলে যে ধরণের টুপল আপনার উচিত receive আপনি যে ধরণের প্রত্যাশা করেছিলেন সেগুলি?)।
ক্ষেত্রগুলি সহ "স্ট্রাক্ট" ক্লাস
অন্যান্য উত্তর যেমন উল্লেখ করেছে, আপনি কেবল সর্বজনীন ক্ষেত্র সহ একটি শ্রেণি ব্যবহার করতে পারেন। আপনি যদি এইগুলি চূড়ান্ত করেন তবে আপনি একটি অপরিবর্তনীয় শ্রেণি পেয়ে যাবেন এবং আপনি তাদের নির্মাণকারীর সাথে আরম্ভ করবেন:
class ParseResult0 {
public final long millis;
public final boolean isSeconds;
public final boolean isLessThanOneMilli;
public ParseResult0(long millis, boolean isSeconds, boolean isLessThanOneMilli) {
this.millis = millis;
this.isSeconds = isSeconds;
this.isLessThanOneMilli = isLessThanOneMilli;
}
}
অবশ্যই, এর অর্থ হ'ল আপনি একটি নির্দিষ্ট শ্রেণীর সাথে আবদ্ধ রয়েছেন এবং যে কোনও কিছু যা কখনও বিশ্লেষণের ফলাফল তৈরি বা গ্রাস করতে প্রয়োজন তা এই শ্রেণিটি ব্যবহার করতে হবে। কিছু অ্যাপ্লিকেশনগুলির জন্য, এটি ঠিক আছে। অন্যদের জন্য, এটি কিছু ব্যথা হতে পারে। অনেক জাভা কোড চুক্তিগুলি সংজ্ঞায়িত করার বিষয়ে এবং এটি আপনাকে সাধারণত ইন্টারফেসে নিয়ে যায়।
আরেকটি ক্ষতি হ'ল শ্রেণিভিত্তিক পদ্ধতির সাহায্যে আপনি ক্ষেত্রগুলি প্রকাশ করছেন এবং সেই ক্ষেত্রগুলির সকলেরই মান থাকতে হবে । উদাহরণস্বরূপ, ইসসেকেন্ডস এবং মিলিসের সর্বদা কিছুটা মূল্য থাকতে হবে, এমনকি যদি লেসথ্যানমিলি সত্য হয়। #LessThanOneMilli সত্য হলে মিলিস ক্ষেত্রের মানটির ব্যাখ্যাটি কী হওয়া উচিত?
ইন্টারফেস হিসাবে "স্ট্রাকচারস"
ইন্টারফেসে স্থির পদ্ধতি অনুমোদিত হওয়ার সাথে সাথে সিনট্যাকটিক ওভারহেডের পুরোটা ছাড়াই অপরিবর্তনীয় প্রকারগুলি তৈরি করা তুলনামূলকভাবে সহজ। উদাহরণস্বরূপ, আমি যে ধরণের ফলাফল কাঠামোর বিষয়ে কথা বলছি তা প্রয়োগ করতে পারি:
interface ParseResult {
long getMillis();
boolean isSeconds();
boolean isLessThanOneMilli();
static ParseResult from(long millis, boolean isSeconds, boolean isLessThanOneMill) {
return new ParseResult() {
@Override
public boolean isSeconds() {
return isSeconds;
}
@Override
public boolean isLessThanOneMilli() {
return isLessThanOneMill;
}
@Override
public long getMillis() {
return millis;
}
};
}
}
এটি এখনও প্রচুর বয়লারপ্লেট, আমি একেবারে একমত, তবে বেশ কয়েকটি সুবিধাও রয়েছে এবং আমি মনে করি সেগুলি আপনার মূল প্রশ্নের কয়েকটি উত্তর দেওয়া শুরু করে।
এই পার্স রেজাল্টের মতো কাঠামোর সাথে আপনার পার্সারের চুক্তিটি খুব স্পষ্টভাবে সংজ্ঞায়িত। পাইথনে, একটি টিপল অন্য টিপল থেকে সত্যই আলাদা নয়। জাভাতে, স্ট্যাটিক টাইপিং পাওয়া যায়, তাই আমরা ইতিমধ্যে কিছু শ্রেণীর ত্রুটিগুলিকে বাতিল করে দিয়েছি। উদাহরণস্বরূপ, আপনি যদি পাইথনে একটি টুপল ফিরিয়ে দিচ্ছেন এবং আপনি টিপলটি ফিরে পেতে (মিলিস, ইসসেকেন্ডস, আইস লেসথনঅনমিল্লি) চান তবে আপনি দুর্ঘটনাক্রমে এটি করতে পারেন:
return (true, 500, false)
যখন আপনি বোঝাতে চেয়েছিলেন:
return (500, true, false)
এই জাতীয় জাভা ইন্টারফেসের সাহায্যে আপনি সংকলন করতে পারবেন না:
return ParseResult.from(true, 500, false);
মোটেই তোমাকে করতে হবে:
return ParseResult.from(500, true, false);
সাধারণভাবে স্ট্যাটিক্যালি টাইপ করা ভাষার এটি একটি সুবিধা a
এই পদ্ধতির সাহায্যে আপনি কোন মানগুলি পেতে পারেন তা সীমাবদ্ধ করার ক্ষমতাও দেওয়া শুরু করে। উদাহরণস্বরূপ, getMillis () কল করার সময়, আপনি ISLessThanOneMilli () সত্য কিনা তা পরীক্ষা করে দেখতে পারেন এবং যদি এটি হয় তবে একটি ইলিজেলস্টেট এক্সেকশন (উদাহরণস্বরূপ) নিক্ষেপ করুন, যেহেতু সেই ক্ষেত্রে মিলিসের কোনও অর্থবহ মূল্য নেই।
ভুল কাজটি করা কঠিন করা
উপরের ইন্টারফেসের উদাহরণে, আপনার এখনও সমস্যা রয়েছে যে আপনি ঘটনাক্রমে আইসেকেন্ডগুলি এবং আইস লেসথ্যানঅনমিলি যুক্তিগুলি অদলবদল করতে পারেন, যদিও তাদের একই ধরনের রয়েছে।
অনুশীলনে, আপনি সত্যিই টাইমউনাইট এবং সময়কাল ব্যবহার করতে চাইতে পারেন, যাতে আপনার ফলাফল যেমন হয়:
interface Duration {
TimeUnit getTimeUnit();
long getDuration();
static Duration from(TimeUnit unit, long duration) {
return new Duration() {
@Override
public TimeUnit getTimeUnit() {
return unit;
}
@Override
public long getDuration() {
return duration;
}
};
}
}
interface ParseResult2 {
boolean isLessThanOneMilli();
Duration getDuration();
static ParseResult2 from(TimeUnit unit, long duration) {
Duration d = Duration.from(unit, duration);
return new ParseResult2() {
@Override
public boolean isLessThanOneMilli() {
return false;
}
@Override
public Duration getDuration() {
return d;
}
};
}
static ParseResult2 lessThanOneMilli() {
return new ParseResult2() {
@Override
public boolean isLessThanOneMilli() {
return true;
}
@Override
public Duration getDuration() {
throw new IllegalStateException();
}
};
}
}
এটি অনেক বেশি কোড হতে চলেছে তবে আপনাকে কেবল এটি একবার লিখতে হবে, এবং ( আপনার কোডটি সঠিকভাবে নথিভুক্ত করে ধরে নিয়েছেন), আপনার কোডটি ব্যবহার করে এমন লোকেরা ফলাফলটির অর্থ কী তা অনুমান করতে হবে না, এবং ঘটনাক্রমে result[0]
যখন বোঝাতে চাইছে তেমন কিছু করতে পারে না result[1]
। আপনি এখনও চমত্কারভাবে দৃষ্টান্তগুলি তৈরি করতে পারেন এবং সেগুলির মধ্যে থেকে ডেটা পাওয়া এতটা শক্ত নয়:
ParseResult2 x = ParseResult2.from(TimeUnit.MILLISECONDS, 32);
ParseResult2 y = ParseResult2.lessThanOneMilli();
নোট করুন যে আপনিও ক্লাস ভিত্তিক পদ্ধতির সাহায্যে এই জাতীয় কিছু করতে পারেন। বিভিন্ন ক্ষেত্রে কেবল কনস্ট্রাক্টর নির্দিষ্ট করুন। অন্য ক্ষেত্রগুলিতে কী কী শুরু করতে হবে তা এখনও আপনার কাছে রয়েছে এবং আপনি এগুলিতে অ্যাক্সেস আটকাতে পারবেন না।
আর একটি উত্তরে উল্লেখ করা হয়েছে যে জাভাটির এন্টারপ্রাইজ ধরণের প্রকৃতির অর্থ হ'ল আপনি ইতিমধ্যে বিদ্যমান অন্যান্য গ্রন্থাগারগুলি রচনা করছেন বা অন্য লোকেরা ব্যবহারের জন্য লাইব্রেরি লিখছেন। আপনার সার্বজনীন এপিআই-র এড়াতে যদি এড়ানো যায় তবে ফলাফলের ধরণের ব্যাখ্যা করতে ডকুমেন্টেশনের সাথে পরামর্শ করার জন্য প্রচুর সময় নেওয়া উচিত নয়।
আপনি কেবল এই কাঠামোগুলি একবার লিখেছেন , তবে আপনি এগুলি বহুবার তৈরি করেন, তাই আপনি এখনও সেই সংক্ষিপ্ত সৃষ্টিটি (যা আপনি পেয়েছেন) চান না। স্ট্যাটিক টাইপিং নিশ্চিত করে যে আপনি যে ডেটা বের করে আসছেন সেটিই আপনার প্রত্যাশা।
এখন, যা যা বলেছিল, এখনও এমন জায়গাগুলি রয়েছে যেখানে সাধারণ টিপলস বা তালিকাগুলি প্রচুর অর্থবোধ করতে পারে। কোনও কিছুর অ্যারে ফেরত দেওয়ার ক্ষেত্রে কম ওভারহেড থাকতে পারে, এবং যদি সে ক্ষেত্রে হয় (এবং সেই ওভারহেড তাৎপর্যপূর্ণ, যা আপনি প্রোফাইলের সাথে নির্ধারণ করেছেন), তবে অভ্যন্তরীণভাবে মানগুলির একটি সহজ অ্যারে ব্যবহার করে প্রচুর অর্থ হতে পারে। আপনার সার্বজনীন এপিআই তে সম্ভবত স্পষ্টভাবে সংজ্ঞায়িত প্রকারগুলি থাকা উচিত।