সফটওয়্যার লেখা জটিলতা এবং সরলতার মধ্যে একটি যুদ্ধ। দুটির মধ্যে ভারসাম্য রাখা কঠিন। ট্রেড-অফ দীর্ঘ অরক্ষণীয় পদ্ধতি এবং অত্যধিক বিমূর্ততার মধ্যে। যেকোনো দিকে খুব বেশি ঝুঁকে পড়া কোড পাঠযোগ্যতা হ্রাস করে এবং ত্রুটির সম্ভাবনা বৃদ্ধি করে।
ত্রুটি এড়ানো যায়? নাসা চেষ্টা করে, কিন্তু তারা প্রচুর পরিমাণে পরীক্ষাও করে। তাদের সফটওয়্যার আক্ষরিক অর্থে মিশন সমালোচনামূলক – একটি এককালীন চুক্তি। বেশিরভাগ সংস্থার জন্য, এটি কেস নয় এবং বড় পরিমাণে পরীক্ষা ব্যয়বহুল এবং অব্যবহারিক। পরীক্ষার কোনো বিকল্প নেই থাকলেও, পরীক্ষা ছাড়াই ত্রুটি-প্রতিরোধী কোড লেখা সম্ভব।
২০ বছরের কোডিং এবং অ্যাপ্লিকেশন আর্কিটেকচারে, আমি ত্রুটি কমাতে চারটি অনুশীলন চিহ্নিত করেছি। প্রথম দুটি অনুশীলন ত্রুটির প্রবর্তন সীমিত করে এবং শেষ দুটি অনুশীলন ত্রুটি প্রকাশ করে। প্রতিটি অনুশীলন নিজেই একটি বিশাল বিষয় যেখানে অনেক বই লেখা হয়েছে। আমি প্রতিটি অনুশীলনকে কয়েক অনুচ্ছেদে সংক্ষিপ্ত করেছি এবং যখন সম্ভব অতিরিক্ত তথ্যের লিঙ্ক প্রদান করেছি।
১. সহজ কোড লিখুন
সহজ হওয়া সহজ হওয়া উচিত, কিন্তু এটি নয়। সহজ কোড লেখা কঠিন।
কেউ কেউ এটি পড়ে ভাববে এটি সহজ ভাষার বৈশিষ্ট্য ব্যবহার করার অর্থ, কিন্তু এটি কেস নয় — সহজ কোড বোবা কোড নয়।
এটি উদ্দেশ্যমূলক রাখতে, আমি সাইক্লোম্যাটিক জটিলতা একটি পরিমাপ হিসাবে ব্যবহার করছি। জটিলতা পরিমাপ করার অন্যান্য উপায় এবং অন্যান্য ধরনের জটিলতা রয়েছে, আমি পরবর্তী নিবন্ধগুলিতে এই বিষয়গুলি অন্বেষণ করার আশা করি।
মাইক্রোসফট সাইক্লোম্যাটিক জটিলতা সংজ্ঞায়িত করে:
সাইক্লোম্যাটিক জটিলতা পদ্ধতির মাধ্যমে রৈখিকভাবে-স্বাধীন পথের সংখ্যা পরিমাপ করে, যা শর্তসাপেক্ষ শাখার সংখ্যা এবং জটিলতা দ্বারা নির্ধারিত হয়। কম সাইক্লোম্যাটিক জটিলতা সাধারণত একটি পদ্ধতি নির্দেশ করে যা বোঝা, পরীক্ষা এবং রক্ষণাবেক্ষণ করা সহজ।
কম সাইক্লোম্যাটিক জটিলতা কী? মাইক্রোসফট সাইক্লোম্যাটিক জটিলতা ২৫ এর নিচে রাখার সুপারিশ করে।
সৎ হতে গেলে, আমি মাইক্রোসফটের সাইক্লোম্যাটিক জটিলতা ২৫ এর সুপারিশ খুব বেশি বলে মনে করি। রক্ষণাবেক্ষণযোগ্যতা এবং জটিলতার জন্য, আমি আদর্শ পদ্ধতির আকার ১ থেকে ১০ লাইনের মধ্যে এবং সাইক্লোম্যাটিক জটিলতা ১ থেকে ৫ এর মধ্যে পেয়েছি।
বিল ওয়াগনার কার্যকর C#, দ্বিতীয় সংস্করণে পদ্ধতির আকার সম্পর্কে লিখেছেন:
মনে রাখবেন যে আপনার C# কোডকে মেশিন-এক্সিকিউটেবল কোডে অনুবাদ করা একটি দুই-ধাপের প্রক্রিয়া। C# কম্পাইলার IL তৈরি করে যা অ্যাসেম্বলিতে সরবরাহ করা হয়। JIT কম্পাইলার প্রতিটি পদ্ধতির জন্য (বা পদ্ধতির গ্রুপ, যখন ইনলাইনিং জড়িত থাকে) প্রয়োজন অনুযায়ী মেশিন কোড তৈরি করে। ছোট ফাংশন JIT কম্পাইলারের জন্য সেই খরচ পরিশোধ করা অনেক সহজ করে তোলে। ছোট ফাংশনগুলি ইনলাইনিংয়ের জন্য প্রার্থী হওয়ার সম্ভাবনা বেশি। এটি শুধুমাত্র ছোটতা নয়: সহজ নিয়ন্ত্রণ প্রবাহ সমানভাবে গুরুত্বপূর্ণ। ফাংশনের মধ্যে কম নিয়ন্ত্রণ শাখা JIT কম্পাইলারের জন্য ভেরিয়েবল এনরেজিস্টার করা সহজ করে তোলে। এটি শুধুমাত্র পরিষ্কার কোড লেখার জন্য ভাল অনুশীলন নয়; এটি কীভাবে আপনি রানটাইমে আরও দক্ষ কোড তৈরি করেন।
সাইক্লোম্যাটিক জটিলতা দৃষ্টিভঙ্গিতে রাখতে, নিম্নলিখিত পদ্ধতির সাইক্লোম্যাটিক জটিলতা ১২।
public string ComplexityOf12(int status)
{
var isTrue = true;
var myString = "Chuck";
if (isTrue)
{
if (isTrue)
{
myString = string.Empty;
isTrue = false;
for (var index = 0; index < 10; index++)
{
isTrue |= Convert.ToBoolean(new Random().Next());
}
if (status == 1 || status == 3)
{
switch (status)
{
case 3:
return "Bye";
case 1:
if (status % 1 == 0)
{
myString = "Super";
}
break;
}
return myString;
}
}
}
if (!isTrue)
{
myString = "New";
}
switch (status)
{
case 300:
myString = "3001";
break;
case 400:
myString = "4003";
break;
}
return myString;
}
সাধারণত গৃহীত জটিলতা অনুমান জটিলতা এবং ত্রুটির মধ্যে একটি ইতিবাচক সম্পর্ক বিদ্যমান বলে অনুমান করে।
পূর্ববর্তী লাইনটি একটু জটিল। সবচেয়ে সহজ শর্তে — কোড সহজ রাখা আপনার ত্রুটির হার হ্রাস করে।
২. পরীক্ষাযোগ্য কোড লিখুন
গবেষণা দেখিয়েছে যে পরীক্ষাযোগ্য কোড লেখা, প্রকৃত পরীক্ষা না লিখে ত্রুটির ঘটনা হ্রাস করে। এটি এত গুরুত্বপূর্ণ এবং গভীর যে এটি পুনরাবৃত্তির প্রয়োজন: পরীক্ষাযোগ্য কোড লেখা, প্রকৃত পরীক্ষা না লিখে, ত্রুটির ঘটনা হ্রাস করে।
এটি প্রশ্ন উত্থাপন করে, পরীক্ষাযোগ্য কোড কী?
আমি পরীক্ষাযোগ্য কোডকে এমন কোড হিসাবে সংজ্ঞায়িত করি যা বিচ্ছিন্নভাবে পরীক্ষা করা যায়। এর মানে সমস্ত নির্ভরতা একটি পরীক্ষা থেকে মক করা যায়। একটি নির্ভরতার উদাহরণ একটি ডাটাবেস প্রশ্ন। একটি পরীক্ষায়, ডেটা মক (জাল) করা হয় এবং প্রত্যাশিত আচরণের একটি দাবি করা হয়। যদি দাবিটি সত্য হয়, পরীক্ষা পাস হয়, যদি না হয় তা ব্যর্থ হয়।
পরীক্ষাযোগ্য কোড লেখা কঠিন মনে হতে পারে, কিন্তু, বাস্তবে, এটি নিয়ন্ত্রণের বিপরীতকরণ (নির্ভরতা ইনজেকশন) এবং S.O.L.I.D নীতি অনুসরণ করার সময় সহজ। আপনি সহজতায় অবাক হবেন এবং ভাববেন কেন এটি এত দীর্ঘ সময় নিয়েছে এই উপায়ে লেখা শুরু করতে।
৩. কোড পর্যালোচনা
একটি উন্নয়ন দল গ্রহণ করতে পারে এমন সবচেয়ে প্রভাবশালী অনুশীলনগুলির মধ্যে একটি হল কোড পর্যালোচনা।
কোড পর্যালোচনা ডেভেলপারদের মধ্যে জ্ঞান ভাগাভাগি সহজতর করে। অভিজ্ঞতা থেকে বলছি, অন্যান্য ডেভেলপারদের সাথে কোড নিয়ে খোলামেলা আলোচনা আমার কোড লেখার দক্ষতায় সবচেয়ে বেশি প্রভাব ফেলেছে।
কোড সম্পূর্ণ বইতে, স্টিভ ম্যাকনেল দ্বারা, স্টিভ কোড পর্যালোচনার সুবিধা সম্পর্কে অসংখ্য কেস স্টাডি প্রদান করে:
- AT&T-এর ২০০ এরও বেশি লোকের একটি সংস্থার একটি অধ্যয়ন সংস্থা পর্যালোচনা চালু করার পরে উৎপাদনশীলতায় ১৪ শতাংশ বৃদ্ধি এবং ত্রুটিতে ৯০ শতাংশ হ্রাস রিপোর্ট করেছে।
- Aetna বীমা কোম্পানি পরিদর্শন ব্যবহার করে একটি প্রোগ্রামে ৮২ শতাংশ ত্রুটি খুঁজে পেয়েছে এবং তার উন্নয়ন সম্পদ ২০ শতাংশ হ্রাস করতে সক্ষম হয়েছে।
- একই গ্রুপের মানুষ দ্বারা উন্নত ১১টি প্রোগ্রামের একটি গ্রুপে, প্রথম ৫টি পর্যালোচনা ছাড়াই উন্নত হয়েছিল। অবশিষ্ট ৬টি পর্যালোচনা সহ উন্নত হয়েছিল। সমস্ত প্রোগ্রাম উৎপাদনে প্রকাশিত হওয়ার পরে, প্রথম ৫টির গড় ১০০ লাইন কোডে ৪.৫ ত্রুটি ছিল। যা পরিদর্শন করা হয়েছিল তার গড় মাত্র ১০০ এ ০.৮২ ত্রুটি ছিল। পর্যালোচনা ত্রুটি ৮০ শতাংশেরও বেশি কমিয়েছে।
যদি সেই সংখ্যাগুলি আপনাকে কোড পর্যালোচনা গ্রহণ করতে প্ররোচিত না করে, তাহলে আপনি জনি পেচেকের টেক দিস জব অ্যান্ড শোভ ইট গাইতে গাইতে একটি কালো গর্তে ভেসে যেতে নিয়তি।
৪. ইউনিট পরীক্ষা
আমি স্বীকার করি, যখন আমি একটি সময়সীমার বিরুদ্ধে থাকি পরীক্ষা প্রথম জিনিস যা যায়। কিন্তু পরীক্ষার সুবিধা অস্বীকার করা যায় না যেমন নিম্নলিখিত গবেষণা চিত্রিত করে।
মাইক্রোসফট ইউনিট পরীক্ষার কার্যকারিতা সম্পর্কে একটি অধ্যয়ন পরিচালনা করেছে। তারা খুঁজে পেয়েছে যে কোডিং সংস্করণ ২ (সংস্করণ ১ এর কোনো পরীক্ষা ছিল না) স্বয়ংক্রিয় পরীক্ষার সাথে অবিলম্বে ত্রুটি ২০ শতাংশ হ্রাস করেছে, কিন্তু অতিরিক্ত ৩০ শতাংশের খরচে।
আরেকটি অধ্যয়ন পরীক্ষা চালিত উন্নয়ন (TDD) দেখেছে। তারা TDD ব্যবহার না করে অনুরূপ প্রকল্পের তুলনায় দুই গুণেরও বেশি কোড গুণমান বৃদ্ধি পর্যবেক্ষণ করেছে। TDD প্রকল্পগুলি গড়ে উন্নয়নে ১৫ শতাংশ বেশি সময় নিয়েছে। TDD এর একটি পার্শ্ব-প্রতিক্রিয়া ছিল পরীক্ষাগুলি লাইব্রেরি এবং API এর জন্য ডকুমেন্টেশন হিসাবে কাজ করেছে।
সর্বশেষ, পরীক্ষা কভারেজ এবং পোস্ট-যাচাইকরণ ত্রুটি সম্পর্কে একটি অধ্যয়নে:
… আমরা উভয় প্রকল্পে পরীক্ষা কভারেজ বৃদ্ধি ক্ষেত্র রিপোর্ট করা সমস্যা হ্রাসের সাথে যুক্ত পাই যখন প্রাক-প্রকাশ পরিবর্তনের সংখ্যার জন্য সামঞ্জস্য করা হয়…
একটি উদাহরণ
নিম্নলিখিত কোডের সাইক্লোম্যাটিক জটিলতা ৪।
public void SendUserHadJoinedEmailToAdministrator(DataAccess.Database.Schema.dbo.Agency agency, User savedUser)
{
AgencySettingsRepository agencySettingsRepository = new AgencySettingsRepository();
var agencySettings = agencySettingsRepository.GetById(agency.Id);
if (agencySettings != null)
{
var newAuthAdmin = agencySettings.NewUserAuthorizationContact;
if (newAuthAdmin.IsNotNull())
{
EmailService emailService = new EmailService();
emailService.SendTemplate(new[] { newAuthAdmin.Email }, GroverConstants.EmailTemplate.NewUserAdminNotification, s =>
{
s.Add(new EmailToken { Token = "Domain", Value = _settings.Domain });
s.Add(new EmailToken
{
Token = "Subject",
Value =
string.Format("New User {0} has joined {1} on myGrover.", savedUser.FullName(), agency.Name)
});
s.Add(new EmailToken { Token = "Name", Value = savedUser.FullName() });
return s;
});
}
}
}
উপরের কোডের পরীক্ষাযোগ্যতা পরীক্ষা করি।
এটি সহজ কোড?
হ্যাঁ, এটি, সাইক্লোম্যাটিক জটিলতা ৫ এর নিচে।
কোনো নির্ভরতা আছে?
হ্যাঁ। ২টি সেবা আছে AgencySettingsRepository এবং EmailService।
সেবাগুলি মক করা যায়?
না, তাদের সৃষ্টি পদ্ধতির মধ্যে লুকানো।
কোড পরীক্ষাযোগ্য?
না, এই কোড পরীক্ষাযোগ্য নয় কারণ আমরা AgencySettingsRepository এবং EmailService মক করতে পারি না।
পুনর্গঠিত কোডের উদাহরণ
আমরা এই কোড পরীক্ষাযোগ্য কীভাবে করতে পারি?
আমরা ইনজেক্ট করি (কনস্ট্রাক্টর ইনজেকশন ব্যবহার করে) AgencySettingsRepository এবং EmailService নির্ভরতা হিসাবে। এটি আমাদের একটি পরীক্ষা থেকে তাদের মক করতে এবং বিচ্ছিন্নভাবে পরীক্ষা করতে দেয়।
নিচে পুনর্গঠিত সংস্করণ।
লক্ষ্য করুন কীভাবে সেবাগুলি কনস্ট্রাক্টরে ইনজেক্ট করা হয়। এটি আমাদের নিয়ন্ত্রণ করতে দেয় কোন বাস্তবায়ন SendMail কনস্ট্রাক্টরে পাস করা হয়। তারপর ডামি ডেটা পাস করা এবং সেবা পদ্ধতি কল ইন্টারসেপ্ট করা সহজ।
public class SendEmail
{
private IAgencySettingsRepository _agencySettingsRepository;
private IEmailService _emailService;
public SendEmail(IAgencySettingsRepository agencySettingsRepository, IEmailService emailService)
{
_agencySettingsRepository = agencySettingsRepository;
_emailService = emailService;
}
public void SendUserHadJoinedEmailToAdministrator(DataAccess.Database.Schema.dbo.Agency agency, User savedUser)
{
var agencySettings = _agencySettingsRepository.GetById(agency.Id);
if (agencySettings != null)
{
var newAuthAdmin = agencySettings.NewUserAuthorizationContact;
if (newAuthAdmin.IsNotNull())
{
_emailService.SendTemplate(new[] { newAuthAdmin.Email },
GroverConstants.EmailTemplate.NewUserAdminNotification, s =>
{
s.Add(new EmailToken { Token = "Domain", Value = _settings.Domain });
s.Add(new EmailToken
{
Token = "Subject",
Value = string.Format("New User {0} has joined {1} on myGrover.", savedUser.FullName(), agency.Name)
});
s.Add(new EmailToken { Token = "Name", Value = savedUser.FullName() });
return s;
});
}
}
}
}
পরীক্ষা উদাহরণ
নিচে বিচ্ছিন্নভাবে পরীক্ষার একটি উদাহরণ। আমরা মকিং ফ্রেমওয়ার্ক FakeItEasy ব্যবহার করছি।
[Test]
public void TestEmailService()
{
//Given
//Using FakeItEasy mocking framework
var repository = A<IAgencySettingsRepository>.Fake();
var service = A<IEmailService>.Fake();
var agency = new Agency { Name = "Acme Inc." };
var user = new User { FirstName = "Chuck", LastName = "Conway", Email = "chuck.conway@fakedomain.com" }
//When
var sendEmail = new SendEmail(repository, service);
sendEmail.SendUserHadJoinedEmailToAdministrator(agency, user);
//Then
//An exception is thrown when this is not called.
A.CallTo(() => service.SendTemplate(A<Agency>.Ignore, A<User>.Ignore)).MustHaveHappened();
}
সমাপনী
ত্রুটি প্রতিরোধী কোড লেখা আশ্চর্
লেখক: চাক কনওয়ে একজন এআই ইঞ্জিনিয়ার যার কাছে প্রায় ৩০ বছরের সফটওয়্যার ইঞ্জিনিয়ারিং অভিজ্ঞতা রয়েছে। তিনি ব্যবহারিক এআই সিস্টেম তৈরি করেন—কন্টেন্ট পাইপলাইন, অবকাঠামো এজেন্ট এবং সরঞ্জাম যা বাস্তব সমস্যার সমাধান করে—এবং তার শেখার বিষয়গুলি শেয়ার করেন। তার সাথে সোশ্যাল মিডিয়ায় সংযোগ করুন: X (@chuckconway) অথবা তাকে YouTube এবং SubStack এ দেখুন।