পঠনযোগ্যতা বনাম রক্ষণাবেক্ষণযোগ্যতা, নেস্টেড ফাংশন কলগুলি লেখার বিশেষ ক্ষেত্রে


57

নেস্টেড ফাংশন কলগুলির জন্য আমার কোডিং শৈলীটি নিম্নলিখিত:

var result_h1 = H1(b1);
var result_h2 = H2(b2);
var result_g1 = G1(result_h1, result_h2);
var result_g2 = G2(c1);
var a = F(result_g1, result_g2);

আমি সম্প্রতি একটি বিভাগে পরিবর্তিত হয়েছি যেখানে নিম্নলিখিত কোডিং শৈলীটি খুব ব্যবহৃত হয়:

var a = F(G1(H1(b1), H2(b2)), G2(c1));

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

আমি আশঙ্কা করি যে, প্রথম ভাবে প্রোগ্রাম করা একই সমস্যার কারণে ক্রাশ হওয়ার পরে, কোন ক্র্যাশ ক্রাশের কারণ হয়েছে তা আমি জানতে সক্ষম হব না।

অন্যদিকে, আপনি যত বেশি প্রসেসিং একটি লাইনে রাখবেন, তত যুক্তি আপনি এক পৃষ্ঠায় পাবেন, যা পাঠযোগ্যতা বাড়ায়।

আমার ভয় কি সঠিক বা আমি কিছু হারিয়ে যাচ্ছি, এবং সাধারণভাবে, যা বাণিজ্যিক পরিবেশে পছন্দ করা হয়? পঠনযোগ্যতা বা রক্ষণাবেক্ষণযোগ্যতা?

এটি প্রাসঙ্গিক কিনা তা আমি জানি না তবে আমরা সি ++ (এসটিএল) / সি # তে কাজ করছি।


17
@ গ্যাनेट: আপনি একটি সাধারণ প্রশ্ন উল্লেখ করেছেন, যদিও আমি বিশেষভাবে নেস্টেড ফাংশন কলগুলির উল্লিখিত ক্ষেত্রে এবং ক্র্যাশ ডাম্প বিশ্লেষণের ক্ষেত্রে পরিণতি সম্পর্কে আগ্রহী, তবে লিঙ্কটির জন্য ধন্যবাদ, এতে বেশ কিছু আকর্ষণীয় তথ্য রয়েছে।
ডোমিনিক

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

4
পরিবর্তনশীল নামটি result_g1যা আপনি আসলে ব্যবহার করতে চান বা এই মানটি আসলে কোনও বুদ্ধিমান নামের সাথে কিছু উপস্থাপন করে; যেমন percentageIncreasePerSecond। দুজনের মধ্যে সিদ্ধান্ত নেওয়ার জন্য এটিই আমার পরীক্ষা হবে
রিচার্ড টিঙ্গল

3
কোডিং শৈলীতে আপনার অনুভূতি নির্বিশেষে, আপনার কনভেনশনটি ইতিমধ্যে স্থানে থাকা উচিত যদি না এটি পরিষ্কারভাবে ভুল হয় (তবে মনে হয় না যে এটি এই ক্ষেত্রে রয়েছে)।
n00b

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

উত্তর:


111

আপনি যদি ওয়ান লাইনারের মতো প্রসারিত করতে বাধ্য হন

 a = F(G1(H1(b1), H2(b2)), G2(c1));

আমি আপনাকে দোষ দেব না এটি কেবল পড়া কঠিন নয়, এটি ডিবাগ করাও শক্ত।

কেন?

  1. এটা ঘন
  2. কিছু ডিবাগার কেবল একবারে পুরো বিষয়টি হাইলাইট করবে
  3. এটি বর্ণনামূলক নামমুক্ত

আপনি যদি মধ্যবর্তী ফলাফলগুলি দিয়ে এটি প্রসারিত করেন তবে পাবেন

 var result_h1 = H1(b1);
 var result_h2 = H2(b2);
 var result_g1 = G1(result_h1, result_h2);
 var result_g2 = G2(c1);
 var a = F(result_g1, result_g2);

