ফ্রাঙ্কেনস্টাইন প্রোগ্রামিংয়ে হল কোড যা বিভিন্ন প্রযুক্তি, শৈলী এবং আর্কিটেকচারের অসামঞ্জস্যপূর্ণ অংশ থেকে জড়ো করা হয়েছে। ThoughtWorks Technology Radar (2024) গবেষণা অনুসারে, 28% বড় প্রকল্পে ফ্রাঙ্কেনস্টাইন সিনড্রোমের লক্ষণ পাওয়া যায় — একটি সমন্বিত প্রযুক্তিগত দৃষ্টিভঙ্গির অভাবে সৃষ্ট আর্কিটেকচারাল এক্লেক্টিসিজম। মেরি শেলির উপন্যাসের সাদৃশ্যে, এই ধরনের কোড কাজ করে, কিন্তু এর রক্ষণাবেক্ষণ দুঃস্বপ্নে পরিণত হয়।
মূল বিষয়
ফ্রাঙ্কেনস্টাইন (ফ্রাঙ্কেনস্টাইন কোড, ফ্রাঙ্কেনস্টাইন প্যাটার্ন) একটি অ্যান্টিপ্যাটার্ন যেখানে একটি সফটওয়্যার সিস্টেম এমন অংশ থেকে জড়ো করা হয় যা একসাথে কাজ করার জন্য ডিজাইন করা হয়নি। ফ্রাঙ্কেনস্টাইনের দানবের মতো, এই ধরনের কোড কাজ করতে পারে, কিন্তু এটি কুৎসিত, অপ্রত্যাশিত এবং সামান্য পরিবর্তনে বিপজ্জনক।
শব্দটি সাহিত্য থেকে এসেছে: মেরি শেলির উপন্যাস “ফ্রাঙ্কেনস্টাইন, অর দ্য মডার্ন প্রমিথিউস” (1818)-এ, একজন বিজ্ঞানী বিভিন্ন মৃত মানুষের দেহের টুকরো থেকে একটি জীবন্ত প্রাণী তৈরি করেছিলেন। প্রোগ্রামিংয়ে, সাদৃশ্যটি সঠিক — ডেভেলপাররা বিভিন্ন ফ্রেমওয়ার্ক, লাইব্রেরি, ভাষার টুকরো নেয় এবং সেগুলিকে “জড়ো করে”, একটি কার্যকরী কিন্তু ভয়ানক ফলাফল তৈরি করে।
ফ্রাঙ্কেনস্টাইন এবং স্প্যাগেটি কোডর মধ্যে পার্থক্য স্কেল এবং প্রকৃতিতে। স্প্যাগেটি কোড একটি প্রযুক্তি স্ট্যাকের ভিতরে জট পাকানো কাঠামো। ফ্রাঙ্কেনস্টাইন আর্কিটেকচার স্তরে এক্লেক্টিসিজম: বিভিন্ন প্রযুক্তি, অসামঞ্জস্যপূর্ণ দৃষ্টান্ত, একই সিস্টেমের মধ্যে বিরোধপূর্ণ পদ্ধতি।
মাইক্রোসার্ভিস আর্কিটেকচার বিভিন্ন সার্ভিসের জন্য বিভিন্ন প্রযুক্তি ব্যবহারের অনুমতি দেয়, কিন্তু স্পষ্ট সীমানা এবং মানকিকৃত মিথস্ক্রিয়া প্রোটোকলের শর্তে। ফ্রাঙ্কেনস্টাইন সীমানাহীন বিশৃঙ্খল মিশ্রণ: একই কন্ট্রোলারে REST এবং GraphQL, একই মডিউলে দুটি ORM, একই এন্টিটির জন্য SQL এবং NoSQL।
প্রযুক্তিগত নেতা বা আর্কিটেক্টের অনুপস্থিতি মূল কারণ। যখন প্রকল্পে আর্কিটেকচারের অখণ্ডতার জন্য দায়ী কেউ থাকে না, প্রতিটি ডেভেলপার “নিজের জন্য” সরঞ্জাম বেছে নেয়। একজন Spring পছন্দ করে, অন্যজন Guice, তৃতীয়জন কাস্টম DI ব্যবহার করে। ফলাফল — আর্কিটেকচারাল মিশ্রণ।
প্রকল্পের একীকরণ দ্বিতীয় সাধারণ কারণ। দুটি দল স্বাধীনভাবে তাদের মডিউল তৈরি করেছিল, বিভিন্ন স্ট্যাক ব্যবহার করে। যখন মডিউলগুলিকে একটি অ্যাপ্লিকেশনে একত্রিত করার প্রয়োজন হয়, তখন সেগুলিকে অ্যাডাপ্টার এবং মিডলওয়্যার দিয়ে “আঠা” দিয়ে জোড়া দেওয়া হয়। ফলাফল ফ্রাঙ্কেনস্টাইন।
কর্পোরেট অধিগ্রহণ তৃতীয় পরিস্থিতি। কোম্পানি A কোম্পানি B কিনেছে এবং তার পণ্যকে নিজের সাথে একীভূত করতে চায়। পুনর্লিখনের পরিবর্তে — API, শেয়ার্ড ডাটাবেস এবং প্যাচের মাধ্যমে জোড়া দেওয়া। এক বছর পরে, সিস্টেমটি একটি দানবে পরিণত হয় যা কেউ বোঝে না।
| কারণ | বর্ণনা | সাধারণ ফলাফল |
|---|---|---|
| কোনো আর্কিটেক্ট নেই | প্রত্যেক ডেভেলপার নিজের স্ট্যাক বেছে নেয় | এক মডিউলে ৩টি ভিন্ন HTTP ক্লায়েন্ট |
| প্রকল্প একীকরণ | দুটি পণ্য একটিতে জোড়া দেওয়া | দুটি ORM, দুটি লগিং পদ্ধতি |
| M&A | তার পণ্য সহ কোম্পানি অধিগ্রহণ | বিভিন্ন আর্কিটেকচার এবং শৈলীর সংকর |
| পরীক্ষা-নিরীক্ষা | কৌশল ছাড়া নতুন প্রযুক্তি প্রবর্তন | এক ফাইলে Java 8 + Java 21 বৈশিষ্ট্য |
| রাজনৈতিক সিদ্ধান্ত | প্রসঙ্গ ছাড়া উপর থেকে প্রযুক্তি চাপানো | সাধারণ স্ক্রিপ্টের জন্য এন্টারপ্রাইজ ফ্রেমওয়ার্ক |
অভিজ্ঞ ডেভেলপাররা যারা প্রোডাকশনে নতুন প্রযুক্তি চেষ্টা করতে চান, তারা প্রায়ই ফ্রাঙ্কেনস্টাইনের উৎস হন। পরীক্ষা-নিরীক্ষাকে বিচ্ছিন্ন মডিউলে সীমাবদ্ধ না রেখে, তারা সিস্টেমের গুরুত্বপূর্ণ অংশে পরীক্ষামূলক কোড অন্তর্ভুক্ত করেন।
একটি ক্লাসিক উদাহরণ হল একটি অ্যাপ্লিকেশনে একাধিক ORM ব্যবহার করা। কিছু মডিউল Hibernate ব্যবহার করে, কিছু MyBatis, এবং কিছু সরাসরি JDBC কোয়েরি। লেনদেন নিয়ন্ত্রণাতীত হয়, ক্যাশ অসঙ্গত হয়, এবং নতুন ডেভেলপার জানে না কোন পদ্ধতি ব্যবহার করতে হবে।
দ্বিতীয় উদাহরণ হল আর্কিটেকচারাল শৈলীর মিশ্রণ। একটি REST API কন্ট্রোলারে, আপনি SOAP সার্ভিস কল, সরাসরি SQL কোয়েরি, ফাইল সিস্টেম অ্যাক্সেস এবং HTML জেনারেশন খুঁজে পান। এই ধরনের অ্যাপ্লিকেশন পরীক্ষা, সম্প্রসারণ বা ডকুমেন্টেশন করা অসম্ভব।
তৃতীয় উদাহরণ হল একটি প্রযুক্তি স্ট্যাক যেখানে Python ব্যাকএন্ডের জন্য, Node.js মাইক্রোসার্ভিসের জন্য, C# ডেস্কটপ ক্লায়েন্টের জন্য এবং Java Android অ্যাপের জন্য ব্যবহৃত হয়, যেখানে সমস্ত ব্যবসায়িক যুক্তি দায়িত্বের স্পষ্ট বিভাজন ছাড়াই তাদের মধ্যে ছড়িয়ে আছে।
// ফ্রাঙ্কেনস্টাইন — মিশ্র শৈলী এবং প্রযুক্তি
// callbacks, Promises, এবং async/await সম্মিলিত
// callbacks
db.query("SELECT * FROM users", function(err, rows) {
if (err) handleError(err);
// callback এর ভিতরে Promise
fetch("/api/data").then(function(data) {
// then এর ভিতরে async/await
(async () => {
const result = await processData(data);
sendResponse(result);
})();
});
});
// পরিষ্কার কোড — একীভূত async/await শৈলী
async function getUserData(userId) {
const user = await db.query("SELECT * FROM users WHERE id = ?", [userId]);
const data = await fetch("/api/data/" + userId);
return await processData(user, data);
}
একটি ডাটাবেস একই সাথে SQL রিলেশনাল (সাধারণীকরণ সহ) এবং NoSQL ডকুমেন্ট-ওরিয়েন্টেড (JSON কলাম সহ) হিসাবে ব্যবহৃত হয়। কিছু কোয়েরি ORM-এর মাধ্যমে যায়, কিছু সংরক্ষিত প্রক্রিয়ার মাধ্যমে, কিছু কোড থেকে সরাসরি SQL-এর মাধ্যমে। DB স্কিমা ডকুমেন্টেড নয়, মাইগ্রেশন বিরোধ করে।
অনবোর্ডিং জটিলতা প্রথম পরিণতি। একজন নতুন ডেভেলপারকে সিস্টেম বুঝতে ৫টি ভাষা, ৩টি ফ্রেমওয়ার্ক, ২টি আর্কিটেকচারাল শৈলী জানতে হবে। অনবোর্ডিং সপ্তাহ থেকে মাস পর্যন্ত লম্বা হয়। LinkedIn (2023) অনুসারে, প্রযুক্তিগত এক্লেক্টিসিজমযুক্ত প্রকল্পগুলি নতুন কর্মচারীদের ২ গুণ বেশি হারায়।
আচরণের অপ্রত্যাশিততা দ্বিতীয় পরিণতি। Python মাইক্রোসার্ভিসে পরিবর্তন অপ্রত্যাশিতভাবে Java মডিউল ভেঙে দিতে পারে কারণ তারা স্পষ্ট চুক্তি ছাড়া একটি ডাটাবেস ভাগ করে। এই ধরনের সমস্যা ডিবাগ করার জন্য স্ট্যাকের সমস্ত প্রযুক্তির একসঙ্গে জ্ঞান প্রয়োজন।
নিরাপত্তা তৃতীয় পরিণতি। স্ট্যাকের প্রতিটি প্রযুক্তির নিজস্ব নিরাপত্তা কনফিগারেশন, নিজস্ব প্যাচ, নিজস্ব মনিটরিং প্রয়োজন। ৫-৬টি ভিন্নধর্মী প্রযুক্তির জন্য গ্রহণযোগ্য স্তরে নিরাপত্তা বজায় রাখা কার্যত অসম্ভব। তাদের মধ্যে একটি অনিবার্যভাবে দুর্বল হবে।
SonarQube প্রযুক্তিগত ঋণ পরিমাপ করতে পারে, কিন্তু “আর্কিটেকচারাল ঋণ” পরিমাপ করতে পারে না — উপাদান অসামঞ্জস্যতা। এই ঋণ লিন্টার সতর্কবাণীতে নয়, বরং বিভিন্ন প্রযুক্তিতে লেখা তিনটি ভিন্ন মডিউল পরিবর্তন না করে একটি নতুন বৈশিষ্ট্য যোগ করার অসম্ভবতায় প্রকাশ পায়।
প্রথম এবং প্রধান পদক্ষেপ — প্রযুক্তি স্ট্যাকের অখণ্ডতার জন্য দায়ী একজন আর্কিটেক্ট বা টেক লিড নিয়োগ করা। এই ব্যক্তির আর্কিটেকচারাল পর্যালোচনা ছাড়া নতুন প্রযুক্তি প্রবর্তনের উপর ভেটো পাওয়ার আছে। গণতন্ত্র নয়, বরং মূল প্রযুক্তির উপর দায়িত্বশীল একক সিদ্ধান্ত।
দ্বিতীয় — Architecture Decision Record (ADR) প্রক্রিয়া বাস্তবায়ন করা। কোনো গুরুত্বপূর্ণ আর্কিটেকচারাল সিদ্ধান্ত (DB, ফ্রেমওয়ার্ক, প্রোটোকল নির্বাচন) একটি ছোট লেখা হিসেবে ডকুমেন্টেড করা হয়: প্রসঙ্গ, বিবেচিত বিকল্প, গৃহীত সিদ্ধান্ত, পরিণতি। ADR রিপোজিটরিতে সংরক্ষিত থাকে এবং পুরো টিমের জন্য উপলব্ধ থাকে।
তৃতীয় — “একটি কাজ — একটি সরঞ্জাম” নীতি প্রতিষ্ঠা করা। HTTP অনুরোধের জন্য — একটি ক্লায়েন্ট। ORM-এর জন্য — একটি লাইব্রেরি। লগিংয়ের জন্য — একটি ফ্রেমওয়ার্ক। ব্যতিক্রম শুধুমাত্র ADR-এর মাধ্যমে যুক্তিসহ অনুমোদিত। যদি প্রকল্পে ইতিমধ্যে Axios থাকে — fetch যোগ করবেন না, যদি SLF4J থাকে — System.out-এর মাধ্যমে লিখবেন না।
পরীক্ষা-নিরীক্ষা অনুমোদিত, কিন্তু বিচ্ছিন্ন পরিবেশে। একটি মডিউল বা সার্ভিস বরাদ্দ করুন যা বাকি সিস্টেমকে প্রভাবিত না করে নতুন প্রযুক্তি দিয়ে পুনরায় লেখা যেতে পারে। যদি পরীক্ষা সফল হয় — ADR-এর মাধ্যমে এটি মানকিকৃত করুন। যদি না হয় — পরিণতি ছাড়া মুছে ফেলুন।
ইনভেন্টরি — প্রথম পদক্ষেপ। প্রযুক্তি স্ট্যাকের একটি সম্পূর্ণ মানচিত্র তৈরি করুন: কী কী ফ্রেমওয়ার্ক, লাইব্রেরি, ভাষা, প্রোটোকল ব্যবহার করা হয়, কোন মডিউলে এবং কোন কাজের জন্য। আপনি সমস্যার মাত্রা দেখতে পাবেন: সরঞ্জামের পুনরাবৃত্তি, বিরোধপূর্ণ প্রযুক্তি, অব্যবহৃত নির্ভরতা।
মানকিকরণ — দ্বিতীয় পদক্ষেপ। প্রতিটি কাজের জন্য একটি সরঞ্জাম চয়ন করুন। উদাহরণস্বরূপ: ORM-এর জন্য শুধুমাত্র Hibernate, লগিংয়ের জন্য শুধুমাত্র SLF4J + Logback, API-র জন্য শুধুমাত্র REST। ADR-এ মানকটি ডকুমেন্ট করুন। যেসব মডিউলে এক্লেক্টিসিজম সবচেয়ে বেশি সমস্যা সৃষ্টি করে সেখান থেকে প্রতিস্থাপন শুরু করুন।
Parallel Run কৌশল — তৃতীয় পদক্ষেপ। পুরানো এবং নতুন সরঞ্জাম সমান্তরালে কাজ করে যতক্ষণ না নতুন তার নির্ভরযোগ্যতা প্রমাণ করে। উদাহরণস্বরূপ, পুরানো HTTP ক্লায়েন্ট এবং নতুন একসাথে কাজ করে, কিন্তু নতুন শুধুমাত্র অনুরোধের একটি অংশ পরিচালনা করে। স্থিতিশীলতার সময়ের পরে, পুরানোটি সরানো হয়।
// ফ্রাঙ্কেনস্টাইন — একটি প্রকল্পে তিনটি HTTP পদ্ধতি
// মডিউল A: OkHttp
OkHttpClient client = new OkHttpClient().newCall(request);
// মডিউল B: RestTemplate (Spring)
restTemplate.getForObject(url, String.class);
// মডিউল C: java.net.HttpURLConnection
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
// একীভূত পদ্ধতি: সিঙ্কের জন্য RestTemplate, রিঅ্যাক্টিভের জন্য WebClient
@Autowired
private RestTemplate restTemplate;
public String callApi(String url) {
return restTemplate.getForObject(url, String.class);
}
প্রযুক্তিগত নেতা ফ্রাঙ্কেনস্টাইনের বিরুদ্ধে লড়াইয়ের প্রধান হাতিয়ার। ম্যানেজার নয়, হাতির দাঁতের টাওয়ারের আর্কিটেক্ট নয়, বরং একজন অনুশীলনকারী ডেভেলপার যিনি কোড লেখেন, PR রিভিউ করেন এবং আর্কিটেকচারাল সিদ্ধান্ত নেন। এরূপ ব্যক্তি ছাড়া, প্রকল্প অনিবার্যভাবে প্রযুক্তিগত এক্লেক্টিসিজমে পিছলে যায়।
RFC (Request for Comments) একটি প্রক্রিয়া যা ওপেন সোর্স সম্প্রদায় থেকে ধার করা হয়েছে। কোনো গুরুত্বপূর্ণ প্রযুক্তি প্রবর্তনের আগে, লেখক RFC লেখেন: সমস্যা, প্রস্তাবিত সমাধান, বিকল্প, বাস্তবায়ন পরিকল্পনা। টিম আলোচনা করে, ভোট দেয়, গ্রহণ বা প্রত্যাখ্যান করে। RFC স্বচ্ছতা তৈরি করে এবং “নীরব” আর্কিটেকচারাল সিদ্ধান্ত প্রতিরোধ করে।
প্রযুক্তিগত রাডার (ThoughtWorks Technology Radar) শ্রেণীবিন্যাসের হাতিয়ার: Adopt, Trial, Assess, Hold। টিম নিয়মিতভাবে রাডার পর্যালোচনা করে এবং স্থিতি আপডেট করে। এটি “ট্রেন্ডি” কে “উপযোগী” থেকে আলাদা করতে এবং গুরুত্বপূর্ণ কোডে অপ্রমাণিত প্রযুক্তি প্রবর্তন এড়াতে সাহায্য করে।
আর্কিটেকচারের সবচেয়ে গুরুত্বপূর্ণ গুণ হল সামঞ্জস্য (consistency)। পুরো প্রকল্প জুড়ে ব্যবহৃত একটি খুব ভালো নয় এমন সরঞ্জাম, শুধুমাত্র একটি মডিউলে ব্যবহৃত সেরা সরঞ্জামের চেয়ে ভাল। সামঞ্জস্য জ্ঞানীয় বোঝা হ্রাস করে, অনবোর্ডিং সহজ করে এবং কোডকে পূর্বাভাসযোগ্য করে তোলে।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
Polyglot persistence হল বিভিন্ন কাজের জন্য বিভিন্ন DB-র সচেতন ব্যবহার (PostgreSQL লেনদেনের জন্য, Redis ক্যাশের জন্য, Elasticsearch অনুসন্ধানের জন্য)। ফ্রাঙ্কেনস্টাইন কৌশল ছাড়া বিশৃঙ্খল মিশ্রণ। পার্থক্য আর্কিটেকচারাল সিদ্ধান্তের উপস্থিতিতে: polyglot একটি পরিকল্পনা, ফ্রাঙ্কেনস্টাইন তার অনুপস্থিতি।
হ্যাঁ, এবং এটি একটি সাধারণ সমস্যা। যখন প্রতিটি মাইক্রোসার্ভিস কেন্দ্রীভূত মান ছাড়া নিজস্ব ভাষা, নিজস্ব DB, নিজস্ব প্রোটোকল এবং নিজস্ব ডিপ্লয়মেন্ট পদ্ধতি ব্যবহার করে — আপনি একটি বিতরণকৃত ফ্রাঙ্কেনস্টাইন পান। মাইক্রোসার্ভিসের জন্য, সাধারণ মান গুরুত্বপূর্ণ: একীভূত প্রোটোকল (REST/gRPC), সাধারণ লগ ফরম্যাট, কেন্দ্রীভূত পর্যবেক্ষণযোগ্যতা।
নিষেধ করবেন না — নির্দেশনা দিন। লেখককে RFC লিখতে পরামর্শ দিন: বর্ণনা করুন কেন বিদ্যমান সমাধান উপযুক্ত নয়, কী কী বিকল্প বিবেচনা করা হয়েছে, কীভাবে মাইগ্রেশন করা হবে। প্রায়শই RFC লেখার প্রক্রিয়ায়, ডেভেলপার নিজেই বুঝতে পারেন যে নতুন প্রযুক্তির প্রয়োজন নেই। যদি RFC বিশ্বাসযোগ্য হয় — বাস্তবায়ন করুন, কিন্তু পরিকল্পনা এবং সীমাবদ্ধতা সহ।
প্রথমে ইনভেন্টরি, তারপর মানকিকরণ। একবারে সবকিছু পুনরায় লেখার চেষ্টা করবেন না। একটি স্তর নির্বাচন করুন (যেমন HTTP ক্লায়েন্ট বা লগিং), একটি সরঞ্জাম চয়ন করুন, ADR লিখুন এবং ধীরে ধীরে মাইগ্রেট করুন। Strangler Fig প্যাটার্ন — অ্যাপ্লিকেশন বন্ধ না করে পুরানো উপাদানগুলিকে একে একে নতুন দিয়ে প্রতিস্থাপন করুন।
যত কম, তত ভাল। আদর্শভাবে — একটি ভাষা, একটি ফ্রেমওয়ার্ক, একটি DB, একটি লগিং পদ্ধতি। বাস্তবসম্মতভাবে — ২-৩টি ভাষা (স্পষ্ট বিভাজন সহ), ১-২টি DB, ১-২টি ফ্রেমওয়ার্ক। প্রতিটি অতিরিক্ত প্রযুক্তি টিমের জ্ঞানীয় বোঝা এবং রক্ষণাবেক্ষণ খরচ বাড়ায়।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন