সুস্পষ্ট অর্থ সহ 2 টি পদ্ধতি বা কেবল 1 টি দ্বৈত ব্যবহারের পদ্ধতি থাকা ভাল?


30

ইন্টারফেসটি সহজ করার জন্য, কেবল getBalance()পদ্ধতিটি না রাখাই ভাল ? পাসিং 0করতে charge(float c);একই ফলাফল দিতে হবে:

public class Client {
    private float bal;
    float getBalance() { return bal; }
    float charge(float c) {
        bal -= c;
        return bal;
    }
}

ভিতরে একটি নোট করতে পারেন javadoc? বা, ক্লাস ব্যবহারকারীর কাছে কীভাবে ভারসাম্য পাবেন তা নির্ধারণের জন্য রেখে দিন?


26
আমি উদারভাবে ধরে নিচ্ছি এটি উদাহরণ, উদাহরণস্বরূপ কোড এবং এটি যে আপনি আর্থিক মানগুলি সংরক্ষণ করতে ভাসমান পয়েন্ট গণিত ব্যবহার করছেন না। অন্যথায় আমি সব প্রচার করতে হবে। :-)
corsiKa

1
পছন্দ করুন এটি কেবল একটি উদাহরণ। তবে, হ্যাঁ, আমি সত্যিকারের ক্লাসে অর্থ উপস্থাপন করতে ভাসা ব্যবহার করতাম ... ভাসমান পয়েন্ট সংখ্যার বিপদ সম্পর্কে আমাকে মনে করিয়ে দেওয়ার জন্য ধন্যবাদ।
ডেভিড

10
কিছু ভাষা ভাল প্রভাবের জন্য পরিবর্তনকারী এবং অ্যাক্সেসরের মধ্যে পার্থক্য করে। এটি কেবল ধ্রুবক হিসাবে অ্যাক্সেসযোগ্য একটি উদাহরণের ভারসাম্য পেতে অক্ষম হতে পেরে বিরক্তিকর হবে!
জেডিগোগস

উত্তর:


90

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

তদ্ব্যতীত কলিং কমপক্ষে অবাকcharge(0) হওয়ার নীতির লঙ্ঘন করে , প্রতি মিনিট মেট্রিকের জন্য ডাব্লুটিএফ হিসাবেও পরিচিত (নীচের চিত্র থেকে ক্লিন কোড থেকে), দলের নতুন সদস্যদের (বা বর্তমানগুলি , কোড থেকে কিছুটা দূরে থাকার পরে) পর্যন্ত এটি শক্ত করে তোলে তারা বুঝতে পারে যে কলটি আসলে ভারসাম্য বজায় রাখতে ব্যবহৃত হয়। অন্যান্য পাঠকরা কীভাবে প্রতিক্রিয়া জানাবে তা ভেবে দেখুন:

এখানে চিত্র বর্ণনা লিখুন

এছাড়াও, chargeপদ্ধতির স্বাক্ষরটি একটি এবং কেবল একটি কাজ করার নির্দেশিকা এবং কমান্ড-কোয়েরি পৃথকীকরণের বিপরীতে যায় কারণ এটি কোনও নতুন মান ফেরত দেওয়ার সাথে সাথে বস্তুকে তার অবস্থার পরিবর্তন করতে বাধ্য করে।

সর্বোপরি, আমি বিশ্বাস করি যে এই ক্ষেত্রে সবচেয়ে সহজ ইন্টারফেস হবে:

public class Client {
  private float bal;
  float getBalance() { return bal; }
  void charge(float c) { bal -= c; }
}

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

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

12
সিকিউএস উপদেশটি প্রয়োজনীয়ভাবে যথাযথ নয়। একটি charge()পদ্ধতির জন্য, যদি সেই পদ্ধতিটি সমবর্তী সিস্টেমে পারমাণবিক হয় তবে নতুন বা পুরানো মানটি ফেরত দেওয়া উপযুক্ত হতে পারে।
ডায়েটারিচ এপ্পি

3
সিকিউআরএসের জন্য আপনার দুটি উদ্ধৃতি আমি অত্যন্ত স্বতঃস্ফূর্তভাবে খুঁজে পেয়েছি। উদাহরণস্বরূপ, আমি মায়ারের আইডিয়াগুলি সাধারণত পছন্দ করি তবে কোনও ফাংশনের রিটার্নের ধরণটি দেখে এটির কোনও পরিবর্তন হয় কিনা তা স্বেচ্ছাচারিতা এবং অকারণীয় is অনেক যুগ্ম বা অপরিবর্তনীয় ডেটা স্ট্রাকচারের জন্য মিউটেশন + রিটার্ন প্রয়োজন। আপনি কীভাবে সিকিউআরএস লঙ্ঘন না করে কোনও স্ট্রিংয়ের সাথে যুক্ত হবেন? আপনার কি আরও ভাল উদ্ধৃতি আছে?
ব্যবহারকারী 4949300

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

28

