জাভা 8 এর ptionচ্ছিকটি যুক্তি হিসাবে ব্যবহার করা উচিত নয়


392

আমি অনেকগুলি ওয়েবসাইটে পড়েছি ptionচ্ছিকটি কেবলমাত্র রিটার্ন টাইপ হিসাবে ব্যবহার করা উচিত, এবং পদ্ধতি আর্গুমেন্টে ব্যবহার করা উচিত নয়। আমি এর যৌক্তিক কারণ খুঁজতে লড়াই করছি। উদাহরণস্বরূপ আমার কাছে লজিকের একটি টুকরা রয়েছে যার মধ্যে 2 টি alচ্ছিক পরামিতি রয়েছে। সুতরাং আমি মনে করি এটির মতো আমার পদ্ধতির স্বাক্ষরটি লিখতে হবে (সমাধান 1):

public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
    // my logic
}

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

public int calculateSomething(String p1, BigDecimal p2) {
    // my logic
}

বিকল্পভাবে আমি একটি ভাল ইন্টারফেস সরবরাহ করতে এবং এটি আরও সুস্পষ্ট p1 এবং p2 করতে alচ্ছিক (সমাধান 3) করতে আমার চারটি পাবলিক পদ্ধতির সাথে আমার পদ্ধতিটি প্রতিস্থাপন করতে পারি:

public int calculateSomething() {
    calculateSomething(null, null);
}

public int calculateSomething(String p1) {
    calculateSomething(p1, null);
}

public int calculateSomething(BigDecimal p2) {
    calculateSomething(null, p2);
}

public int calculateSomething(String p1, BigDecimal p2) {
    // my logic
}

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

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);

যদি সমাধান 2 ব্যবহার করা হয়, কলিং কোডটি দেখতে এরকম হবে:

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));

যদি সমাধান 3 প্রয়োগ করা হয়, আমি উপরের কোডটি ব্যবহার করতে পারি বা আমি নিম্নলিখিতটি ব্যবহার করতে পারি (তবে এটি উল্লেখযোগ্যভাবে আরও কোড):

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
    if (p2.isPresent()) {
        result = myObject.calculateSomething(p1, p2);
    } else {
        result = myObject.calculateSomething(p1);
    }
} else {
    if (p2.isPresent()) {
        result = myObject.calculateSomething(p2);
    } else {
        result = myObject.calculateSomething();
    }
}

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


16
আপনি যদি alsচ্ছিক ব্যবহার করেন তবে আপনাকে কী পরীক্ষা করতে হবে যে পরামিতি হিসাবে passedচ্ছিকটি পাস হয়েছে null?
বিজিকলপ

17
হ্যাঁ, তবে ভবিষ্যতে কোডটি বজায় রেখে অন্য কারও কাছে এটি স্পষ্ট হয়ে উঠবে যে প্যারামিটারটি খালি / নাল হতে পারে, তাই ভবিষ্যতে সম্ভাব্যভাবে একটি নাল পয়েন্টার ব্যতিক্রম এড়ানো হবে
নীল স্টিভেন্স

1
কি দারুন. নাল আর্গুমেন্ট একটি পদ্ধতিতে পাস হচ্ছে? এটি এত ভিজ্যুয়াল বেসিক। এটি কোন নীতি লঙ্ঘন করছে? এসআরপি (সম্ভবত) এটি অন্য একটি নীতিও লঙ্ঘন করেছে যার নাম আমাকে শৃঙ্খলাবদ্ধ করে কেবল তার কাজটি করার জন্য কোনও পদ্ধতি বা ফাংশনের জন্য প্রয়োজনীয় তথ্য কেবল পাস করার লাইনে।
আলোকিত

