জাভাতে দুটি আর্গুমেন্ট চেক করুন, উভয়ই নাল নয় বা উভয়ই মার্জিতভাবে নাল নয়


161

আমি ইমেল প্রেরণের জন্য ব্যবহৃত শেল প্রকল্প বিকাশের জন্য স্প্রিং বুট ব্যবহার করি, যেমন

sendmail -from foo@bar.com -password  foobar -subject "hello world"  -to aaa@bbb.com

যদি fromএবং passwordতর্কগুলি অনুপস্থিত থাকে তবে আমি একটি ডিফল্ট প্রেরক এবং পাসওয়ার্ড ব্যবহার করি, যেমন noreply@bar.comএবং 123456

ব্যবহারকারী যদি fromযুক্তিটি পাস করে তবে তাদের অবশ্যই তর্ক করতে হবে এবং passwordবিপরীতে। এর অর্থ, উভয়ই নন-নাল, বা উভয়ই নাল।

আমি কীভাবে এটি মার্জিতভাবে পরীক্ষা করব?

এখন আমার উপায়

if ((from != null && password == null) || (from == null && password != null)) {
    throw new RuntimeException("from and password either both exist or both not exist");
}

14
একটি সরু হিসাবে, নোট করুন কীভাবে সাদাসিধা ব্যবহার করে যত্ন সহকারে কোড পড়া অনেক সহজ হয়ে যায় - কেবলমাত্র আপনার বর্তমান কোডটিতে অপারেটরদের মধ্যে স্পেস যুক্ত করা পঠনযোগ্যতা আইএমওতে উল্লেখযোগ্যভাবে যুক্ত হবে।
জন স্কিটি

8
"কমনীয়তা" সংজ্ঞায়িত করুন।
রেনাউড

এসএমটিপি প্রমাণীকরণ শংসাপত্রগুলির জন্য এবং খাম প্রেরক ই-মেইল ঠিকানার জন্য আপনার পৃথক যুক্তিগুলির প্রয়োজন। Fromই-মেইল ঠিকানা সবসময় SMTP এর প্রমাণীকরণ নাম নয়।
কাজ

3
এটি সত্যিই অনেক বেশি অনুকূলিত হতে পারে না, এটি পঠনযোগ্য কোডের এক লাইন এবং এটি অত্যধিক অনুকূলিতকরণের মাধ্যমে কিছুই অর্জন করা যায় না।
দিইনেওয়ালা

3
পার্শ্ব দ্রষ্টব্য: এটি শেল স্ক্রিপ্ট হলে শেল ইতিহাসে পাসওয়ার্ডগুলি সংরক্ষণ করা হবে না?
আমার

উত্তর:


331

^( এক্সওআর ) অপারেটরটি ব্যবহার করার একটি উপায় রয়েছে :

if (from == null ^ password == null) {
    // Use RuntimeException if you need to
    throw new IllegalArgumentException("message");
}

ifশর্ত সত্য হতে হবে কেবল এক পরিবর্তনশীল নাল হয়।

তবে আমি মনে করি সাধারণত ifবিভিন্ন ব্যতিক্রম বার্তায় দুটি শর্ত ব্যবহার করা ভাল । আপনি একক শর্ত ব্যবহার করে কী ভুল হয়েছে তা নির্ধারণ করতে পারবেন না।

if ((from == null) && (password != null)) {
    throw new IllegalArgumentException("If from is null, password must be null");
}
if ((from != null) && (password == null)) {
    throw new IllegalArgumentException("If from is not null, password must not be null");
}

এটি আরও পঠনযোগ্য এবং এটি বোঝার পক্ষে আরও সহজ এবং এটি কেবলমাত্র কিছু অতিরিক্ত টাইপ করে takes


152
দুটি স্তরে দুটি স্তরে জোর বেশি কেন পছন্দ করার কোনও কারণ !=রয়েছে?
এরিক লিপার্ট