এবং এটি পড়া এখনও কঠিন। কেন? এটি দুটি সমস্যার সমাধান করে এবং একটি চতুর্থ পরিচয় দেয়:

  1. এটা ঘন
  2. কিছু ডিবাগার কেবল একবারে পুরো বিষয়টি হাইলাইট করবে
  3. এটি বর্ণনামূলক নামমুক্ত
  4. এটি অ-বর্ণনামূলক নামের সাথে বিশৃঙ্খল

আপনি যদি এটির নামের সাথে এটি প্রসারিত করেন যা নতুন, ভাল, অর্থপূর্ণ অর্থ যুক্ত করে, আরও ভাল! একটি ভাল নাম আমাকে বুঝতে সাহায্য করে।

 var temperature = H1(b1);
 var humidity = H2(b2);
 var precipitation = G1(temperature, humidity);
 var dewPoint = G2(c1);
 var forecast = F(precipitation, dewPoint);

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

যদি আপনি এটি অর্থহীন নামগুলির মতো করে করেন result_thisএবং result_thatকারণ আপনি কেবল ভাল নামগুলি ভাবতে পারেন না তবে আমি আপনাকে অবশ্যই অর্থহীন নাম বিশৃঙ্খলা বাদ দিয়ে কিছু ভাল পুরাতন শ্বেত স্পেস ব্যবহার করে এটি প্রসারিত করতে পছন্দ করব:

int a = 
    F(
        G1(
            H1(b1), 
            H2(b2)
        ), 
        G2(c1)
    )
;

অর্থহীন ফলাফলের নামগুলির চেয়ে এটি যতটা পঠনযোগ্য, তত বেশি না পঠনযোগ্য (এই ফাংশনের নামগুলি যে দুর্দান্ত তা নয়)।

  1. এটা ঘন
  2. কিছু ডিবাগার কেবল একবারে পুরো বিষয়টি হাইলাইট করবে
  3. এটি বর্ণনামূলক নামমুক্ত
  4. এটি অ-বর্ণনামূলক নামের সাথে বিশৃঙ্খল

আপনি যখন ভাল নাম চিন্তা করতে পারেন না, এটি যতটা ভাল তা পায়।

কোনও কারণে ডিবাগারগুলি নতুন রেখাগুলি পছন্দ করে তাই আপনার এটি খুঁজে পাওয়া উচিত যে এটির ডিবাগিংটি কঠিন নয়:

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

যদি এটি পর্যাপ্ত না G2()হয় তবে কল্পনাটি একাধিক জায়গায় ডাকা হয়েছিল এবং তারপরে এটি ঘটেছিল:

Exception in thread "main" java.lang.NullPointerException
    at composition.Example.G2(Example.java:34)
    at composition.Example.main(Example.java:18)

আমি মনে করি এটি দুর্দান্ত যেহেতু প্রতিটি G2()কল তার নিজস্ব লাইনে থাকবে, এই স্টাইলটি আপনাকে সরাসরি আপত্তিজনক কলটিতে নিয়ে যায়।

সুতরাং দয়া করে আমাদের সমস্যাটি আটকে রাখার অজুহাত হিসাবে 1 এবং 2 সমস্যাটি ব্যবহার করবেন না 4.. আপনি যখন সেগুলি সম্পর্কে ভাবতে পারেন তখন ভাল নাম ব্যবহার করুন। যখন আপনি পারবেন না তখন অর্থহীন নামগুলি এড়িয়ে চলুন।

অরবিটের মন্তব্যে লাইটনেস রেসগুলি সঠিকভাবে উল্লেখ করেছে যে এই ফাংশনগুলি কৃত্রিম এবং তাদের মৃত দুর্বল নামগুলি রয়েছে। তাই বন্য থেকে কিছু কোডে এই স্টাইলটি প্রয়োগ করার একটি উদাহরণ এখানে দেওয়া হয়েছে:

var user = db.t_ST_User.Where(_user => string.Compare(domain,  
_user.domainName.Trim(), StringComparison.OrdinalIgnoreCase) == 0)
.Where(_user => string.Compare(samAccountName, _user.samAccountName.Trim(), 
StringComparison.OrdinalIgnoreCase) == 0).Where(_user => _user.deleted == false)
.FirstOrDefault();

শব্দের মোড়কের প্রয়োজন নেই এমন কি শব্দের প্রবাহের দিকে তাকাতেও আমি ঘৃণা করি। এই স্টাইলের নীচে এটি দেখতে কেমন তা এখানে দেখুন:

var user = db
    .t_ST_User
    .Where(
        _user => string.Compare(
            domain, 
            _user.domainName.Trim(), 
            StringComparison.OrdinalIgnoreCase
        ) == 0
    )
    .Where(
        _user => string.Compare(
            samAccountName, 
            _user.samAccountName.Trim(), 
            StringComparison.OrdinalIgnoreCase
        ) == 0
    )
    .Where(_user => _user.deleted == false)
    .FirstOrDefault()
;

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


20
@ স্টিভ এবং আমি আপনাকে না করতে বলছি না। আমি অর্থপূর্ণ নামের জন্য ভিক্ষা করছি। সবসময় প্রায়শই আমি মাঝারি শৈলীটি নির্বোধভাবে সম্পন্ন করে দেখেছি। খারাপ নামগুলি আমার মস্তিষ্কে প্রতি লাইন বিচ্ছিন্ন কোডের চেয়ে অনেক বেশি জ্বলিত করে দেয় I আমি তাদের আরও পচে যাওয়ার জন্য অনুপ্রাণিত করি। যদি ভাল নামগুলি না ঘটে তবে অর্থহীন শব্দটি এড়ানোর জন্য এই কাজটি বিবেচনা করুন।
candied_orange

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

4
প্রসারিত সংস্করণটি কুরুচিপূর্ণ দেখাচ্ছে। সেখানে অনেক বেশি শ্বেতস্থান রয়েছে যা হ্রাসকারী কার্যনির্বাহী কিছু কমিয়ে দেয়, অর্থনীতির অর্থহীন।
মতিন উলহাক

5
@ ম্যাটেন উলহাক কেবলমাত্র অতিরিক্ত শ্বেতস্থানটিতে বেশ কয়েকটি নিউলাইন এবং কিছু ইন্ডেন্টেশন রয়েছে এবং এটি সমস্ত সাবধানতার সাথে অর্থবহ সীমানায় স্থাপন করা হয়েছে । আপনার মন্তব্য পরিবর্তে অ-অর্থপূর্ণ সীমানায় সাদা স্থান রাখে। আমি আপনাকে কিছুটা কাছাকাছি এবং আরও বেশি উন্মুক্ত চেহারা দেওয়ার পরামর্শ দিচ্ছি।
jpmc26

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

50

অন্যদিকে, আপনি যত বেশি প্রসেসিং একটি লাইনে রাখবেন, তত যুক্তি আপনি এক পৃষ্ঠায় পাবেন, যা পাঠযোগ্যতা বাড়ায়।

আমি এর সাথে পুরোপুরি একমত নই। আপনার দুটি কোড উদাহরণ দেখে কেবল এটিকে ভুল হিসাবে আখ্যায়িত করেছেন:

var a = F(G1(H1(b1), H2(b2)), G2(c1));

পড়তে শোনা যায়। "পঠনযোগ্যতা" মানে তথ্য ঘনত্ব নয়; এর অর্থ "পড়া সহজ, বুঝতে এবং বজায় রাখা সহজ"।

কখনও কখনও, কোডটি সহজ এবং এটি একটি একক লাইন ব্যবহার করা বোধ করে। অন্য সময়, এটি করা কেবল পড়া কঠিন করে তোলে, এক লাইনে আরও ক্র্যামিংয়ের বাইরে কোনও সুস্পষ্ট সুবিধার জন্য।