20
তাত্ত্বিকভাবে সম্ভবত বাতিল হওয়া সমস্ত কিছু লাইব্রেরির প্রতিটি পদ্ধতির মতোই সম্ভবত System.exit (0) কল করে। আপনি টিআইএসের বিরুদ্ধে পরীক্ষা করতে পারবেন না এবং আপনার এটি পরীক্ষা করা উচিত নয়। বাস্তবে আপনার যা যা করা উচিত সবই (প্রায়) কখনই করা উচিত নয়। সমস্ত পরামিতি চূড়ান্ত করার মত। আপনার সরঞ্জামগুলিকে প্যারামিটারের মানগুলি পরিবর্তন করতে বা আপনার কোডটি হাজার ফাইনাল এবং অনেকগুলি নাল চেকের মাধ্যমে আপনার কোডটি অপঠনযোগ্য করার পরিবর্তে ক্ষেত্রগুলি আরম্ভ করতে ভুলে যেতে সহায়তা করতে দিন Let
ইয়োমন

6
প্রকৃতপক্ষে কেবল নননল / নালযোগ্য টীকাগুলি ব্যবহার করুন, এটি আপনি optionচ্ছিক নয়, এই পরিস্থিতিতে অনুসন্ধান করছেন।
বিল কে

উত্তর:


202

ওহ, এই কোডিং শৈলীগুলি কিছুটা লবণ দিয়ে নেওয়া উচিত।

  1. (+) কোনও অর্থগত বিশ্লেষণ ছাড়াই অন্য পদ্ধতিতে anচ্ছিক ফলাফল পাস করা; পদ্ধতি ছেড়ে যে, বেশ ঠিক আছে।
  2. (-) পদ্ধতিগুলির অভ্যন্তরে শর্তযুক্ত যুক্তি সৃষ্টিকারী paraচ্ছিক পরামিতিগুলি ব্যবহার করা আক্ষরিক অর্থে বিপরীত।
  3. (-) একটি ptionচ্ছিক মধ্যে একটি আর্গুমেন্ট প্যাক করা প্রয়োজন, সংকলক জন্য suboptimal, এবং একটি অপ্রয়োজনীয় মোড়ানো না।
  4. (-) অপ্রয়োজনীয় পরামিতিগুলির তুলনায় alচ্ছিক আরও ব্যয়বহুল।

সাধারণভাবে: alচ্ছিক দুটি রাজ্যকে একত্রিত করে, যা অবমুক্ত করাতে হবে। সুতরাং তথ্য প্রবাহের জটিলতার জন্য ইনপুট চেয়ে ফলাফলের জন্য আরও উপযুক্ত।


38
আসলে, একটি থাকার OptionalA: প্যারামিটার তিন রাজ্যের এক প্রতিনিধিত্ব করে nullঐচ্ছিক, একটি অ-নাল Optionalসঙ্গে isPresent() == falseএবং একটি অ-নাল Optionalএকটি প্রকৃত মূল্য মোড়কে।
বিজিকলপ

16
@ বিজিক্লপ হ্যাঁ, একটি অনিবার্য বিষয় ইতিমধ্যে সমালোচিত। তবে অভিপ্রায়টি কেবল নন-এক্সপ্রেশন মত প্রকাশের জন্য। এটি খুব বেশি সময় নেয়নি, কিছু ক্ষেত্রে ptionচ্ছিক এড়ানোর পরামর্শটি শুনতে যথেষ্ট ব্যঙ্গাত্মক। ক @NotNull Optional
জোপ এগেন

80
@ বিজিক্লপ নোট করুন যে আপনি যদি কিছুটা ব্যবহার Optionalকরেন তবে 1 স্টেটটি (ptionচ্ছিক null) সাধারণত একটি প্রোগ্রামিং ত্রুটির ইঙ্গিত দেয়, যাতে আপনি এটি পরিচালনাও করতে পারেন না (কেবল এটি ছুঁড়ে দিন NullPointerException)
ব্যবহারকারী 253751

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

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

165

সেরা পোস্ট আমি বিষয়ে দেখা করেছি দ্বারা লিখিত হয় ড্যানিয়েল Olszewski :

যদিও বাধ্যতামূলক পদ্ধতির পরামিতিগুলির জন্য ptionচ্ছিক বিবেচনা করার জন্য এটি লোভনীয় হতে পারে তবে অন্যান্য সম্ভাব্য বিকল্পের সাথে তুলনায় এই জাতীয় সমাধানটি ফ্যাকাশে। সমস্যাটি চিত্রিত করার জন্য, নিম্নলিখিত নির্মাণকারীর ঘোষণা পরীক্ষা করুন:

public SystemMessage(String title, String content, Optional<Attachment> attachment) {
    // assigning field values
}

প্রথম নজরে এটি একটি সঠিক ডিজাইনের সিদ্ধান্ত হিসাবে দেখাতে পারে। সর্বোপরি, আমরা স্পষ্টভাবে সংযুক্তি প্যারামিটারটিকে alচ্ছিক হিসাবে চিহ্নিত করেছি। তবে কনস্ট্রাক্টরকে কল করার ক্ষেত্রে ক্লায়েন্ট কোডটি কিছুটা আনাড়ি হতে পারে।

SystemMessage withoutAttachment = new SystemMessage("title", "content", Optional.empty());
Attachment attachment = new Attachment();
SystemMessage withAttachment = new SystemMessage("title", "content", Optional.ofNullable(attachment));

স্পষ্টতা দেওয়ার পরিবর্তে theচ্ছিক শ্রেণীর কারখানার পদ্ধতিগুলি কেবল পাঠককে বিভ্রান্ত করে। মনে রাখবেন একটি মাত্র oneচ্ছিক প্যারামিটার রয়েছে তবে দুটি বা তিনটি থাকার কথা কল্পনা করুন। চাচা বব অবশ্যই এই জাতীয় কোড of নিয়ে গর্ব করবেন না 😉

যখন কোনও পদ্ধতি alচ্ছিক পরামিতিগুলি গ্রহণ করতে পারে, তখন পদ্ধতিটি ওভারলোডিং ব্যবহার করে ভাল-প্রমাণিত পদ্ধতির অবলম্বন করা এবং এ জাতীয় কেস ডিজাইন করা ভাল। সিস্টেমমেসেস ক্লাসের উদাহরণে, দুটি পৃথক নির্মাতা ঘোষণা করা ptionচ্ছিক ব্যবহারের চেয়ে উচ্চতর superior

public SystemMessage(String title, String content) {
    this(title, content, null);
}

public SystemMessage(String title, String content, Attachment attachment) {
    // assigning field values
}

এই পরিবর্তনটি ক্লায়েন্ট কোডটি আরও সহজ এবং পড়তে সহজ করে তোলে।

SystemMessage withoutAttachment = new SystemMessage("title", "content");
Attachment attachment = new Attachment();
SystemMessage withAttachment = new SystemMessage("title", "content", attachment);

10
কেবলমাত্র এক বা দুটি অনুচ্ছেদ প্রাসঙ্গিক হলে এটি অনেকগুলি অনুলিপি + পেস্ট হয়।
গ্যারেট উইলসন

47
দুর্ভাগ্যক্রমে এই ব্যাখ্যাটি যখন কলকারী তখন উদ্বিগ্নতা বিবেচনা করে না কিছু উদাহরণ পার্স করা pচ্ছিক হতে পারে। মেথড ওভারলোডিং (উপরে প্রস্তাবিত হিসাবে) দিয়ে, কলিং কোডটি বলতে হবে, "এক্স উপস্থিত আছেন? যদি তাই হয় তবে আমি ওভারলোডেড পদ্ধতিটি কল করব। কি উপস্থিত আছে? আমাকে ওভারলোডেড পদ্ধতি বি কল করতে হবে বি এবং এক্স এবং ওয়াই উপস্থিত, আমাকে ওভারলোডেড পদ্ধতি সি কল করতে হবে। " ইত্যাদি। এর একটি ভাল উত্তর থাকতে পারে, তবে "কেন" এর এই ব্যাখ্যা এটি আবৃত করে না।
গ্যারেট উইলসন

9
এছাড়াও, যখন সংগ্রহগুলি আসে তখন খালি সংগ্রহ এবং কোনও সংগ্রহের মধ্যে আলাদা পার্থক্য থাকে। উদাহরণস্বরূপ, একটি ক্যাশে। এটি একটি ক্যাশে মিস ছিল? খালি alচ্ছিক / নাল। কোনও ক্যাশে হিট ছিল যা খালি সংগ্রহ হিসাবে দেখা দেয়? সম্পূর্ণ alচ্ছিক / সংগ্রহ।
আজাক্স

1
@ আজাক্স আমি মনে করি আপনি নিবন্ধটি ভুল বুঝছেন। তারা কার্যকর জাভা বইয়ের পক্ষ থেকে উক্ত পয়েন্টটির উদ্ধৃতি দিচ্ছে , যেখানে বলা হয়েছে যে যখন কোনও পদ্ধতি রিটার্ন টাইপ একটি সংগ্রহ (ক্যাশে হিসাবে কোনও স্বেচ্ছাচারিত বস্তু নয়) তখন আপনি nullবা এর পরিবর্তে খালি সংগ্রহ ফিরিয়ে আনার পক্ষে উচিত Optional
গিলি

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

86

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

কার্যকরী প্রোগ্রামিং ভাষা Optionalপ্যারামিটারগুলিকে উত্সাহ দেয় । এটি ব্যবহারের সর্বোত্তম উপায়গুলির মধ্যে একটি হ'ল একাধিক alliftM2 চ্ছিক পরামিতি থাকা এবং প্যারামিটারগুলি ধরে রেখে কোনও ফাংশন ব্যবহার করা খালি নয় এবং optionচ্ছিক ফিরে আসা (দেখুন http://www.functionaljava.org/javadoc/4.4/functionaljava/fj/ ডেটা / অপশন html # লিফটএম 2-এফজে.এফ- )। জাভা 8 দুর্ভাগ্যক্রমে একটি খুব সীমাবদ্ধ লাইব্রেরি সমর্থনকারী alচ্ছিকভাবে প্রয়োগ করেছে।

জাভা প্রোগ্রামার হিসাবে আমাদের কেবল উত্তরাধিকার লাইব্রেরিগুলির সাথে ইন্টারঅ্যাক্ট করতে নাল ব্যবহার করা উচিত।


3
পরিবর্তে javax.annotation ব্যবহার @Nonnullএবং সম্পর্কে কীভাবে @Nullable? আমি তাদের যে লাইব্রেরিটি বিকাশ করি সেগুলিতে আমি সেগুলি ব্যাপকভাবে ব্যবহার করি এবং আইডিই (ইন্টেলিজিজ) সরবরাহিত সহায়তাটি খুব ভাল।
রোজিরিও

1
এটি ঠিক আছে, তবে আপনাকে এই এনোটোটেশনটি যে কোনও জায়গায় ব্যবহার করতে হবে এবং মানচিত্র, ফ্ল্যাটম্যাপ / বাইন্ড, লিফটএম 2, সিকোয়েন্স ইত্যাদির মতো পদ্ধতিগুলির সমর্থন করার জন্য আপনার একটি লাইব্রেরি প্রয়োজন
মার্ক পেরি

14
কার্যকরী প্রোগ্রামিং ভাষাগুলি ptionচ্ছিক পরামিতিগুলিকে উত্সাহ দেয়। তথ্যসূত্র প্রয়োজন. বেশিরভাগ ফাংশনগুলির একটি anচ্ছিক গ্রহণ করা উচিত নয়; পরিবর্তে, কোনও মূল্য উপস্থিতি বা অনুপস্থিতির সাথে ডিলিংয়ের (যথাযথ উচ্চ-অর্ডার ফাংশনগুলি ব্যবহার করে) প্রশ্নাবলীর ক্রিয়াকলাপের উপর নির্ভর করে।
jub0bs

5
এই. প্রকৃতপক্ষে, উত্তরগুলির কোনওটিই যথেষ্ট বিশ্বাসযোগ্য নয় এবং তাদের কোনওটিই এই নির্দিষ্ট প্রশ্নের উত্তর দেয় না "কেন পদ্ধতি প্যারামিটার হিসাবে বিকল্পগুলি ব্যবহারকে খারাপ অনুশীলন হিসাবে বিবেচনা করা @NonNullহয় তবে তারা যদি বিভিন্ন উপায়ে একই উদ্দেশ্য উপস্থাপন করে তবে পদ্ধতি পরামিতিগুলি সম্পূর্ণরূপে সঠিক?" আমার জন্য, কেবলমাত্র একটি যুক্তি যা কমপক্ষে কিছুটা বোঝায়: "আরও ভাল API সরবরাহের জন্য ptionচ্ছিক ব্যবহার করা উচিত, যার সুস্পষ্ট রিটার্ন টাইপ রয়েছে। তবে পদ্ধতির যুক্তিগুলির জন্য, ওভারলোডেড ফাংশনগুলি ব্যবহার করা যেতে পারে।" - তবুও, আমি মনে করি না এটি একটি যুক্তি যা যথেষ্ট শক্ত।
উত্কু dezdemir

1
অবশ্যই, নাল থেকে অগ্রাধিকারযোগ্য, তবে এর চেয়েও বেশি পছন্দনীয় হ'ল প্রথম স্থানে প্রচুর alচ্ছিক মান প্রয়োজন হয় না কারণ ভাল নকশা: ডি
ইয়োমন

12

এই পরামর্শটি আঙ্গুলের নিয়ম "ইনপুট সম্পর্কিত যতটা সম্ভব অপ্রয়োজনীয় এবং আউটপুট সম্পর্কিত যতটা সম্ভব সুনির্দিষ্ট হতে হবে" এর একটি বৈকল্পিক।

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

  • আপনি চান যে আপনার ফাংশনটি অন্য একটি API এর সাথে একত্রে ব্যবহৃত হবে যা একটি ফেরত দেয় Optional
  • Optionalপ্রদত্ত মানটি ফাঁকা থাকলে আপনার ফাংশনটি খালি ব্যতীত অন্য কোনও কিছু ফিরিয়ে আনবে
  • আপনার মনে Optionalহয় এত দুর্দান্ত যে আপনার এপিআই ব্যবহার করেন সে সম্পর্কে এটি শিখতে হবে ;-)

10

যার সাথে প্যাটার্নটি Optionalহ'ল ফিরতে এড়ানো nullnullকোনও পদ্ধতিতে প্রবেশ করা এখনও পুরোপুরি সম্ভব ।

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

public int calculateSomething(@NotNull final String p1, @NotNull final String p2) {}

এখানে সমস্যাটি বরং এটি নয় যে @ নটনুল ডিফল্ট কেস নয় এবং এটি স্পষ্টরূপে বর্নিত করতে হবে - তাই বয়লারপ্লেট এবং স্টাফ যা লোকেরা কেবল অলসতার কারণে করবে না।
ডিগেইনার

1
@ ডিজেগার হ্যাঁ, তবে Optionalসমস্যাটিও ঠিক করে না, সুতরাং টীকাগুলির জন্য আমার পরামর্শ।
মাকোটো

2
ডকস / উত্স পড়ার সময় বা আপনার সরঞ্জামটি যদি এটি ধরতে পারে তবে স্থির বিশ্লেষণ সর্বদা সঠিকভাবে নির্ধারণ করতে পারে না এমন কোনও টীকাকে উপেক্ষা করার চেয়ে Oচ্ছিক উপেক্ষা করা অনেক বেশি শক্ত।
আজাক্স

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

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

7

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

বলা হচ্ছে, এক সাথে পদ্ধতিগুলি শৃঙ্খলাবদ্ধ করা যা বিকল্পগুলি গ্রহণ / প্রত্যাবর্তনগুলি করা যুক্তিসঙ্গত জিনিস, যেমন: মোনাড Maybe