1
বাহ, আমি বুঝতে পারি নি যে বুলিয়ানের এক্সওআর একই রকম !=। Mindblown। এবং এটি মন্তব্যে একটি উচ্চ সংখ্যক upvotes। এবং, এই মন্তব্যে গুণমান যুক্ত করার জন্য, হ্যাঁ, আমি আরও মনে করি যে পৃথক ত্রুটি মামলার জন্য পৃথক ত্রুটি বার্তা দেওয়া আরও ভাল, যেহেতু ব্যবহারকারী কীভাবে ত্রুটিটি সংশোধন করবেন সে সম্পর্কে আরও ভাল জানেন।
জাস্টহেলফ

1
2 উপাদান জন্য ঠিক আছে। > 2 টি উপাদান দিয়ে এটি কীভাবে করবেন?
আনুশ্রী আচার্জি

আমি উপাদানগুলির যে কোনও একটি> 0 থাকলে একটি ত্রুটি বার্তা প্রদর্শন করতে চাই। ডিফল্টরূপে সমস্ত 0 তে সেট করা থাকে all সবগুলি যদি হয়> 0 এটির একটি বৈধ দৃশ্য। কিভাবে এই কাজ করতে?
আনুশ্রী আচার্জি

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

286

ঠিক আছে, মনে হচ্ছে আপনি দুজনের "নালিকা" অবস্থা একই কিনা তা যাচাই করার চেষ্টা করছেন। আপনি ব্যবহার করতে পারেন:

if ((from == null) != (password == null))
{
    ...
}

অথবা সহায়ক ভেরিয়েবলগুলির সাথে এটি আরও সুস্পষ্ট করুন:

boolean gotFrom = from != null;
boolean gotPassword = password != null;
if (gotFrom != gotPassword)
{
    ...
}

18
আপনি আমার SO হেরোজ @ কাজ এর মধ্যে একজন, তবে কিছুই 'না হয় এটি বা এটি, তবে উভয়ই' একই মত ^নয়। :-)
ডেভিড বুলক

6
@ ডেভিডবুলক: যখন বুলিয়ানদের কথা আসে, তখন কিছুই বলে না "হয় এই বা এটি তবে উভয়ই" মত ... "উভয়ই একই নয়"; বুলিয়ানদের উপর "সমতুল্য নয়" ফাংশনের জন্য এক্সওআর হ'ল অন্য নাম।
কাজ

5
@ কাজ এটি ঠিক ^বলেছেন যে "আরে, আমার অপারেশনগুলি বুলিয়ানস" এমনভাবে হয় যা !=না। (যদিও এই প্রভাবটি দুর্ভাগ্যক্রমে "আমার অপারেশনগুলি সংখ্যাসূচক হতে পারে এবং আমি এই সময়ে কোনও সম্পর্কযুক্ত অপারেটর নাও হতে পারি" যাচাই করার প্রয়োজনের ফলে হ্রাস পাচ্ছে) যা আমি একটি অসুবিধা হ'ল। আমার সাথে একমত না হওয়া সত্ত্বেও আপনার নায়কের অবস্থানটি নির্মূল করা হয়েছে :-)
ডেভিড বুলক

3
সমস্যার প্রয়োজনীয়তাগুলি পড়ার পরে, তারপরে আপনার সমাধান, কোডটি বোঝায় এবং পাঠযোগ্য। তবে 4 বছরের বিকাশকারী হিসাবে (এখনও স্কুলে) এই কোডটি পড়ে তারপরে "ব্যবসায়ের প্রয়োজনীয়তা" কী ছিল তা নির্ধারণের চেষ্টা করা মাথা ব্যথার কারণ হবে। এই কোড থেকে, আমি তাত্ক্ষণিকভাবে বুঝতে পারি না " fromএবং passwordউভয়ই নাল বা উভয়ই নাল নয়"। সম্ভবত এটি কেবল আমার এবং আমার অনভিজ্ঞতা, তবে আমি @ স্টিগ-হেমারের উত্তরের মতো আরও পঠনযোগ্য সমাধানটি পছন্দ করি, যদিও এর জন্য কোডের আরও 3 লাইন ব্যয় হয়। আমার ধারণা আমি কেবল তাত্ক্ষণিকভাবে পাই না bool != bool- এটি স্বজ্ঞাত নয়।
ক্রিস সাইরেফাইস

2
@ ডেভিডবুলক ^অপারেটরটি বিটওয়াস অপারেটর; এটি আসলে বোঝায় না যে এর অপারেশনগুলি বুলিয়ান। বুলিয়ান জোর অপারেটর xor
ব্রিলিন্ড

222

ব্যক্তিগতভাবে, আমি মার্জিত থেকে পঠনযোগ্য পছন্দ।

if (from != null && password == null) {
    throw new RuntimeException("-from given without -password");
}
if (from == null && password != null) {
    throw new RuntimeException("-password given without -from");
}

52
আরও ভাল বার্তা জন্য +1। এই হল গুরুত্বপূর্ণ, কেউ লেগেছে handwaving "কিছু ভুল হয়েছে" -error বার্তা, সেইজন্য কেউই উচিত কারণ এই ধরনের বার্তা। যাইহোক, অনুশীলনে, একটি আরও নির্দিষ্ট ব্যতিক্রম পছন্দ করা উচিত (বিশেষত, IllegalArgumentExceptionএকটি খালি পরিবর্তে একটি RuntimeException)
মার্কো 13

6
@ ম্যাটটি দেখে মনে হচ্ছে আপনার সমালোচনা কোডের সাথে নয়, ব্যতিক্রমগুলির পাঠ্যের সাথে। তবে আমি মনে করি যে এই উত্তরের যোগ্যতা ত্রুটি বার্তাগুলির সামগ্রীতে নয় তবে যদি বিবৃতিগুলির কাঠামোর মধ্যে থাকে। এটি সর্বোত্তম উত্তর কারণ এটি কার্যকারিতার উপরে উন্নতি করে; ওপি সহজেই ব্যতিক্রম পাঠ্যের জন্য তাদের পছন্দ মতো স্ট্রিংয়ের বিকল্প দিতে পারে।
ড্যান হেন্ডারসন

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

4
@ ড্যানহেন্ডারসন "" আপনি এই বিষয়গুলির মধ্যে একটি ভুল করেছেন "তা বলা কখনই ভাল ধারণা নয়। আমি একমত নই পাসওয়ার্ড / ব্যবহারকারীর নামটি কেবল ইউজারনেম এবং পাসওয়ার্ডের সাথে মেলে না বলা নিরাপদ।
ম্যাট

2
@ ড্যানহেন্ডারসন একটি সুরক্ষার দৃষ্টিকোণ থেকে ডিরেক্টরিতে যেখানে ব্যবহারকারীর নামটি রয়েছে তার মধ্যে পার্থক্য না করাই ভাল, অন্যথায় আক্রমণকারী বৈধ ব্যবহারকারীর নাম জানতে পারে could তবে নাল / নাল না মেশানো সর্বদা ব্যবহারের ত্রুটি এবং আরও বিস্তারিত ত্রুটি বার্তা দেখানো ব্যবহারকারীর প্রথম স্থানে সরবরাহ করা ছাড়া আর কোনও তথ্য ফাঁস হয় না।
siegi

16

স্বাক্ষর সহ 2 টি আর্গুমেন্ট পদ্ধতিতে সেই কার্যকারিতাটি রাখুন:

void assertBothNullOrBothNotNull(Object a, Object b) throws RuntimeException

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


14
বনাম কোনও স্থান সংরক্ষণ করা যায় ((from == null) != (password == null))তা বুঝতে খুব সহজ। দরকারী পদ্ধতি না করে কিছু ভুল আছে।
edc65

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

10
কোডটি পড়ার সময় আপনার কাছে একটি পদ্ধতির নাম রয়েছে যা আপনাকে বনাম শর্ত জাগলিং বুঝতে হবে।
ট্রাবেনফুচস

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