আইএমও, প্রতিস্থাপন getBalance()সঙ্গে charge(0)আপনার আবেদন জুড়ে একটি সরলীকরণ নয়। হ্যাঁ এটি কম রেখাগুলি, তবে এটি charge()পদ্ধতির অর্থটিকে অস্পষ্ট করে তোলে , যখন আপনার বা অন্য কেউ এই কোডটি পুনর্বিবেচনার প্রয়োজন হয় তখন সম্ভবত লাইনটির মাথা ব্যথার কারণ হতে পারে।

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


13

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

float charge(float c) {
    lockDownUserAccountUntilChargeClears();
    bal -= c;
    Unlock();
    return bal;
}

হঠাৎ charge()ভারসাম্য পেতে ব্যবহার করা এত ভাল লাগে না।


হ্যাঁ! একটি ভাল পয়েন্ট যা chargeআরও বেশি ভারী ওজন।
অনুচ্ছেদে

2

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

if (c > 0) {
    // make and log charge
}
return bal;

তবে এগুলি এগুলি বাস্তবায়ন করতে জেনে প্রোগ্রামারের উপর নির্ভর করে, যা সে প্রয়োজনীয় হবে না তা যদি তাৎক্ষণিকভাবে স্পষ্ট না হয় তবে সে তা করবে না।

সংক্ষেপে: আপনার ব্যবহারকারী বা আপনার প্রোগ্রামার উত্তরসূরিদের উপর নির্ভর করবেন না যে charge(0);এটি ভারসাম্য পাওয়ার সঠিক উপায়, কারণ যদি ডকুমেন্টেশন না থাকে যে তাদের নিশ্চিত না হয় তবে স্পষ্টতই ভারসাম্য পাওয়ার সবচেয়ে ভীতিজনক উপায় বলে মনে হচ্ছে সম্ভব.


0

আমি জানি প্রচুর উত্তর রয়েছে, তবে এর বিপরীতে অন্য charge(0)একটি charge(9)কারণ হ'ল আপনি যখনই তার ভারসাম্য পেতে চান প্রতিবার আপনার গ্রাহকের ভারসাম্য হ্রাস পাবে। আপনার যদি ভাল ইউনিট পরীক্ষা করা থাকে তবে আপনি সেই ঝুঁকি হ্রাস করতে সক্ষম হতে পারেন, তবে আপনি যদি প্রতিটি কলটিতে অধ্যবসায় করতে ব্যর্থ হন তবে chargeএই দুর্ঘটনা ঘটতে পারে।


-2

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

সেক্ষেত্রে প্রতিটি বাস্তবায়ন লেখার কাজটিকে সহজ করে তোলা এর ব্যবহারের স্পষ্টতার চেয়ে অনেক বেশি মূল্যবান, কারণ প্রাক্তন চুক্তি লঙ্ঘন বাগগুলি এড়িয়ে চলেন (দুটি পদ্ধতি একে অপরের সাথে অসামঞ্জস্যপূর্ণ), তবে পরেরটি কেবল পঠনযোগ্যতার ক্ষতি করে যা পারে একটি সাহায্যকারী ফাংশন বা সুপারক্লাস পদ্ধতি নির্ধারণ করে উদ্ধার করা getBalanceপরিপ্রেক্ষিতে charge

(এটি একটি নকশার ধরণ, যা আমি এর জন্য নির্দিষ্ট নামটি স্মরণ করি না: একটি ন্যূনতম প্রয়োগকারী-বান্ধব দিক থেকে একটি জটিল কলার-বান্ধব ইন্টারফেসকে সংজ্ঞায়িত করে Class ক্লাসিক ম্যাক ওএসে অঙ্কন অপারেশনের জন্য ন্যূনতম ইন্টারফেসকে "বাটালেনেক" বলা হত) তবে এটি কোনও জনপ্রিয় শব্দ বলে মনে হয় না))

যদি এটি না হয় (কয়েকটি বাস্তবায়ন বা ঠিক একটিই রয়েছে) তবে স্পষ্টতার জন্য পদ্ধতিগুলি পৃথক করে দেওয়া এবং ননজারো চার্জের সাথে সম্পর্কিত আচরণের সহজ সংযোজনকে মঞ্জুরি দেওয়া charge()বোধ করে।


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

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

@ নিকলবোলাস: এবং পুনর্বাসনের জন্য কেউ নেই? যাইহোক, যে কোনওটির প্রায়শই একই রকম realloc, কিছু সিস্টেমে "বেনিফিট" যুক্ত রয়েছে ।
উত্সাহক

@ উত্সাহক: বরাদ্দ বনাম পুনঃনির্ধারণ হ'ল ... ঠিক আছে। তাদের একই ফাংশনে রাখা দুর্দান্ত নয়, তবে এটি একই ডিলেকেশনকে রাখার মতো খারাপ নয়। এটি তৈরি করাও সহজ পার্থক্য।
নিকল বোলাস

আমি বলব যে (পুনরায়) বরাদ্দ দিয়ে ডিফলেশনকে বিভ্রান্ত করা এই ধরণের ইন্টারফেসের একটি বিশেষত খারাপ উদাহরণ। (ক্ষয়ক্ষতির একটি খুব আলাদা চুক্তি রয়েছে: এর ফলে কোনও বৈধ পয়েন্টার হয় না ))
কেভিন রেড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.