7
মানগুলি এবং ক্ষেত্রগুলিও শূন্য হতে পারে না? তাহলে Optionalকি পুরোপুরি অর্থহীন?
স্যামুয়েল এডউইন ওয়ার্ড

6

JDK10, https://docs.oracle.com/javase/10/docs/api/java/util/Optional.html এ জাভাডোকটি দেখুন , একটি এপিআই নোট যুক্ত হয়েছে:

এপিআই দ্রষ্টব্য: ptionচ্ছিকটি মূলত একটি পদ্ধতি রিটার্ন টাইপ হিসাবে ব্যবহারের উদ্দেশ্যে তৈরি করা হয় যেখানে "কোনও ফলাফল নয়" উপস্থাপনের স্পষ্ট প্রয়োজন আছে এবং যেখানে নাল ব্যবহারের ফলে ত্রুটি হওয়ার সম্ভাবনা রয়েছে।


4

আমার গ্রহণযোগ্যতাটি হ'ল ptionচ্ছিকটি একটি মোনাড হওয়া উচিত এবং এটি জাভাতে অনুমেয় নয়।

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

বিমূর্তির এই দুটি স্তরের মিশ্রিত করা সুগম্যতার পক্ষে সুবিধাজনক নয় তাই আপনি কেবল এড়ানো এটাই ভাল।


3

Optionalপ্যারামিটারটি পাস করার সময় সাবধানতা অবলম্বন করার আরেকটি কারণ হ'ল কোনও পদ্ধতিতে একটি জিনিস করা উচিত ... আপনি যদি কোনও Optionalপ্যারাম পাস করেন তবে আপনি একাধিক জিনিসকে পছন্দ করতে পারেন, এটি বুলিয়ান পারম পাস করার মতো হতে পারে।

public void method(Optional<MyClass> param) {
     if(param.isPresent()) {
         //do something
     } else {
         //do some other
     }
 }

আমি মনে করি এটি একটি ভাল কারণ নয়। Logচ্ছিক ব্যবহার না করা হলে পরম নাল হয় কিনা তা যাচাই করার জন্য একই যুক্তি প্রয়োগ করা যেতে পারে। আসলে, if(param.isPresent())param.forEach(() -> {...})
ptionচ্ছিক

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

2

Paraচ্ছিককে প্যারামিটার হিসাবে গ্রহণ করা কলার স্তরে অপ্রয়োজনীয় মোড়কের কারণ হয়।

উদাহরণস্বরূপ:

public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {}

ধরুন আপনার কাছে দুটি নাল-স্ট্রিং রয়েছে (যেমন, অন্য কোনও পদ্ধতি থেকে ফিরে এসেছেন):

String p1 = "p1"; 
String p2 = "p2";

আপনি জেনে রাখেন যে তারা খালি নয় even

এটি আরও খারাপ হয়ে যায় যখন আপনাকে অন্যান্য "ম্যাপেবল" কাঠামো, যেমন রচনা করতে হয়। আইথারস :

Either<Error, String> value = compute().right().map((s) -> calculateSomething(
< here you have to wrap the parameter in a Optional even if you know it's a 
  string >));

সুত্র:

পদ্ধতির বিকল্পগুলি পরামিতি হিসাবে প্রত্যাশা করা উচিত নয়, এটি প্রায়শই একটি কোড গন্ধ যা কলার থেকে কলিতে নিয়ন্ত্রণ প্রবাহের ফুটো ইঙ্গিত দেয়, কোনও বিকল্পের বিষয়বস্তু যাচাই করা কলারের দায়িত্ব হওয়া উচিত

সুত্র। https://github.com/teamdigitale/digital-citizenship-functions/pull/148#discussion_r170862749


1

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


1

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


