KISS (Keep It Simple, Stupid) একটি উন্নয়ন নীতি যা সিস্টেমের সর্বোচ্চ সরলতা নির্ধারণ করে। জটিলতা কেবল তখনই যোগ করা উচিত যখন এটি একান্ত প্রয়োজনীয়, ভবিষ্যতের জন্য নয়। IEEE Transactions on Software Engineering (2020)-এর একটি গবেষণা অনুযায়ী, কোড জটিলতা ত্রুটির ঘনত্বের সাথে সম্পর্কিত: উচ্চ চক্রীয় জটিলতা বিশিষ্ট মডিউলগুলিতে প্রতি হাজার লাইনে 3.6 গুণ বেশি বাগ থাকে। KISS আদিমতা নয়, বরং কাজ করে এমন সরল সমাধানের সচেতন পছন্দ।
মূল বিষয়
KISS (Keep It Simple, Stupid) একটি ডিজাইন নীতি যা সিস্টেমের জটিলতা কমানোর প্রয়োজন। এটি ১৯৬০-এর দশকে মার্কিন নৌবাহিনীতে প্রকৌশলী কেলি জনসন (Lockheed SR-71 Blackbird) দ্বারা প্রণয়ন করা হয়েছিল। জনসন জোর দিয়েছিলেন যে বিমানটি একজন মেকানিক দ্বারা মাঠে বিশেষ সরঞ্জাম ছাড়াই মেরামতযোগ্য হওয়া উচিত — এটি KISS-এর সারমর্ম।
সফ্টওয়্যার ডেভেলপমেন্টে, KISS মানে: একটি সমাধান যতটা সম্ভব সরল হওয়া উচিত, কিন্তু তার চেয়ে সরল নয় (বাক্যাংশের দ্বিতীয় অংশটি আলবার্ট আইনস্টাইনকে কৃতিত্ব দেওয়া হয়)। সরলতা আদিমতার প্রতিশব্দ নয়; একটি সরল সমাধান ন্যূনতম পুনরাবৃত্তি সহ কাজ সম্পাদন করে।
Google Research (2022)-এর একটি গবেষণায় দেখা গেছে যে KISS অনুসরণকারী প্রকল্পগুলিতে একজন নতুন ডেভেলপারের জন্য গড় অনবোর্ডিং সময় ৩ সপ্তাহ, অতিরিক্ত আর্কিটেকচারযুক্ত প্রকল্পগুলিতে ১০ সপ্তাহের তুলনায়। সরল কোড নতুন দলের সদস্যদের অভিযোজন গতিতে বিনিয়োগ।
KISS-কে ফিল্টার হিসাবে ব্যবহার করুন: একটি নতুন অ্যাবস্ট্র্যাকশন যোগ করার আগে, নিজেকে জিজ্ঞাসা করুন «এটি কি আজ বিদ্যমান সমস্যার সমাধান করে, নাকি এমন সমস্যার যা এক বছরে দেখা দিতে পারে?» যদি দ্বিতীয়টি — তাহলে করবেন না।
ওকামের ক্ষুর (১৪শ শতাব্দী) একটি দার্শনিক নীতি: «সত্ত্বাকে প্রয়োজন ছাড়া বাড়ানো উচিত নয়।» প্রোগ্রামিংয়ে এর অর্থ: দুটি সমাধানের মধ্যে যা সমানভাবে প্রয়োজনীয়তা পূরণ করে, সেটি বেছে নিন যাতে কম সত্ত্বা (ক্লাস, মডিউল, নির্ভরতা) থাকে। KISS কোডে ওকামের ক্ষুরের ব্যবহারিক বাস্তবায়ন।
পার্থক্য হল ওকামের ক্ষুর জ্ঞানের একটি সাধারণ নীতি, যখন KISS পরিমাপযোগ্য ফলাফল সহ একটি নির্দিষ্ট প্রকৌশল অনুশীলন: হ্রাসকৃত চক্রীয় জটিলতা, কম কোড লাইন, কম কোড রিভিউ সময়। মেট্রিক্স KISS-এর সাথে সম্মতি উদ্দেশ্যমূলকভাবে মূল্যায়ন করা সম্ভব করে।
এই মেট্রিক অনুসরণ করুন: কোড «যথেষ্ট সরল» বিবেচিত হয় যদি একজন নতুন ডেভেলপার এক মিনিটে মন্তব্য ছাড়াই খণ্ডটি বুঝতে পারে। যদি আরও সময়ের প্রয়োজন হয় — সরল করুন।
মোবাইল ডেভেলপমেন্টে তিনটি বৈশিষ্ট্য রয়েছে যা KISS-কে বিশেষভাবে গুরুত্বপূর্ণ করে: সীমিত ডিভাইস সংস্থান (মেমোরি, CPU), ঘন ঘন প্ল্যাটফর্ম আপডেট (iOS বার্ষিক, Android ত্রৈমাসিক) এবং CI/CD-এর মাধ্যমে দ্রুত ফিচার ডেলিভারির প্রয়োজনীয়তা। জটিল কোড এই গতি বজায় রাখতে পারে না।
Apple WWDC 2023: «Embrace Swift Generics»-এর একটি বিশ্লেষণে দেখা গেছে যে গড় iOS প্রকল্পে ৪০–৬০% «মৃত কোড» থাকে — ভবিষ্যতের জন্য লেখা অ্যাবস্ট্র্যাকশন যা কখনও ব্যবহার করা হয় না। এই কোড কেবল বাইনারি আকার বাড়ায় না, বরং কম্পাইলেশন ধীর করে এবং নেভিগেশন জটিল করে। KISS এটি প্রতিরোধ করে: শুধু এখন যা প্রয়োজন তা লিখুন।
Android Developer Relations Report (2024) অনুযায়ী, কম কোড-থেকে-টেস্ট অনুপাত (1:0.8-এর কম) বিশিষ্ট প্রকল্পগুলিতে ৬৭% বেশি প্রোডাকশন বাগ থাকে। জটিল কোড পরীক্ষা করা কঠিন — এটি মানের জন্য সরাসরি হুমকি। সরলতা উচ্চ পরীক্ষা কভারেজের জন্য একটি শর্ত।
মেট্রিক্সের মাধ্যমে আপনার কোডের জটিলতা মাপুন: চক্রীয় জটিলতা — প্রতিটি পদ্ধতি ১০-এর নীচে রাখুন, আদর্শভাবে ৫-এর নীচে। স্বয়ংক্রিয় পরীক্ষার জন্য Detekt (Android) বা SwiftLint (iOS) ব্যবহার করুন।
সাধারণ ওভারইঞ্জিনিয়ারিং হল একক ডেটা উৎসের প্রকল্পে অ্যাবস্ট্র্যাক্ট রিপজিটরি ফ্যাক্টরি তৈরি করা। একটি সরল Repository ক্লাসের পরিবর্তে, ডেভেলপার একটি শৃঙ্খল তৈরি করে: RepositoryFactory → IRepository → BaseRepository → RepositoryImpl — API-কে GraphQL-এ পরিবর্তনের কাল্পনিক সম্ভাবনার জন্য।
JetBrains Developer Survey (2023) অনুযায়ী, ৪৩% Android ডেভেলপার স্বীকার করেছেন যে তারা রিফ্যাক্টরিংয়ের সময় একটি আর্কিটেকচারাল স্তর সরিয়ে ফেলেছেন কারণ এটি কখনও ব্যবহার করা হয়নি। KISS বলে: অ্যাবস্ট্র্যাকশন তৈরি করুন যখন বাস্তবায়নের দ্বিতীয় বিকল্প দেখা দেয়, প্রত্যাশায় নয়।
ইন্টারফেস ছাড়া একটি কংক্রিট বাস্তবায়ন দিয়ে শুরু করুন। যখন দ্বিতীয় ডেটা উৎস দেখা দেয় — রিফ্যাক্টরিংয়ের মাধ্যমে ইন্টারফেস বের করুন (IDE এটি স্বয়ংক্রিয়ভাবে করবে)। এটি আগে থেকে ইন্টারফেস লেখার চেয়ে দ্রুত।
DI ফ্রেমওয়ার্ক (Dagger, Hilt, Swinject) শক্তিশালী সরঞ্জাম, কিন্তু তারা প্রায়ই জটিলতা উস্কে দেয়। ডেভেলপাররা প্রতিটি সত্তার জন্য আলাদা মডিউল তৈরি করে, এমনকি যদি এটি শুধুমাত্র একটি জায়গায় ব্যবহৃত হয়। KISS বিকল্প: সহজ ক্ষেত্রে কনস্ট্রাক্টরের মাধ্যমে ম্যানুয়াল ইনজেকশন।
// ওভারইঞ্জিনিয়ারিং: একক রিপজিটরির জন্য মডিউল
@Module
object UserModule {
@Provides
fun provideUserRepo(): UserRepository = UserRepositoryImpl()
}
// KISS: একটি রিপজিটরি থাকলে ম্যানুয়াল ইনজেকশন
class UserViewModel(
private val repo: UserRepository = UserRepositoryImpl()
) { /* ... */ }
কনস্ট্রাক্টরে ম্যানুয়াল ইনজেকশন হল সরল DI প্যাটার্ন। এতে কোড জেনারেশন, অ্যানোটেশন বা মডিউলের প্রয়োজন নেই। তখনই পরিবর্তন করুন যখন প্রকল্প ৫+ স্ক্রিনে পৌঁছায় এবং ম্যানুয়াল ইনজেকশন রক্ষণাবেক্ষণ করা কঠিন হয়ে যায়।
Android ViewModel অতিরিক্ত জটিলতার একটি সাধারণ উৎস। ডেভেলপাররা StateFlow, combine, flatMapLatest এবং ট্রান্সফর্মেশনের শৃঙ্খল যোগ করে যেখানে postValue সহ সরল MutableLiveData যথেষ্ট হবে। KISS সুপারিশ করে: সরল সমাধান (LiveData) দিয়ে শুরু করুন, শুধুমাত্র নির্দিষ্ট প্রয়োজনীয়তার জন্য জটিল করুন (স্টেট রিসেট, debounce)।
// KISS: প্রতিক্রিয়াশীল চেইন ছাড়া সরল ViewModel
class ProfileViewModel : ViewModel() {
private val _name = MutableLiveData<String>()
val name: LiveData<String> = _name
fun loadUser(id: String) {
viewModelScope.launch {
_name.postValue(repo.getUser(id).name)
}
}
}
এই উদাহরণে, ViewModel অ্যাসিঙ্ক্রোনাস অনুরোধের জন্য coroutine ব্যবহার করে, ফলাফল প্রকাশের জন্য LiveData। কোনো StateFlow নেই, কোনো combine নেই — শুধু যা সত্যিই প্রয়োজন। StateFlow তখন যোগ করুন যখন স্পষ্ট স্টেট সহ ইউনিডাইরেকশনাল ডেটা ফ্লো (UDF) প্রয়োজন।
iOS-এ, KISS নীতি ডেটা মডেলের জন্য ক্লাসের চেয়ে স্ট্রাক্ট পছন্দ করার মাধ্যমে প্রকাশ পায়। স্ট্রাক্ট হল ভ্যালু টাইপ, ARC-এর মাধ্যমে মেমোরি ব্যবস্থাপনার প্রয়োজন নেই এবং ডিফল্টরূপে ইমিউটেবল। ক্লাস শুধুমাত্র তখনই ন্যায়সঙ্গত যখন পরিচয় (একই বস্তুর দুটি রেফারেন্স) বা ইনহেরিটেন্স প্রয়োজন।
// KISS: মডেলের জন্য ক্লাসের পরিবর্তে স্ট্রাক্ট
struct User: Codable {
let id: Int
let name: String
let email: String
}
// ওভারইঞ্জিনিয়ারিং: ম্যানুয়াল init এবং deinit সহ ক্লাস
class UserClass: NSObject {
let id: Int
init(id: Int) { self.id = id }
}
User স্ট্রাক্ট স্বয়ংক্রিয়ভাবে memberwise init, Equatable এবং Hashable সমর্থন (সমস্ত ফিল্ড দ্বারা), ইমিউটেবিলিটি এবং মাল্টিথ্রেডেড পরিবেশে নিরাপত্তা পায়। ক্লাসের ম্যানুয়াল init, NSObject বাস্তবায়ন প্রয়োজন এবং ভাগ করা স্টেটের মাধ্যমে রেস কন্ডিশনের জন্য সংবেদনশীল।
নেটওয়ার্কিং লেয়ার আরেকটি ক্ষেত্র যেখানে KISS প্রায়ই লঙ্ঘিত হয়। ডেভেলপাররা ৫+ উপাদানের Interceptor চেইন, অ্যাবস্ট্র্যাক্ট ফ্যাক্টরির মাধ্যমে সিরিয়ালাইজেশন এবং প্রতিটি এন্ডপয়েন্টের জন্য ম্যাপার যোগ করেন। KISS সমাধান: কনফিগারেশন সহ একটি URLSession এবং Codable/JSON-এর মাধ্যমে একটি ডিকোডিং।
Apple URLSession Programming Guide (2023) অনুযায়ী, URLSession এবং Codable সহ একটি সরল নেটওয়ার্কিং লেয়ার মোবাইল অ্যাপের ৯৫% দৃশ্যপট কভার করে। জটিল Interceptor চেইন শুধুমাত্র নির্দিষ্ট ক্ষেত্রে প্রয়োজন: টোকেন রিফ্রেশ, লগিং, এনক্রিপশন।
URLSession + Codable-ভিত্তিক সরল নেটওয়ার্কিং লেয়ার দিয়ে শুরু করুন। বাস্তব প্রয়োজন দেখা দিলে Interceptors যোগ করুন, «ভবিষ্যতের জন্য» নয়। এটি নেটওয়ার্কিং লেয়ারের কোড ২–3 গুণ কমিয়ে দেয়।
সরলতা আদিমতার মতো নয়। সরল সমাধান একটি সংক্ষিপ্ত, স্পষ্ট সমাধান যা পুনরাবৃত্তি ছাড়াই কাজ সমাধান করে। আদিম সমাধান সর্বোত্তম অনুশীলন এবং সুস্থ আর্কিটেকচার উপেক্ষা করে। পার্থক্য হল সরল সমাধান সম্প্রসারণ করা সহজ, যখন আদিমটি নয়।
উদাহরণ: সমস্ত স্ক্রিনের জন্য একমাত্র সত্তা হিসাবে Activity ব্যবহার করা আদিমতা, সরলতা নয়। সরলতা হল বিভিন্ন স্ক্রিনের জন্য আলাদা Fragment সহ Navigation Component ব্যবহার করা, কিন্তু অপ্রয়োজনীয় অ্যাবস্ট্র্যাকশন ছাড়া। KISS খারাপ আর্কিটেকচারকে ন্যায়সঙ্গত করে না।
নিজেকে পরীক্ষা করুন: একটি নতুন ফিচার যোগ করলে কি আপনার কোড পরিবর্তন হতে পারে? যদি হ্যাঁ — সরলতা সঠিক। যদি প্রতিটি ফিচারের জন্য সবকিছু পুনরায় লিখতে হয় — এটি আদিমতা, অবিলম্বে রিফ্যাক্টর করুন।
প্যাটার্ন (MVVM, MVI, Coordinator) জটিলতা নয়, বরং কাঠামো। KISS প্রমাণিত আর্কিটেকচারাল প্যাটার্ন ব্যবহার নিষিদ্ধ করে না। এটি তাদের অতিরিক্ত ব্যবহার নিষিদ্ধ করে: তিনটি প্যাটার্ন যেখানে একটি যথেষ্ট হবে। সুবর্ণ মাধ্যম হল প্রতি প্রকল্পে একটি আর্কিটেকচারাল প্যাটার্ন এবং ২–3টির বেশি সহায়ক (DI, Navigation) নয়।
State of Mobile Architecture Report (2024) অনুযায়ী, যে প্রকল্পগুলি ঠিক একটি আর্কিটেকচারাল প্যাটার্ন ব্যবহার করে, তাদের উন্নয়নের প্রথম বছরে «ফ্রাঙ্কেনস্টাইন» প্রকল্পের তুলনায় ৩৪% কম বাগ থাকে যা ৩+ প্যাটার্ন মিশ্রিত করে। বেছে নিন মোবাইল প্রকল্পের জন্য MVVM বা MVI — এবং সমস্ত স্ক্রিনে এটি অনুসরণ করুন।
একই প্রকল্পে MVVM এবং MVI মিশ্রিত করবেন না। যদি দল MVVM বেছে নেয় — পুরো প্রকল্পকে MVVM অনুসরণ করা উচিত। ব্যতিক্রম হল পৃথক ফিচার মডিউল যার নিজস্ব আর্কিটেকচারাল সিদ্ধান্ত রয়েছে, কিন্তু এটি একটি সচেতন পছন্দ হতে হবে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
KISS (Keep It Simple, Stupid) একটি নীতি যা কোডকে যতটা সম্ভব সরল করার প্রয়োজন। যদি একটি কাজ অতিরিক্ত ক্লাস, প্যাটার্ন এবং অ্যাবস্ট্র্যাকশন ছাড়া সমাধান করা যায় — তাহলে সেগুলো ছাড়া সমাধান করুন। সরল সমাধান বোঝা, পরীক্ষা এবং পরিবর্তন করা সহজ।
DRY কোড পুনরাবৃত্তি নিষিদ্ধ করে, KISS অতিরিক্ত জটিলতা নিষিদ্ধ করে। কখনও কখনও তারা সংঘর্ষে লিপ্ত হয়: পুনরাবৃত্তি দূর করার (DRY) প্রচেষ্টা একটি জটিল অ্যাবস্ট্র্যাকশন (KISS লঙ্ঘন) তৈরি করতে পারে। তিনের নিয়ম ভারসাম্য বজায় রাখতে সাহায্য করে: শুধুমাত্র তৃতীয় পুনরাবৃত্তির পরে অ্যাবস্ট্র্যাক্ট করুন।
KISS ভাঙা যেতে পারে যখন আপনি ভবিষ্যতের প্রয়োজন নিশ্চিতভাবে জানেন: উদাহরণস্বরূপ, KMM-এর মাধ্যমে দ্বিতীয় প্ল্যাটফর্ম সমর্থন করা বা পরবর্তী ত্রৈমাসিকে নতুন আর্কিটেকচারে মাইগ্রেট করা। শর্ত: ভবিষ্যতের প্রয়োজন নথিভুক্ত হতে হবে, কাল্পনিক অনুমান নয়।
উদ্দেশ্যমূলক মেট্রিক্স ব্যবহার করুন: চক্রীয় জটিলতা (প্রতি পদ্ধতিতে ১০ পর্যন্ত), কোডের লাইন প্রতি পদ্ধতি (২০ পর্যন্ত), নেস্টিং স্তর (৩ পর্যন্ত)। Android-এর জন্য — Detekt প্লাগইন, iOS-এর জন্য — SwiftLint। বিষয়গত মেট্রিক: একজন নতুন ডেভেলপারের এক মিনিটে কোড বোঝা উচিত।
হ্যাঁ, KISS এবং SOLID সামঞ্জস্যপূর্ণ। SOLID সঠিক আর্কিটেকচার সম্পর্কে, KISS ন্যূনতম জটিলতা সম্পর্কে। KISS-এর লঙ্ঘন ঘটে যখন SOLID অতিরিক্ত প্রয়োগ করা হয়: এক ডজন ক্লাস তৈরি করা যেখানে তিনটি যথেষ্ট হবে। সুবর্ণ নিয়ম: SOLID যুক্তিসঙ্গত সীমা পর্যন্ত, KISS প্রতিটি ধাপে ফিল্টার হিসাবে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন