
সফটওয়্যার লেখা জটিলতা এবং সরলতার মধ্যে একটি যুদ্ধ। এই দুটির মধ্যে ভারসাম্য রক্ষা করা কঠিন। এটি দীর্ঘ রক্ষণাবেক্ষণযোগ্য নয় এমন পদ্ধতি এবং অত্যধিক বিমূর্ততার মধ্যে একটি ট্রেড-অফ। যেকোনো দিকে অত্যধিক ঝুঁকে পড়া কোডের পাঠযোগ্যতা ক্ষতিগ্রস্ত করে এবং ত্রুটির সম্ভাবনা বৃদ্ধি করে।
ত্রুটি কি এড়ানো যায়? NASA চেষ্টা করে, কিন্তু তারা প্রচুর পরিমাণে পরীক্ষা করে। তাদের সফটওয়্যার আক্ষরিক অর্থেই মিশন ক্রিটিক্যাল – একটি একক সুযোগের ব্যাপার। বেশিরভাগ সংস্থার জন্য, এটি এমন নয় এবং বড় পরিমাণে পরীক্ষা ব্যয়বহুল এবং অব্যবহারিক। যদিও পরীক্ষার কোনো বিকল্প নেই, পরীক্ষা ছাড়াই ত্রুটি প্রতিরোধী কোড লেখা সম্ভব।
২০ বছরের কোডিং এবং অ্যাপ্লিকেশন আর্কিটেক্টিং এর অভিজ্ঞতায়, আমি ত্রুটি কমানোর জন্য চারটি অনুশীলন চিহ্নিত করেছি। প্রথম দুটি অনুশীলন ত্রুটির প্রবেশ সীমিত করে এবং শেষ দুটি অনুশীলন ত্রুটি প্রকাশ করে। প্রতিটি অনুশীলন নিজেই একটি বিস্তৃত বিষয় যার উপর অনেক বই লেখা হয়েছে। আমি প্রতিটি অনুশীলনকে কয়েকটি অনুচ্ছেদে সংক্ষিপ্ত করেছি এবং সম্ভব হলে অতিরিক্ত তথ্যের লিঙ্ক প্রদান করেছি।
১. সরল কোড লিখুন
সরল হওয়া সহজ হওয়া উচিত, কিন্তু তা নয়। সরল কোড লেখা কঠিন।
কেউ কেউ এটি পড়ে ভাববেন এর মানে সরল ভাষার বৈশিষ্ট্য ব্যবহার করা, কিন্তু এটি সেই ক্ষেত্রে নয় — সরল কোড মানে বোকা কোড নয়।
এটি বস্তুনিষ্ঠ রাখতে, আমি সাইক্লোম্যাটিক জটিলতাকে একটি পরিমাপ হিসেবে ব্যবহার করছি। জটিলতা পরিমাপের অন্যান্য উপায় এবং অন্যান্য ধরনের জটিলতা রয়েছে, আমি পরবর্তী নিবন্ধগুলিতে এই বিষয়গুলি অন্বেষণ করার আশা করি।
Microsoft সাইক্লোম্যাটিক জটিলতাকে সংজ্ঞায়িত করে:
সাইক্লোম্যাটিক জটিলতা পদ্ধতির মধ্য দিয়ে রৈখিক-স্বাধীন পথের সংখ্যা পরিমাপ করে, যা শর্তাধীন শাখার সংখ্যা এবং জটিলতা দ্বারা নির্ধারিত হয়। একটি কম সাইক্লোম্যাটিক জটিলতা সাধারণত এমন একটি পদ্ধতি নির্দেশ করে যা বুঝতে, পরীক্ষা করতে এবং রক্ষণাবেক্ষণ করতে সহজ।
কম সাইক্লোম্যাটিক জটিলতা কী? Microsoft সাইক্লোম্যাটিক জটিলতা ২৫ এর নিচে রাখার সুপারিশ করে।
সত্যি বলতে, আমি Microsoft এর ২৫ সাইক্লোম্যাটিক জটিলতার সুপারিশ খুব বেশি বলে মনে করেছি। রক্ষণাবেক্ষণযোগ্যতা এবং জটিলতার জন্য, আমি আদর্শ পদ্ধতির আকার ১ থেকে ১০ লাইনের মধ্যে এবং সাইক্লোম্যাটিক জটিলতা ১ থেকে ৫ এর মধ্যে পেয়েছি।
Bill Wagner তার Effective C#, Second Edition বইতে পদ্ধতির আকার সম্পর্কে লিখেছেন:
মনে রাখবেন যে আপনার 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;
}
একটি সাধারণভাবে গৃহীত জটিলতা অনুমান অনুমান করে জটিলতা এবং ত্রুটির মধ্যে একটি ইতিবাচক সম্পর্ক বিদ্যমান।
পূর্ববর্তী লাইনটি কিছুটা জটিল। সহজ ভাষায় — কোড সরল রাখা আপনার ত্রুটির হার কমায়।
২. পরীক্ষাযোগ্য কোড লিখুন
গবেষণায় দেখা গেছে যে পরীক্ষাযোগ্য কোড লেখা, প্রকৃত পরীক্ষা না লিখেও ত্রুটির ঘটনা কমায়। এটি এত গুরুত্বপূর্ণ এবং গভীর যে এটি পুনরাবৃত্তি করা প্রয়োজন: পরীক্ষাযোগ্য কোড লেখা, প্রকৃত পরীক্ষা না লিখেও, ত্রুটির ঘটনা কমায়।
এটি প্রশ্ন তোলে, পরীক্ষাযোগ্য কোড কী?
আমি পরীক্ষাযোগ্য কোডকে এমন কোড হিসেবে সংজ্ঞায়িত করি যা বিচ্ছিন্নভাবে পরীক্ষা করা যায়। এর মানে সমস্ত নির্ভরতা একটি পরীক্ষা থেকে মক করা যেতে পারে। নির্ভরতার একটি উদাহরণ হল ডাটাবেস কোয়েরি। একটি পরীক্ষায়, ডেটা মক (নকল) করা হয় এবং প্রত্যাশিত আচরণের একটি দাবি করা হয়। যদি দাবিটি সত্য হয়, পরীক্ষা পাস হয়, না হলে ব্যর্থ হয়।
পরীক্ষাযোগ্য কোড লেখা কঠিন মনে হতে পারে, কিন্তু, প্রকৃতপক্ষে, Inversion of Control (Dependency Injection) এবং S.O.L.I.D নীতিগুলি অনুসরণ করার সময় এটি সহজ। আপনি সহজতায় অবাক হবেন এবং ভাববেন কেন এইভাবে লেখা শুরু করতে এত সময় লেগেছে।
৩. কোড রিভিউ
একটি ডেভেলপমেন্ট টিম যে সবচেয়ে প্রভাবশালী অনুশীলন গ্রহণ করতে পারে তা হল কোড রিভিউ।
কোড রিভিউ ডেভেলপারদের মধ্যে জ্ঞান ভাগাভাগি সহজ করে। অভিজ্ঞতা থেকে বলতে পারি, অন্যান্য ডেভেলপারদের সাথে খোলামেলাভাবে কোড নিয়ে আলোচনা আমার কোড লেখার দক্ষতায় সবচেয়ে বেশি প্রভাব ফেলেছে।
Steve McConnell এর Code Complete বইতে, Steve কোড রিভিউর সুবিধার উপর অসংখ্য কেস স্টাডি প্রদান করেছেন:
- AT&T এর ২০০ জনেরও বেশি লোক নিয়ে একটি সংস্থার একটি গবেষণায় রিভিউ চালু করার পর উৎপাদনশীলতায় ১৪ শতাংশ বৃদ্ধি এবং ত্রুটিতে ৯০ শতাংশ হ্রাসের রিপোর্ট করা হয়েছে।
- Aetna Insurance Company ইনস্পেকশন ব্যবহার করে একটি প্রোগ্রামের ৮২ শতাংশ ত্রুটি খুঁজে পেয়েছে এবং তাদের ডেভেলপমেন্ট রিসোর্স ২০ শতাংশ কমাতে সক্ষম হয়েছে।
- একই গ্রুপের লোকদের দ্বারা ডেভেলপ করা ১১টি প্রোগ্রামের একটি গ্রুপে, প্রথম ৫টি রিভিউ ছাড়াই ডেভেলপ করা হয়েছিল। বাকি ৬টি রিভিউ সহ ডেভেলপ করা হয়েছিল। সমস্ত প্রোগ্রাম প্রোডাকশনে রিলিজ হওয়ার পর, প্রথম ৫টিতে প্রতি ১০০ লাইন কোডে গড়ে ৪.৫টি ত্রুটি ছিল। যে ৬টি ইনস্পেক্ট করা হয়েছিল তাতে গড়ে মাত্র ০.৮২টি ত্রুটি ছিল। রিভিউ ত্রুটি ৮০ শতাংশেরও বেশি কমিয়েছে।
যদি এই সংখ্যাগুলি আপনাকে কোড রিভিউ গ্রহণ করতে প্রভাবিত না করে, তাহলে আপনি Johnny Paycheck’s Take This Job and Shove It গাইতে গাইতে একটি ব্ল্যাক হোলে ভেসে যেতে নিয়তিবদ্ধ।
৪. ইউনিট টেস্টিং
আমি স্বীকার করি, যখন আমি একটি ডেডলাইনের বিরুদ্ধে থাকি তখন পরীক্ষা প্রথম জিনিস যা চলে যায়। কিন্তু পরীক্ষার সুবিধা অস্বীকার করা যায় না যেমন নিম্নলিখিত গবেষণাগুলি চিত্রিত করে।
Microsoft ইউনিট টেস্টিংয়ের কার্যকারিতা নিয়ে একটি গবেষণা করেছে। তারা দেখেছে যে স্বয়ংক্রিয় পরীক্ষা সহ কোডিং সংস্করণ ২ (সংস্করণ ১ এ কোনো পরীক্ষা ছিল না) অবিলম্বে ত্রুটি ২০% কমিয়েছে, কিন্তু অতিরিক্ত ৩০% খরচে।
আরেকটি গবেষণা Test Driven Development (TDD) দেখেছে। তারা TDD ব্যবহার না করা অনুরূপ প্রকল্পের তুলনায় কোডের গুণমানে দুই গুণেরও বেশি বৃদ্ধি পর্যবেক্ষণ করেছে। TDD প্রকল্পগুলি ডেভেলপ করতে গড়ে ১৫% বেশি সময় নিয়েছে। TDD এর একটি পার্শ্ব-প্রতিক্রিয়া ছিল পরীক্ষাগুলি লাইব্রেরি এবং API এর জন্য ডকুমেন্টেশন হিসেবে কাজ করেছে।
অবশেষে, Test Coverage and Post-Verification Defects এর একটি গবেষণায়:
… আমরা দেখতে পাই যে উভয় প্রকল্পেই পরীক্ষা কভারেজ বৃদ্ধি প্রি-রিলিজ পরিবর্তনের সংখ্যার জন্য সমন্বয় করা হলে ফিল্ড রিপোর্ট করা সমস্যা হ্রাসের সাথে যুক্ত…
একটি উদাহরণ
নিম্নলিখিত কোডের সাইক্লোম্যাটিক জটিলতা ৪।
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
//FakeItEasy মকিং ফ্রেমওয়ার্ক ব্যবহার করে
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
//এটি কল না হলে একটি ব্যতিক্রম নিক্ষেপ করা হয়।
A.CallTo(() => service.SendTemplate(A<Agency>.Ignore, A<User>.Ignore)).MustHaveHappened();
}
সমাপনী
ত্রুটি প্রতিরোধী কোড লেখা আশ্চর্যজনকভাবে সহজ। ভুল বুঝবেন না, আপনি কখনও ত্র
লেখক: চাক কনওয়ে সফটওয়্যার ইঞ্জিনিয়ারিং এবং জেনারেটিভ এআই-তে বিশেষজ্ঞ। তার সাথে সোশ্যাল মিডিয়ায় যোগাযোগ করুন: X (@chuckconway) অথবা তাকে YouTube-এ দেখুন।