কোড গন্ধ এমন একটি লক্ষণ যা ইঙ্গিত দেয় যে নকশায় একটি সমস্যা রয়েছে যা সম্ভাব্যভাবে বাগের সংখ্যা বাড়িয়ে তুলবে: অঞ্চলগুলির ক্ষেত্রে এটি এমন নয়, অঞ্চলগুলি দীর্ঘ পদ্ধতির মতো কোড গন্ধ তৈরিতে অবদান রাখতে পারে।
থেকে:
একটি অ্যান্টি-প্যাটার্ন (বা অ্যান্টিপ্যাটার্ন) হ'ল এমন একটি প্যাটার্ন যা সামাজিক বা ব্যবসায়িক ক্রিয়াকলাপ বা সফ্টওয়্যার ইঞ্জিনিয়ারিংয়ে ব্যবহৃত হয় যা সাধারণত ব্যবহৃত হতে পারে তবে অকার্যকর এবং / অথবা অনুশীলনে অনুশীলনমূলক
অঞ্চলে হয় বিরোধী নিদর্শন। তাদের আরও বেশি কাজ করা দরকার যা কোডের গুণমান বা পঠনযোগ্যতা বাড়ায় না, যা বাগের সংখ্যা হ্রাস করে না এবং এটি কেবল কোডটিকে চুল্লি থেকে আরও জটিল করে তুলতে পারে।
পদ্ধতির অভ্যন্তরে অঞ্চলগুলি ব্যবহার করবেন না; পরিবর্তে রিফ্যাক্টর
পদ্ধতিগুলি সংক্ষিপ্ত হতে হবে । যদি কোনও পদ্ধতিতে কেবল দশটি লাইন থাকে তবে আপনি অন্য পাঁচটিতে কাজ করার সময় সম্ভবত পাঁচটি অঞ্চল লুকানোর জন্য অঞ্চলগুলি ব্যবহার করবেন না।
এছাড়াও, প্রতিটি পদ্ধতিতে অবশ্যই একটি এবং একটি জিনিস করা উচিত । অন্যদিকে অঞ্চলগুলি বিভিন্ন জিনিস আলাদা করার উদ্দেশ্যে । যদি আপনার পদ্ধতিটি এ, বি বি করে দেয় তবে দুটি অঞ্চল তৈরি করা যৌক্তিক তবে এটি একটি ভুল পদ্ধতির; পরিবর্তে, আপনার দুটি পৃথক পদ্ধতিতে পদ্ধতিটি রিফ্যাক্টর করা উচিত।
এক্ষেত্রে অঞ্চলগুলি ব্যবহার করা রিফ্যাক্টরিংকে আরও কঠিন করে তুলতে পারে। আপনার কল্পনা করুন:
private void DoSomething()
{
var data = LoadData();
#region Work with database
var verification = VerifySomething();
if (!verification)
{
throw new DataCorruptedException();
}
Do(data);
DoSomethingElse(data);
#endregion
#region Audit
var auditEngine = InitializeAuditEngine();
auditEngine.Submit(data);
#endregion
}
দ্বিতীয় অঞ্চলে মনোনিবেশ করার জন্য প্রথম অঞ্চলটি ভেঙে যাওয়া কেবল ঝুঁকিপূর্ণ নয়: আমরা সহজেই ব্যতিক্রমটি প্রবাহ বন্ধ করে দেওয়া সম্পর্কে ভুলে যেতে পারি (এর return
পরিবর্তে কোনও প্রহরী ধারা থাকতে পারে , যা স্পট করা আরও কঠিন), তবে সমস্যাও হবে কোডটি যদি এভাবে রিফ্যাক্ট করা উচিত:
private void DoSomething()
{
var data = LoadData();
#region Work with database
var verification = VerifySomething();
var info = DoSomethingElse(data);
if (verification)
{
Do(data);
}
#endregion
#region Audit
var auditEngine = InitializeAuditEngine(info);
auditEngine.Submit(
verification ? new AcceptedDataAudit(data) : new CorruptedDataAudit(data));
#endregion
}
এখন অঞ্চলগুলি কোনও ধারণা রাখে না, এবং আপনি প্রথম অঞ্চলে কোডটি না দেখিয়ে সম্ভবত দ্বিতীয় অঞ্চলে কোডটি পড়তে এবং বুঝতে পারবেন না।
আমি মাঝে মাঝে দেখতে পাই এমন একটি ঘটনা:
public void DoSomething(string a, int b)
{
#region Validation of arguments
if (a == null)
{
throw new ArgumentNullException("a");
}
if (b <= 0)
{
throw new ArgumentOutOfScopeException("b", ...);
}
#endregion
#region Do real work
...
#endregion
}
দশক এলওসি বিস্তৃত হওয়া যখন আর্গুমেন্টের বৈধতা শুরু হয় তখন এটি অঞ্চলগুলিকে ব্যবহার করতে প্ররোচিত হয় তবে এই সমস্যা সমাধানের আরও ভাল উপায় আছে: নেট ফ্রেমওয়ার্ক উত্স কোড দ্বারা ব্যবহৃত একটি:
public void DoSomething(string a, int b)
{
if (a == null)
{
throw new ArgumentNullException("a");
}
if (b <= 0)
{
throw new ArgumentOutOfScopeException("b", ...);
}
InternalDoSomething(a, b);
}
private void InternalDoSomething(string a, int b)
{
...
}
গোষ্ঠীগুলির জন্য পদ্ধতির বাইরে অঞ্চলগুলি ব্যবহার করবেন না
কিছু লোক তাদের ক্ষেত্র, সম্পত্তি ইত্যাদি একত্রে গোষ্ঠী হিসাবে ব্যবহার করে এই পদ্ধতিরটি ভুল: যদি আপনার কোডটি স্টাইলকপ-অনুবর্তী হয় তবে ক্ষেত্র, সম্পত্তি, ব্যক্তিগত পদ্ধতি, নির্মাতা ইত্যাদি ইতিমধ্যে একসাথে গোষ্ঠীযুক্ত এবং সন্ধান করা সহজ। যদি তা না হয় তবে আপনার কোডবেস জুড়ে অভিন্নতা নিশ্চিত করে এমন নিয়ম প্রয়োগের বিষয়ে চিন্তাভাবনা করা সময়ের চেয়ে বেশি।
অন্যান্য লোকেরা প্রচুর অনুরূপ সত্ত্বাকে আড়াল করতে অঞ্চল ব্যবহার করে । উদাহরণস্বরূপ, আপনার যদি শত ক্ষেত্রের সাথে ক্লাস থাকে (যা কমেন্টের কমপক্ষে 500 টি লাইন কোড তৈরি করে যদি আপনি মন্তব্যগুলি এবং হোয়াইটস্পেস গণনা করেন), আপনি সেই ক্ষেত্রগুলিকে কোনও অঞ্চলের ভিতরে রেখে, এটি ভেঙে ফেলতে এবং সেগুলি ভুলে যেতে প্ররোচিত হতে পারেন। আবার, আপনি এটি ভুল করছেন: একটি ক্লাসে অনেকগুলি ক্ষেত্রের সাথে, উত্তরাধিকার ব্যবহার সম্পর্কে আরও ভালভাবে চিন্তা করা উচিত বা অবজেক্টটিকে কয়েকটি অবজেক্টে টুকরো টুকরো করা উচিত।
পরিশেষে, কিছু লোক অঞ্চল সম্পর্কিত জিনিসগুলিকে একত্রিত করার জন্য প্রলুব্ধ হয় : এর প্রতিনিধিদের সাথে একটি ইভেন্ট, বা আইও সম্পর্কিত অন্যান্য পদ্ধতিগুলির সাথে আইও সম্পর্কিত একটি পদ্ধতি ইত্যাদি প্রথম ক্ষেত্রে, এটি একটি জগাখিচুড়ি হয়ে যায় যা বজায় রাখা কঠিন maintain , পড়ুন এবং বুঝতে। দ্বিতীয় ক্ষেত্রে, আরও ভাল নকশা সম্ভবত বেশ কয়েকটি ক্লাস তৈরি করা হবে।
অঞ্চলগুলির জন্য কি ভাল ব্যবহার আছে?
নং কোডটি আছে: একটি লিগ্যাসি ব্যবহার ছিল। তবুও, কোড জেনারেশন সরঞ্জামগুলির পরিবর্তে কেবল আংশিক ক্লাস ব্যবহার করতে হবে। যদি সি # এর অঞ্চলে সমর্থন থাকে তবে এটি বেশিরভাগ ক্ষেত্রে এই উত্তরাধিকারটি ব্যবহার করার কারণে এবং এখন যেহেতু খুব বেশি লোক তাদের কোডগুলিতে অঞ্চল ব্যবহার করেছেন, বিদ্যমান কোডবেসগুলি না ভেঙে এগুলি সরিয়ে ফেলা অসম্ভব।
সম্পর্কে এটি সম্পর্কে চিন্তা করুন goto
। যে ভাষা বা আইডিই কোনও বৈশিষ্ট্য সমর্থন করে তার অর্থ এই নয় যে এটি প্রতিদিন ব্যবহার করা উচিত। স্টাইলকপ SA1124 নিয়মটি পরিষ্কার: আপনার অঞ্চলগুলি ব্যবহার করা উচিত নয়। কখনও।
উদাহরণ
আমি বর্তমানে আমার সহকর্মীর কোডের একটি কোড পর্যালোচনা করছি। কোডবেজে অনেকগুলি অঞ্চল রয়েছে এবং অঞ্চলগুলি কীভাবে ব্যবহার করা যায় না এবং কেন অঞ্চলগুলি খারাপ কোডের দিকে পরিচালিত করে, উভয়েরই নিখুঁত উদাহরণ এটি। এখানে কিছু উদাহরন:
4000 এলওসি দানব:
আমি সম্প্রতি প্রোগ্রামার্স.এস.এই কোথাও পড়েছি যে যখন কোনও ফাইলে খুব বেশি using
গুলি থাকে ("অপ্রয়োজনীয় ব্যবহারগুলি সরান" কমান্ড কার্যকর করার পরে), এই ফাইলের অভ্যন্তর শ্রেণিটি খুব বেশি কাজ করছে এটি একটি ভাল লক্ষণ। ফাইলের আকারের ক্ষেত্রেও এটি একই প্রযোজ্য।
কোডটি পর্যালোচনা করার সময়, আমি একটি 4000 এলওসি ফাইল জুড়ে এসেছি। দেখা গেছে যে এই কোডটির লেখক কেবল একই 15-লাইন পদ্ধতিটি কয়েকবার কপি-পেস্ট করেছেন, ভেরিয়েবলের নাম এবং পরিবর্তিত পদ্ধতিটির নাম পরিবর্তন করে। একটি সাধারণ রেজেক্স কেবল কয়েকটি জেনেরিক যুক্ত করে 4000 এলওসি থেকে 500 এলওসি থেকে ফাইলটি ছাঁটাই করার অনুমতি দিয়েছে; আমি যথেষ্ট নিশ্চিত যে আরও চতুর রিফ্যাক্টরিংয়ের সাথে এই বর্গটি কয়েক ডজন লাইনে কমিয়ে দেওয়া যেতে পারে।
অঞ্চলগুলি ব্যবহার করে, লেখক নিজেকে এই উত্থাপনে উত্সাহিত করেছিলেন যে কোডটি বজায় রাখা এবং খারাপভাবে লেখা অসম্ভব, এবং কোডটি রিফ্যাক্টরের পরিবর্তে ভারিভাবে সদৃশ করা যায়।
অঞ্চল "একটি কর", অঞ্চল "কর বি":
আর একটি দুর্দান্ত উদাহরণ ছিল একটি দানব সূচনা পদ্ধতি যা কেবল টাস্ক 1, তারপরে টাস্ক 2, তারপর টাস্ক 3 ইত্যাদি করত etc. এখানে পাঁচ বা ছয়টি কাজ ছিল যা সম্পূর্ণ স্বাধীন ছিল, প্রত্যেকে একটি ধারক শ্রেণিতে কিছু শুরু করে। এই সমস্ত কাজকে একটি পদ্ধতিতে বিভক্ত করা হয়েছিল, এবং অঞ্চলগুলিতে বিভক্ত করা হয়েছিল।
এর একটি সুবিধা ছিল:
- অঞ্চলটির নামগুলি দেখে পদ্ধতিটি বোঝা বেশ স্পষ্ট ছিল। এটি বলা হচ্ছে, একবার রিফ্যাক্ট করা একই পদ্ধতিটি আসল হিসাবে পরিষ্কার হবে।
অন্যদিকে, বিষয়গুলি একাধিক ছিল:
অঞ্চলগুলির মধ্যে নির্ভরতা থাকলে এটি স্পষ্ট ছিল না। আশা করি, ভেরিয়েবলগুলির পুনরায় ব্যবহার হয়নি; অন্যথায়, রক্ষণাবেক্ষণ আরও দুঃস্বপ্ন হতে পারে।
পদ্ধতিটি পরীক্ষা করা প্রায় অসম্ভব ছিল। আপনি কীভাবে সহজেই জানবেন যে পদ্ধতিটি একবারে বিশটি কাজ করে তা সঠিকভাবে সম্পাদন করে?
ক্ষেত্র অঞ্চল, বৈশিষ্ট্য অঞ্চল, নির্মাতা অঞ্চল:
পর্যালোচনা কোডটিতে অনেকগুলি অঞ্চল একত্রে সমস্ত ক্ষেত্রকে একত্রিত করা, সমস্ত সম্পত্তি একসাথে করা ইত্যাদি ছিল contained এটির একটি সুস্পষ্ট সমস্যা ছিল: উত্স কোড বৃদ্ধি growth
আপনি যখন কোনও ফাইল খোলেন এবং ক্ষেত্রগুলির একটি বিশাল তালিকা দেখতে পান, আপনি প্রথমে ক্লাসটি রিফ্যাক্টর করতে আরও ঝোঁক হন, তারপরে কোড সহ কাজ করুন। অঞ্চলগুলির সাথে, আপনি স্টাফগুলি ভেঙে ফেলা এবং এটি ভুলে যাওয়ার অভ্যাস গ্রহণ করেন।
আর একটি সমস্যা হ'ল আপনি যদি এটি সর্বত্র করেন তবে আপনি নিজেকে একটি-ব্লক অঞ্চল তৈরি করতে দেখবেন, যার কোনও অর্থ নেই। এটি আসলে আমি কোডটি পর্যালোচনা করেছিলাম যেখানে সেখানে #region Constructor
একজন কনস্ট্রাক্টর প্রচুর ছিল ।
অবশেষে ক্ষেত্র, বৈশিষ্ট্য, নির্মাতা ইত্যাদি ইতিমধ্যে ক্রমযুক্ত হওয়া উচিত । যদি সেগুলি হয় এবং তারা কনভেনশনগুলির সাথে মিলিত হয় (বড় ধরণের অক্ষর ইত্যাদির সাথে ধ্রুবকগুলি শুরু করে) তবে এটি ইতিমধ্যে পরিষ্কার হয়ে গেছে যে ধরণের উপাদানগুলি কোথায় থামবে এবং অন্যান্য শুরু হয়, তাই আপনার জন্য স্পষ্টভাবে অঞ্চলগুলি তৈরি করার দরকার নেই।