1
আপনি যদি এখানে কিছু বর্ণনামূলক ব্যতিক্রম বার্তা চান তবে আপনি অহেতুক সমস্যায় পড়ে যাবেন।
হনজা ব্রাবেক

11

একটি জাভা 8 সমাধানটি Objects.isNull(Object)স্ট্যাটিক আমদানি ধরে ধরে ব্যবহার করা হবে :

if (isNull(from) != isNull(password)) {
    throw ...;
}

জাভা <8 এর জন্য (বা যদি আপনি ব্যবহার পছন্দ করেন না Objects.isNull()), আপনি সহজেই নিজের isNull()পদ্ধতি লিখতে পারেন ।


6
ভাল লাগবে না। from == null != password == nullএটি সমস্ত স্ট্যাকের একই ফ্রেমে রাখে, তবে Objects.isNull(Object)অযথা ব্যবহার করে দুটি ফ্রেম ধাক্কা দেয় এবং পপ করে। অবজেক্টস.আইসনল (অবজেক্ট) আছে কারণ 'এই পদ্ধতিটি ভবিষ্যদ্বাণী হিসাবে ব্যবহার করার জন্য রয়েছে' (অর্থাত্ স্ট্রিমগুলিতে)।
ডেভিড বুলক

5
এর মতো একটি সহজ পদ্ধতিটি সাধারণত জেআইটির মাধ্যমে দ্রুত ইনলাইন করা হবে যাতে পারফরম্যান্সের প্রভাবটি সম্ভবত নগণ্য। আমরা প্রকৃতপক্ষে এর ব্যবহারের বিষয়ে বিতর্ক Objects.isNull()করতে পারি - আপনি যদি নিজের পছন্দ করেন তবে আপনি নিজের লেখা লিখতে পারেন - তবে যতক্ষণ পঠনযোগ্যতার বিষয়টি বিবেচনা করা isNull()হয় আমি মনে করি এটি ব্যবহার করা ভাল। তাছাড়া আপনি অতিরিক্ত প্রথম বন্ধনী করতে হবে সহজ অভিব্যক্তি কম্পাইল: from == null != (password == null)
দিদিয়ের এল

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

4
সত্যি বলতে কী, একক স্ট্যাক ফ্রেমের প্রতি কে যত্নশীল? আপনি যদি (সম্ভবত অসীম) পুনরাবৃত্তি নিয়ে কাজ করছেন, বা সাহারা মরুভূমির আকারের কোনও বস্তু গ্রাফ সহ আপনার যদি 1000-টাইয়ের অ্যাপ্লিকেশন রয়েছে তবে স্ট্যাকটি কেবলমাত্র তখনই একটি সমস্যা।
সারা 13

9

নাল চেকগুলির সংখ্যার জন্য এখানে একটি সাধারণ সমাধান

public static int nulls(Object... objs)
{
    int n = 0;
    for(Object obj : objs) if(obj == null) n++;
    return n;
}

public static void main (String[] args) throws java.lang.Exception
{
    String a = null;
    String b = "";
    String c = "Test";

    System.out.println (" "+nulls(a,b,c));
}

ব্যবহারসমূহ

// equivalent to (a==null & !(b==null|c==null) | .. | c==null & !(a==null|b==null))
if (nulls(a,b,c) == 1) { .. }

// equivalent to (a==null | b==null | c==null)
if (nulls(a,b,c) >= 1) { .. }

// equivalent to (a!=null | b!=null | c!=null)
if (nulls(a,b,c) < 3) { .. }

// equivalent to (a==null & b==null & c==null)
if (nulls(a,b,c) == 3) { .. }

// equivalent to (a!=null & b!=null & c!=null)
if (nulls(a,b,c) == 0) { .. }