2
একটি নাল Oচ্ছিক রেফারেন্স পাস করা একটি প্রোগ্রামিং ত্রুটি হিসাবে বিবেচনা করা যেতে পারে (কারণ ption চ্ছিক একটি "খালি" মান পাস করার একটি সুস্পষ্ট উপায় সরবরাহ করে), সুতরাং এটি পরীক্ষা করার মতো নয়, যদি না আপনি সমস্ত ক্ষেত্রে ব্যতিক্রম ছোঁড়া এড়াতে চান না।
pvgoran

1

ব্রায়ান গয়েটস সুন্দরভাবে ব্যাখ্যা হিসাবে বিকল্পগুলি এই উদ্দেশ্যে ডিজাইন করা হয়নি ।

কোনও পদ্ধতির যুক্তিটি নালার হতে পারে তা বোঝাতে আপনি সর্বদা @ নুলাবল ব্যবহার করতে পারেন। একটি alচ্ছিক ব্যবহার সত্যিই আপনার পদ্ধতি লজিক আরও ঝরঝরে লিখতে সক্ষম করে না।


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

0

আরও একটি পদ্ধতির, আপনি কি করতে পারেন

// get your optionals first
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();

// bind values to a function
Supplier<Integer> calculatedValueSupplier = () -> { // your logic here using both optional as state}

একবার আপনি কোনও ফাংশন তৈরি করার পরে (এই ক্ষেত্রে সরবরাহকারী) আপনি অন্য কোনও পরিবর্তনশীল হিসাবে এটি পাস করতে সক্ষম হবেন এবং এটি ব্যবহার করে এটি কল করতে সক্ষম হবেন

calculatedValueSupplier.apply();

আপনি optionচ্ছিক মান পেয়েছেন কিনা তা এখানে ধারণাটি আপনার ফাংশনের অভ্যন্তরীণ বিশদ হবে এবং প্যারামিটারে থাকবে না। প্যারামিটার হিসাবে alচ্ছিক সম্পর্কে চিন্তা করার সময় ফাংশনগুলি চিন্তা করা আসলে আমি খুঁজে পেয়েছি খুব দরকারী কৌশল।

আপনার প্রশ্নের ভিত্তিতে আপনাকে আসলে এটি করা উচিত কিনা তা আপনার পছন্দের উপর ভিত্তি করে, তবে অন্যরা যেমন বলেছে এটি আপনার এপিআইকে কমদামে কুরুচিপূর্ণ করে তোলে।


0

প্রথমে, আমি পরামিতি হিসাবে বিকল্পগুলি পাস করতেও পছন্দ করেছি, তবে আপনি যদি কোনও API-ডিজাইনার দৃষ্টিকোণ থেকে একটি API- ব্যবহারকারী দৃষ্টিকোণে স্যুইচ করেন তবে আপনি অসুবিধাগুলি দেখতে পাচ্ছেন।

আপনার উদাহরণস্বরূপ, যেখানে প্রতিটি প্যারামিটারটি alচ্ছিক, আমি গণনার পদ্ধতিটিকে নিজের ক্লাসে পরিবর্তনের জন্য নীচের মত পরামর্শ দেব:

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();

MyCalculator mc = new MyCalculator();
p1.map(mc::setP1);
p2.map(mc::setP2);
int result = mc.calculate();

0

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

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

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


0

এটি একটি এপিআই ব্যবহারকারী এবং একটি এপিআই বিকাশকারী আমাদের বিভিন্ন প্রয়োজনীয়তা কারণ।

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

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


0

প্রথমত, আপনি যদি পদ্ধতি 3 ব্যবহার করেন তবে আপনি শেষ 14 টি কোডের লাইন এটি দিয়ে প্রতিস্থাপন করতে পারেন:

int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));

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

public int calculateSomething(String p1OrNull, BigDecimal p2OrNull)

এইভাবে, এটি স্পষ্ট যে নাল মান অনুমোদিত।