তবে, "ক্র্যাশগুলির নির্ণয় করা সহজ" এর অর্থ কোড বজায় রাখা সহজ claim ক্র্যাশ হয় না এমন কোড বজায় রাখা আরও সহজ। "বজায় রাখা সহজ" প্রাথমিকভাবে কোডের মাধ্যমে অর্জনযোগ্যভাবে পড়া এবং বুঝতে সহজ হয়েছে, স্বয়ংক্রিয় পরীক্ষার একটি ভাল সেট সহ ব্যাক আপ।

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


37
যদিও আমি সম্মতি জানাই যে F(G1(H1(b1), H2(b2)), G2(c1))এটি পড়া শক্ত, তবে খুব ঘন চক্রযুক্ত হওয়ার সাথে এর কোনও যোগসূত্র নেই। (আপনি যদি এটির অর্থ বোঝাতে চেয়েছিলেন তবে নিশ্চিত নন, তবে এটি ব্যাখ্যা করা যেতে পারে)) একক লাইনে তিন বা চারটি ফাংশন নেস্ট করা পুরোপুরি পাঠযোগ্য হতে পারে, বিশেষত যদি কিছু ফাংশন সরল ইনফিক্স অপারেটর হয়। এটি হ'ল সমস্যা সম্পর্কিত নামগুলি এখানে সমস্যা, তবে মাল্টি-লাইন সংস্করণে এই সমস্যাটি আরও খারাপ, যেখানে আরও ননডেস্ক্রিপটিভ নামগুলি চালু করা হয়েছে। কেবলমাত্র বয়লারপ্লেট যুক্ত করা কখনই পঠনযোগ্যতার পক্ষে সহায়তা করে না।
'14

23
@ বামফুট চক্র: আমার কাছে অসুবিধাটি হ'ল এটি G13 টি প্যারামিটার বা মাত্র 2 নেয় এবং G2এটি অন্য পরামিতি কিনা তা স্পষ্ট নয় F। আমাকে স্ক্রিন্ট করতে হবে এবং বন্ধনীগুলি গণনা করতে হবে।
ম্যাথিউ এম।