2
ভাল দৃষ্টিভঙ্গি, তবে আপনার প্রথম "সমতুল্য" মন্তব্যটি মারাত্মকভাবে ভুল (বানান ভুলের বাইরে যা সমস্ত মন্তব্যে বিদ্যমান)
বেন ভয়েগট

@ বেনভয়েট এখনই ঠিক করা বিজ্ঞপ্তির জন্য আপনাকে ধন্যবাদ
খালেদ.কে।

9

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

// use defaults if neither is provided
if ((from == null) && (password == null)) {
    from = DEFAULT_SENDER;
    password = DEFAULT_PASSWORD;
}

// we should have a sender and a password now
if (from == null) {
    throw new MissingSenderException();
}
if (password == null) {
    throw new MissingPasswordException();
}

একটি অতিরিক্ত সুবিধা হ'ল যে কোনওটি আপনার ডিফল্ট শূন্য হওয়া উচিত, এটিও সনাক্ত করা হবে।


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


1
ডাউনভোটেড কারণ আমি আপনার উত্তরগুলির একটি নমুনার জন্য এলোমেলো বাছাই করেছি এবং প্রতিশ্রুত xkcd লিঙ্কটি খুঁজে পাচ্ছি না! লজ্জা করে না আপনার!
দহেইন

@ জাইবিস আমার প্রতিরক্ষা মতে এটি কেবল একটি শখ, পুরো সময়ের কাজ নয়। তবে আমি দেখতে পাচ্ছি কিনা ...
এসকিউবি

8

আমি অন্য একটি বিকল্প প্রস্তাব করতে চাই যা আমি এই কোডের এই অংশটি কীভাবে লিখব:

if( from != null )
{
    if( password == null )
        error( "password required for " + from );
}
else
{
    if( password != null )
        warn( "the given password will not be used" );
}

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

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


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

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

কমনীয়তা যতদূর যায়, এটি সম্ভবত এটি করার সবচেয়ে স্বল্পতম উপায়।
ফ্রেমজি

7

আমি মনে করি এটি হ্যান্ডেল করার সঠিক উপায়টি তিনটি পরিস্থিতি বিবেচনা করা: উভয় থেকে 'পাসওয়ার্ড' এবং 'পাসওয়ার্ড' সরবরাহ করা হয়, উভয়ই সরবরাহ করা হয় না, উভয়ের মিশ্রণ সরবরাহ করা হয়।

if(from != null && password != null){
    //use the provided values
} else if(from == null && password == null){
    //both values are null use the default values
} else{
   //throw an exception because the input is not correct.
}

মনে হচ্ছে আসল প্রশ্নটি যদি ভুল ইনপুট হয় তবে প্রবাহটি ভাঙ্গতে চায় তবে তাদের পরে যুক্তিটির কিছুটা পুনরাবৃত্তি করতে হবে। সম্ভবত একটি ভাল নিক্ষেপ বিবৃতি হতে পারে:

throw new IllegalArgumentException("form of " + form + 
    " cannot be used with a "
    + (password==null?"null":"not null") +  
    " password. Either provide a value for both, or no value for both"
);

2
এই কোডটি ভুল নয় কারণ এটি কাজ করে না কারণ এটি বোঝা খুব কঠিন। অন্য কারও দ্বারা লিখিত এই জাতীয় কোডটি ডিবাগ করা কেবল একটি দুঃস্বপ্ন।
NO_NAME

2
@NO_NAME আমি বুঝতে পারছি না কেন এটি বোঝা শক্ত। ওপিতে তিনটি কেস সরবরাহ করা হয়েছে: যখন ফর্ম এবং পাসওয়ার্ড উভয়ই সরবরাহ করা হয়, যখন কোনওটি সরবরাহ করা হয় না, এবং মিশ্র কেস যা একটি ব্যতিক্রম ছুঁড়ে ফেলা উচিত। তারা উভয় নাল কিনা তা পরীক্ষা করার জন্য আপনি মধ্য শর্তসাপেক্ষে উল্লেখ করছেন?
ম্যাট