আপনার ব্যবহারের মাধ্যমে p1.orElse(null)বোঝায় যে codeচ্ছিক ব্যবহার করার সময় আমাদের কোডটি কীভাবে ভার্বোজ হয়, যা আমি এড়াতে পারি তারই অংশ। Functionচ্ছিক ফাংশনাল প্রোগ্রামিং জন্য লেখা হয়েছিল। স্ট্রিমগুলির এটির প্রয়োজন। আপনার পদ্ধতিগুলি সম্ভবত ফাংশনাল প্রোগ্রামিংয়ে সেগুলি ব্যবহার করার প্রয়োজন না হলে neverচ্ছিক আর ফিরে আসা উচিত নয়। পদ্ধতির মতো Optional.flatMap()পদ্ধতি রয়েছে, এর জন্য কোনও ফাংশনের রেফারেন্স প্রয়োজন যা ptionচ্ছিক ফেরত দেয়। এটির স্বাক্ষর এখানে:

public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper)

সুতরাং এটি সাধারণত কোনও পদ্ধতি রচনার একমাত্র ভাল কারণ যা ptionচ্ছিক প্রত্যাবর্তন করে। তবে সেখানেও এড়ানো যায়। আপনি এমন একটি গেটর পাস করতে পারেন যা flatচ্ছিকভাবে ফ্ল্যাটম্যাপ () এর মতো কোনও পদ্ধতিতে ফিরে আসে না, এটি অন্য পদ্ধতিতে মোড়ক দিয়ে যা ফাংশনটিকে সঠিক ধরণের রূপান্তর করে। মোড়কের পদ্ধতিটি দেখে মনে হচ্ছে:

public static <T, U> Function<? super T, Optional<U>> optFun(Function<T, U> function) {
    return t -> Optional.ofNullable(function.apply(t));
}

সুতরাং ধরুন আপনার এইরকম একজন গিটার রয়েছে: String getName()

আপনি এটি ফ্ল্যাটম্যাপে এভাবে পাস করতে পারবেন না:

opt.flatMap(Widget::getName) // Won't work!

তবে আপনি এটি এইভাবে পাস করতে পারেন:

opt.flatMap(optFun(Widget::getName)) // Works great!

কার্যকরী প্রোগ্রামিং এর বাইরে Oচ্ছিকতা এড়ানো উচিত।

ব্রায়ান গোয়েট যখন এ কথাটি বলেছেন তখন এটি সবচেয়ে ভাল বলেছেন:

Javaচ্ছিক জাভাতে যুক্ত হওয়ার কারণ হ'ল:

return Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
    .stream()
    .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
    .filter(m ->  Arrays.equals(m.getParameterTypes(), parameterClasses))
    .filter(m -> Objects.equals(m.getReturnType(), returnType))
    .findFirst()
    .getOrThrow(() -> new InternalError(...));

এর চেয়ে পরিষ্কার:

Method matching =
    Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
    .stream()
    .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
    .filter(m ->  Arrays.equals(m.getParameterTypes(), parameterClasses))
    .filter(m -> Objects.equals(m.getReturnType(), returnType))
    .getFirst();
if (matching == null)
  throw new InternalError("Enclosing method not found");
return matching;

1
ঠিক আছে, এটি জাভাতে যুক্ত হওয়ার কারণগুলির মধ্যে একটি। অন্য প্রচুর আছে। নেস্টেড 'if' বিবৃতিগুলির দীর্ঘ চেইনগুলি প্রতিস্থাপন করা যা চ্ছিক.ম্যাপে শৃঙ্খলাবদ্ধ কলগুলির একক ক্রম সহ কোনও ডেটা স্ট্রাকচারে প্রবেশ করে, তা আমার ব্যক্তিগত প্রিয়। ফাংশনাল ল্যাঙ্গুয়েজ প্রোগ্রামিং ওয়ার্ল্ডের ptionচ্ছিকের জন্য অনেকগুলি আকর্ষণীয় ব্যবহার রয়েছে যা কেবল নাল চেকের পরিবর্তে এটিকে প্রতিস্থাপন করে।
কিছু লোক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.