4
@MatthieuM। এটি একটি সমস্যা হতে পারে, তবে যদি ফাংশনগুলি সুপরিচিত হয় তবে এটি প্রায়শই সুস্পষ্ট হয় যা কত যুক্তি গ্রহণ করে। বিশেষত, যেমনটি আমি বলেছি, ইনফিক্স ফাংশনের জন্য এটি তাত্ক্ষণিকভাবে পরিষ্কার হয়ে গেছে যে তারা দুটি যুক্তি নিয়েছে। (এছাড়াও, প্রথম ভাষাগুলির প্রথম F (G1 (H1 b1) (H2 b2)) (G2 c1)
বন্ধনযুক্ত টুপলস

5
ব্যক্তিগতভাবে আমি আরও কমপ্যাক্ট ফর্মটি পছন্দ করি, যতক্ষণ না আমার চারপাশে আমার পূর্ববর্তী মন্তব্যের মতো স্টাইলিং রয়েছে কারণ এটি মানসিকভাবে নজর রাখার জন্য কম রাষ্ট্রের গ্যারান্টি দেয় - result_h1এটি উপস্থিত না থাকলে পুনরায় ব্যবহার করা যাবে না এবং 4 ভেরিয়েবলের মধ্যে নদীর গভীরতানির্ণয়টি হবে সুস্পষ্ট।
ইজকাটা

8
আমি খুঁজে পেয়েছি যে সাধারণভাবে ডিবাগ করা সহজ কোডটি এমন কোড যা ডিবাগিংয়ের প্রয়োজন হয় না।
রব কে

25

আপনার প্রথম উদাহরণ, একক-অ্যাসাইনমেন্ট-ফর্মটি অপঠনযোগ্য, কারণ নির্বাচিত নামগুলি সম্পূর্ণ অর্থহীন। এটি আপনার পক্ষ থেকে অভ্যন্তরীণ তথ্য প্রকাশ না করার চেষ্টা করার একটি নিদর্শন হতে পারে, সত্য কোডটি সে ক্ষেত্রে ভাল হতে পারে, আমরা বলতে পারি না। যাইহোক, অত্যন্ত কম তথ্য-ঘনত্বের কারণে এটি দীর্ঘ-বাতাসযুক্ত, যা সাধারণত সহজে বোঝার জন্য নিজেকে ধার দেয় না।

আপনার দ্বিতীয় উদাহরণটি একটি অযৌক্তিক ডিগ্রীতে ঘনীভূত। যদি ফাংশনগুলির দরকারী নাম থাকে তবে এটি খুব ভাল এবং ভালভাবে পঠনযোগ্য হতে পারে কারণ এর খুব বেশি কিছু নেই, তবে এটি অন্য দিকে বিভ্রান্ত করছে।

অর্থপূর্ণ নাম পরিচয় করানোর পরে, আপনি দেখতে পাবেন যে কোনও ফর্মটি প্রাকৃতিক বলে মনে হচ্ছে, বা যদি কোনও সোনার মাঝখানে আছে।

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


17

সর্বদা হিসাবে, যখন এটি পাঠযোগ্যতার কথা আসে, ব্যর্থতা চূড়ান্ত হয় । আপনি যে কোনও ভাল প্রোগ্রামিং পরামর্শ নিতে পারেন , এটিকে একটি ধর্মীয় নিয়মে পরিণত করতে পারেন এবং একেবারে অপঠনযোগ্য কোড তৈরি করতে ব্যবহার করতে পারেন। (যদি আপনি এই আমাকে বিশ্বাস করি না, বাইরে এই দুটি পরীক্ষা IOCCC বিজয়ীদের borsanyi এবং goren এবং কিভাবে ভিন্নভাবে তারা একদম অপাঠ্য কোড রেন্ডার করতে ফাংশন ব্যবহার কটাক্ষপাত করা ইঙ্গিত:। ঠিক একটি ফাংশন Borsanyi ব্যবহার করে, goren অনেক, আরো অনেক ...)

আপনার ক্ষেত্রে, দুটি চরমপন্থি হ'ল 1) কেবলমাত্র একক অভিব্যক্তি বিবৃতি ব্যবহার করে এবং 2) বড়, অবিচ্ছিন্ন এবং জটিল বিবৃতিতে সমস্ত কিছুতে যুক্ত। হয় চূড়ান্তভাবে গৃহীত পদ্ধতির আপনার কোডটি অপঠনযোগ্য রেন্ডার করে।

প্রোগ্রামার হিসাবে আপনার কাজটি ভারসাম্য রক্ষা করা । আপনার লেখার প্রতিটি বক্তব্যের জন্য, এই প্রশ্নের উত্তর দেওয়া আপনার কাজ: "এই বিবৃতিটি কি বোঝা সহজ, এবং এটি আমার ফাংশনটি পাঠযোগ্য করে তোলে?"


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

double d = sqrt(square(x1 - x0) + square(y1 - y0));

এটি বেশ জটিল বক্তব্য, তবে তাদের নুনের মূল্যবান যে কোনও প্রোগ্রামারকে এটি কী করে তা অবিলম্বে উপলব্ধি করতে সক্ষম হওয়া উচিত। এটি একটি বেশ সুপরিচিত প্যাটার্ন। যেমন, এটি সমমানের চেয়ে অনেক বেশি পঠনযোগ্য

double dx = x1 - x0;
double dy = y1 - y0;
double dxSquare = square(dx);
double dySquare = square(dy);
double dSquare = dxSquare + dySquare;
double d = sqrt(dSquare);

যা সুপরিচিত প্যাটার্নটিকে আপাতদৃষ্টিতে অর্থহীন সংখ্যক সরল পদক্ষেপে বিভক্ত করে। তবে আপনার প্রশ্ন থেকে বিবৃতি

var a = F(G1(H1(b1), H2(b2)), G2(c1));

এটি আমার কাছে অত্যধিক জটিল বলে মনে হচ্ছে, যদিও এটি দূরত্ব গণনার চেয়ে কম অপারেশন । অবশ্যই, যে আমাকে সরাসরি ফল সম্পর্কে কিছু বুদ্ধিমান না F(), G1(), G2(), H1(), অথবা H2()। আমি তাদের সম্পর্কে আরও জানলে আমি অন্যভাবে সিদ্ধান্ত নিতে পারি। তবে এটি হুবহু সমস্যা: বিবৃতিটির যুক্তিযুক্ত জটিলতা প্রসঙ্গে এবং জড়িত ক্রিয়াকলাপগুলির উপর দৃ strongly়ভাবে নির্ভর করে। এবং আপনি, একজন প্রোগ্রামার হিসাবে, যিনি অবশ্যই এই প্রসঙ্গে সন্ধান করতে হবে এবং কোনও একক বিবৃতিতে কী অন্তর্ভুক্ত করবেন তা সিদ্ধান্ত নিতে পারেন। আপনি যদি পঠনযোগ্যতার বিষয়ে যত্নশীল হন তবে আপনি কিছু দায়বদ্ধ নিয়মে এই দায়িত্বটি অফলোড করতে পারবেন না।


14

@ ডমিনিক, আমি আপনার প্রশ্নের বিশ্লেষণে মনে করি, আপনি ভুল করছেন যে "পাঠযোগ্যতা" এবং "রক্ষণাবেক্ষণযোগ্যতা" দুটি পৃথক জিনিস।

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

নেস্টেড ফাংশন কলগুলির জন্য অন্তর্বর্তী ভেরিয়েবলগুলি ব্যবহার করা হবে কিনা তা সিদ্ধান্ত নেওয়ার ক্ষেত্রে, প্রদত্ত 3 টি ভেরিয়েবলের ক্ষেত্রে, 5 টি পৃথক ফাংশনে কল করা হয় এবং কিছু কল 3 ডিস্টে নীস্টে থাকে, আমি এটি কমিয়ে দেওয়ার জন্য কমপক্ষে কিছু মধ্যবর্তী ভেরিয়েবলগুলি ব্যবহার করার দিকে ঝোঁক , যেমন আপনি করেছেন।

তবে আমি অবশ্যই এতদূর যাব না যে ফাংশন কলগুলি কখনই নেস্ট করা উচিত নয়। এটা পরিস্থিতিতে রায় একটি প্রশ্ন।

আমি বলব যে নিম্নলিখিত বিষয়গুলি রায়টি বহন করে:

  1. যদি ডাকা ফাংশনগুলি স্ট্যান্ডার্ড গাণিতিক ক্রিয়াকলাপগুলি উপস্থাপন করে তবে এমন কিছু ফাংশনগুলির তুলনায় তারা নেস্টেড হওয়ার পক্ষে আরও বেশি সক্ষম যা কিছু অস্পষ্ট ডোমেন যুক্তিকে উপস্থাপন করে যার ফলাফল অনাকাঙ্ক্ষিত এবং পাঠকের দ্বারা অগত্যা মানসিকভাবে মূল্যায়ন করা যায় না।

  2. একক প্যারামিটার সহ একটি ফাংশন একাধিক পরামিতিগুলির সাথে ফাংশনের চেয়ে বাসাতে (অভ্যন্তরীণ বা বাহ্যিক ফাংশন হিসাবে) অংশ নিতে আরও সক্ষম। বিভিন্ন নেস্টিং স্তরে বিভিন্ন ধরণের বৈশিষ্ট্যগুলির মিশ্রণে শূকরটির কানের মতো দেখতে কোড ছাড়ার প্রবণতা রয়েছে।

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

  4. ফাংশন কলের একটি ছোট্ট নীড় যা সাধারণ কার্যকারিতা সম্পাদন করে এবং পড়ার জন্য ইতিমধ্যে স্পষ্ট, এবং তারপরে অতিরিক্ত এবং অ্যাটমাইজড হয়ে যায়, একেবারে ভাঙা হয়নি এমনটির চেয়ে পড়তে আরও বেশি কঠিন হতে সক্ষম


3
+1 এ "রক্ষণযোগ্য তবে অপঠনযোগ্য এমন কোড থাকা কি সম্ভব?"। যে খুব আমার প্রথম চিন্তা ছিল.
রন জন

4

উভয়ই suboptimal হয়। মন্তব্য বিবেচনা করুন।

// Calculating torque according to Newton/Dominique, 4th ed. pg 235
var a = F(G1(H1(b1), H2(b2)), G2(c1));

অথবা সাধারণের চেয়ে নির্দিষ্ট কার্যাদি:

var a = Torque_NewtonDominique(b1,b2,c1);

কোন ফলাফলটি বানান তা নির্ধারণ করার সময়, প্রতিটি বিবৃতির জন্য স্বতন্ত্রভাবে ব্যয় (অনুলিপি বনাম রেফারেন্স, এল-মান বনাম আর-মূল্য), পড়ার যোগ্যতা এবং ঝুঁকি মনে রাখবেন।

উদাহরণস্বরূপ, সরল ইউনিট / টাইপ রূপান্তরগুলি তাদের নিজস্ব লাইনে স্থানান্তরিত করার কোনও অতিরিক্ত মূল্য নেই কারণ এগুলি পড়া সহজ এবং ব্যর্থ হওয়ার সম্ভাবনা খুব কম:

var radians = ExtractAngle(c1.Normalize())
var a = Torque(b1.ToNewton(),b2.ToMeters(),radians);

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


আরগ পাস করার ব্যয় পুনরায়: অপ্টিমাইজেশনের দুটি নিয়ম রয়েছে। 1) না। 2) (শুধুমাত্র বিশেষজ্ঞদের জন্য) এখনও না ।
রাবারডাক