2
আমি @NO_NAME এর সাথে একমত, এই মিডল কেসটি নজরে আসতে খুব বেশি পার্সিং করে। আপনি যদি শীর্ষ রেখাকে বিশ্লেষণ না করেন তবে আপনি পাবেন না যে নালটির মাঝের সাথে কোনও সম্পর্ক আছে। সেক্ষেত্রে পাসওয়ার্ড এবং পাসওয়ার্ডের সমতা আসলে নাল না হওয়ার কেবলমাত্র একটি পার্শ্ব-প্রতিক্রিয়া।
jimm101

1
@ jimm101 হ্যাঁ, আমি দেখতে পেলাম যে এটি একটি সমস্যা। পারফরম্যান্স সুবিধাটি আরও ভারবস সমাধানের জন্য ন্যূনতম / সনাক্তকরণযোগ্য হবে। বিষয়টি নিশ্চিত হওয়ার পরেও তা নিশ্চিত কিনা তা আমি নিশ্চিত নই। আমি এটি আপডেট।
ম্যাট

2
@ ম্যাট কোনও পারফরম্যান্সের সুবিধার নাও থাকতে পারে - সংকলকটি কী করবে তা স্পষ্ট নয় এবং এই ক্ষেত্রে চিপটি স্মৃতি থেকে কী টানবে। প্রচুর প্রোগ্রামার চক্র অপ্টিমাইজেশনে পোড়া যেতে পারে যা সত্যিকার অর্থে কিছুই দেয় না।
jimm101

6

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

private void validatePasswordExists(Parameters params) {
   if (!params.hasKey("password")){
      throw new PasswordMissingException("Password missing");
   }
}

private void validateFromExists(Parameters params) {
   if (!params.hasKey("from")){
      throw new FromEmailMissingException("From-email missing");
   }
}

private void validateParams(Parameters params) {

  if (params.hasKey("from") || params.hasKey("password")){
     validateFromExists(params);
     validatePasswordExists(params);
  }
}

1
নিয়ন্ত্রণ ফ্লো স্টেটমেন্টের জায়গায় আপনার ব্যতিক্রম ব্যবহার করা উচিত নয়। পারফরম্যান্স হিট হওয়ার পাশাপাশি আরও গুরুত্বপূর্ণ এটি আপনার কোডের পঠনযোগ্যতা হ্রাস করে কারণ এটি মানসিক প্রবাহকে ভঙ্গ করে।
একটি phu

1
@ এনফু নং ঠিক নেই। ব্যতিক্রমগুলি ব্যবহার করার ফলে কোড পাঠযোগ্যতা বৃদ্ধি পায় কারণ এটি যদি-অন্য ধারাগুলি থেকে মুক্তি পায় এবং কোড প্রবাহকে আরও পরিষ্কার করে তোলে। docs.oracle.com/javase/tutorial/essential/exception/…
অর্ণব দত্ত

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

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

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

6

কেউ মনে করেন না যে টেরিনারি অপারেটরটির কথা উল্লেখ করেছেন :

if (a==null? b!=null:b==null)

এই বিশেষ শর্তটি যাচাই করার জন্য দুর্দান্তভাবে কাজ করে তবে গত দুটি পরিবর্তনশীল ভাল করে না general


1
সৌন্দর্য চমৎকার, কিন্তু কঠিন চেয়ে বুঝতে ^, !=দুই bools বা দুই সঙ্গে ifগুলি
coolguy

@ কুলগুয়ে আমার অনুমান যে টর্নারি অপারেটরটি এক্সওআর অপারেটরের চেয়ে অনেক বেশি সাধারণ (যখনই আপনি কোডটিতে কিছুটা এক্সওর দেখছেন না তখন 'মানসিক অবাক' এর কথা উল্লেখ করবেন না) এবং এই সূত্রটি কাটা এড়ানোর ঝোঁক রাখে এবং পেস্ট ত্রুটিগুলি যা দ্বিগুণ হয়।
gbronner