1

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

আমি পঠনযোগ্যতা 80 এবং 90 রক্ষণাবেক্ষণের মধ্যে কোথাও রাখব। অন্যান্য 10-20 শতাংশ হ'ল এটি রিফ্যাক্টরিংয়ের পক্ষে কতটা অনুকূল।

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

সম্পর্কিত সম্পর্কিত নয়, আপনি বলেছেন যে পৃষ্ঠায় আরও যুক্তি পাঠযোগ্যতার সহায়তা করে। এটি ভুল, মেট্রিক পৃষ্ঠা নয়, এটি পদ্ধতি এবং একটি পদ্ধতিতে যে কম যুক্তি রয়েছে, এটি তত বেশি পাঠযোগ্য।

পঠনযোগ্য অর্থ হ'ল প্রোগ্রামারটি তাদের মাথায় যুক্তি (ইনপুট, আউটপুট এবং অ্যালগরিদম) ধরে রাখতে পারে। এটি যত বেশি করে, কম কোনও প্রোগ্রামার এটি বুঝতে পারে। সাইক্লোমেটিক জটিলতা পড়ুন।


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

@ স্টিভ: আমি সর্বদা এটি করার জন্য বলিনি, তবে আপনি যদি একক মান পেতে 5 টি লাইন ব্যবহার করার কথা ভাবছেন তবে কোনও কার্যকারিতা আরও ভাল হওয়ার সম্ভাবনা রয়েছে। একাধিক লাইনের বনাম জটিল রেখার ক্ষেত্রে: যদি এটি একটি ভাল নামের একটি ফাংশন হয় তবে উভয়ই সমানভাবে ভাল কাজ করবে।
jmoreno

1

আপনি যদি সি # বা সি ++ তে থাকেন তবে আপনি যতক্ষণ না কোনও ডিবাগ বিল্ডে রয়েছেন, ততক্ষণ কোনও সম্ভাব্য সমাধান কার্য সম্পাদন করছে

var a = F(G1(H1(b1), H2(b2)), G2(c1));

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

returnType F( params)
{
    returnType RealF( params);
}

অবশ্যই যদি আপনি একই লাইনে একাধিকবার একই ফাংশনটি কল করেন তবে কোন ফাংশনটি আপনি তা জানতে পারবেন না তবে আপনি এটি সনাক্ত করতে পারেন:

  • ফাংশন পরামিতি তাকিয়ে
  • যদি প্যারামিটারগুলি অভিন্ন হয় এবং ফাংশনটির পার্শ্ব প্রতিক্রিয়া না থাকে তবে দুটি অভিন্ন কল 2 অভিন্ন কল হয়ে যায় ইত্যাদি etc.

এটি কোনও রূপোর বুলেট নয়, তবে অর্ধ-পথের মতো খারাপ নয়।

কোডের পাঠযোগ্যতার জন্য ফাংশনগুলির মোড়ানো গ্রুপ আরও বেশি উপকারী হতে পারে তা উল্লেখ করার দরকার নেই:

type CallingGBecauseFTheorem( T b1, C b2)
{
     return G1( H1( b1), H2( b2));
}

var a = F( CallingGBecauseFTheorem( b1,b2), G2( c1));

1

আমার মতে, স্ব-ডকুমেন্টিং কোড ভাষা নির্বিশেষে রক্ষণাবেক্ষণযোগ্যতা এবং পঠনযোগ্যতা উভয়ের জন্যই ভাল।

উপরে বর্ণিত বিবৃতিটি ঘন, তবে "স্ব দস্তাবেজ":

double d = sqrt(square(x1 - x0) + square(y1 - y0));

পর্যায়ে বিভক্ত হয়ে গেলে (পরীক্ষার পক্ষে সহজ, অবশ্যই) উপরে বর্ণিত সমস্ত প্রসঙ্গ হারাবে:

double dx = x1 - x0;
double dy = y1 - y0;
double dxSquare = square(dx);
double dySquare = square(dy);
double dSquare = dxSquare + dySquare;
double d = sqrt(dSquare);

এবং স্পষ্টতই ভেরিয়েবল এবং ফাংশন নাম ব্যবহার করা যা তাদের উদ্দেশ্য স্পষ্টভাবে জানিয়ে দেয় যে অমূল্য।

এমনকি "যদি" ব্লকগুলি স্ব-ডকুমেন্টিংয়ে ভাল বা খারাপ হতে পারে। এটি খারাপ কারণ আপনি সহজেই প্রথম 2 শর্তটি তৃতীয়টিকে পরীক্ষা করতে বাধ্য করতে পারবেন না ... সবগুলি সম্পর্কিত নয়:

if (Bill is the boss) && (i == 3) && (the carnival is next weekend)

এইটি আরও "সমষ্টিগত" ধারণা তৈরি করে এবং পরীক্ষার শর্ত তৈরি করা সহজ:

if (iRowCount == 2) || (iRowCount == 50) || (iRowCount > 100)

এবং এই বিবৃতিটি স্ব-ডকুমেন্টিং দৃষ্টিকোণ থেকে দেখা অক্ষরের কেবল একটি এলোমেলো স্ট্রিং:

var a = F(G1(H1(b1), H2(b2)), G2(c1));

উপরোক্ত বক্তব্যটির দিকে তাকানো, রক্ষণাবেক্ষণ এখনও একটি বড় চ্যালেঞ্জ যদি ফাংশন এইচ 1 এবং এইচ 2 উভয়ই একক "এইচ" ফাংশনে একত্রিত হওয়ার পরিবর্তে একই "সিস্টেমের রাষ্ট্রের পরিবর্তনশীল" পরিবর্তন করে, কারণ শেষ পর্যন্ত কেউ এইচ 1 কে এমনকি ভাবনা ছাড়াই এইচ 1 কে পরিবর্তন করবে এইচ 2 ফাংশনটি দেখতে এবং এইচ 2 টি ভাঙ্গতে পারে।

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

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