প্রস্তাবিত নয়। এটি (a! = নাল && বি == নাল) এবং (a == নাল এবং& বি! = নাল) এর মধ্যে পার্থক্য করবে না। আপনি যদি টার্নারি অপারেটরটি ব্যবহার করতে যাচ্ছেন:a == null ? (b == null? "both null" : "a null while b is not") : (b ==null? "b null while a is not")
অর্ণব দত্ত

5

আমি যেমন আপনার উদ্দেশ্যগুলি দেখেছি, উভয়ই সর্বদা দু'টি নালাগুলি পরীক্ষা করার প্রয়োজন নেই তবে passwordশূন্য হয় কিনা এবং তা কেবল নাল নয় কিনা তা খতিয়ে দেখার দরকার নেই from। আপনি প্রদত্ত passwordযুক্তি উপেক্ষা করতে পারেন এবং fromশূন্য হলে আপনার নিজের ডিফল্ট ব্যবহার করতে পারেন ।

সিউডোতে লিখিত অবশ্যই এটি হতে হবে:

if (from == null) { // form is null, ignore given password here
    // use your own defaults
} else if (password == null) { // form is given but password is not
    // throw exception
} else { // both arguments are given
    // use given arguments
}

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

4

আমি অবাক হয়েছি কেউই কোনও শ্রেণীর তৈরি fromএবং passwordক্ষেত্রগুলির সহজ সমাধান এবং সেই শ্রেণীর উদাহরণের জন্য একটি রেফারেন্স পাস করার জন্য উল্লেখ করেনি:

class Account {
    final String name, password;
    Account(String name, String password) {
        this.name = Objects.requireNonNull(name, "name");
        this.password = Objects.requireNonNull(password, "password");
    }
}

// the code that requires an account
Account from;
// do stuff

এখানে fromনাল বা অ-নাল হতে পারে এবং এটি যদি নাল হয় তবে এর উভয় ক্ষেত্রেই নন-নাল মান রয়েছে।

এই পদ্ধতির একটি সুবিধা হ'ল এক ক্ষেত্র তৈরি করার ত্রুটি কিন্তু অন্য ক্ষেত্রটি বাতিল হয়ে যায় না যেখানে অ্যাকাউন্টটি প্রাথমিকভাবে অ্যাকাউন্টটি প্রাপ্ত হয়, যখন অ্যাকাউন্টটি ব্যবহার করে কোড চালানো হয় তা নয়। অ্যাকাউন্টটি ব্যবহার করে কোডটি কার্যকর করার সময়, ডেটা অবৈধ হওয়া অসম্ভব।

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


এটি প্রত্যাশার মতো কার্যকর হয় না যেহেতু new Account(null, null)একটি এনপিই নিক্ষেপ করবে যদিও নাল নাম এবং পাসওয়ার্ড উভয়ের অ্যাকাউন্ট এখনও বৈধ is
হাইওএইচটি

ধারণাটি হ'ল নাম এবং পাসওয়ার্ড শূন্য হলে নাল পাস করা, বাস্তব বিশ্বে আপনি বলবেন যে অ্যাকাউন্টটি বিদ্যমান exists
মনিকা পুনরায়

আমি ওপি থেকে যা পাই তা হ'ল উভয়ই নন-নাল, বা উভয়ই নাল। আমি কেবল ভাবলাম যে আপনি কীভাবে নাম এবং পাসওয়ার্ড নাল উভয় দিয়ে একটি অ্যাকাউন্ট অবজেক্ট তৈরি করতে পারেন?
হাইউইচটি

@ হাইউইচটি দুঃখিত, আমার শেষ মন্তব্যটি অস্পষ্ট ছিল। যদি নাম এবং পাসওয়ার্ডটি শূন্য থাকে তবে আপনি এটির nullপরিবর্তে ব্যবহার করতে পারেন Account। আপনি কনস্ট্রাক্টরের nullকাছে যাবেন না Account
মনিকা পুনরায়
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.