فرینکنسٹائن پروگرامنگ میں وہ کوڈ ہے جو مختلف ٹیکنالوجیز، اسٹائلز اور آرکیٹیکچرز کے غیر مطابقت پذیر حصوں سے جمع کیا گیا ہے۔ ThoughtWorks Technology Radar (2024) کی تحقیق کے مطابق، 28% بڑے پروجیکٹس میں فرینکنسٹائن سنڈروم کی علامات پائی جاتی ہیں — ایک متحد تکنیکی وژن کی کمی سے پیدا ہونے والا آرکیٹیکچرل ایکلیکٹسزم۔ میری شیلی کے ناول کے مشابہ، ایسا کوڈ کام کرتا ہے، لیکن اس کی دیکھ بھال ایک ڈراؤنے خواب میں بدل جاتی ہے۔
اہم نکات
فرینکنسٹائن (فرینکنسٹائن کوڈ، فرینکنسٹائن پیٹرن) ایک اینٹی پیٹرن ہے جس میں ایک سافٹ ویئر سسٹم ان حصوں سے جمع کیا جاتا ہے جو ایک ساتھ کام کرنے کے لیے ڈیزائن نہیں کیے گئے ہیں۔ فرینکنسٹائن کے راکشس کی طرح، ایسا کوڈ کام کر سکتا ہے، لیکن یہ بدصورت، غیر متوقع اور معمولی تبدیلیوں پر خطرناک ہوتا ہے۔
یہ اصطلاح ادب سے آئی ہے: میری شیلی کے ناول “فرینکنسٹائن، یا جدید پرومیتھیس” (1818) میں، ایک سائنس دان نے مختلف مردہ لوگوں کے جسم کے ٹکڑوں سے ایک زندہ مخلوق بنائی۔ پروگرامنگ میں، مشابہت درست ہے — ڈویلپر مختلف فریم ورکس، لائبریریوں، زبانوں کے ٹکڑے لیتے ہیں اور انہیں “زندہ” چپکاتے ہیں، ایک کام کرنے والا لیکن خوفناک نتیجہ حاصل کرتے ہیں۔
فرینکنسٹائن اور سپاگیٹی کوڈ کے درمیان فرق پیمانے اور نوعیت میں ہے۔ سپاگیٹی کوڈ ایک ٹیکنالوجی اسٹیک کے اندر الجھی ہوئی ساخت ہے۔ فرینکنسٹائن آرکیٹیکچر کی سطح پر ایکلیکٹسزم ہے: ایک ہی نظام میں مختلف ٹیکنالوجیز، غیر مطابقت پذیر پیراڈائمز، متصادم طریقے۔
مائیکرو سروسز آرکیٹیکچر مختلف خدمات کے لیے مختلف ٹیکنالوجیز کے استعمال کی اجازت دیتا ہے، لیکن واضح حدود اور معیاری تعامل پروٹوکول کی شرط پر۔ فرینکنسٹائن حدود کے بغیر افراتفری کا مرکب ہے: ایک ہی کنٹرولر میں REST اور GraphQL، ایک ہی ماڈیول میں دو ORM، ایک ہی انٹیٹی کے لیے SQL اور NoSQL۔
تکنیکی لیڈر یا آرکیٹیکٹ کی عدم موجودگی بنیادی وجہ ہے۔ جب پروجیکٹ میں آرکیٹیکچرل سالمیت کا ذمہ دار کوئی نہیں ہوتا، ہر ڈویلپر “اپنے لیے” اوزار چنتا ہے۔ ایک کو Spring پسند ہے، دوسرے کو Guice، تیسرا کسٹم DI استعمال کرتا ہے۔ نتیجہ — آرکیٹیکچرل ملاوٹ۔
پروجیکٹس کا انضمام دوسری عام وجہ ہے۔ دو ٹیموں نے مختلف اسٹیک استعمال کرتے ہوئے اپنے ماڈیولز آزادانہ طور پر تیار کیے۔ جب ماڈیولز کو ایک ایپلیکیشن میں یکجا کرنے کی ضرورت ہوتی ہے، تو انہیں اڈاپٹر اور مڈل ویئر سے “چپکا” دیا جاتا ہے۔ نتیجہ فرینکنسٹائن ہے۔
کارپوریٹ حصول تیسرا منظرنامہ ہے۔ کمپنی A نے کمپنی B خریدی اور اس کی مصنوعات کو اپنی مصنوعات میں ضم کرنا چاہتی ہے۔ دوبارہ لکھنے کے بجائے — API، مشترکہ ڈیٹا بیس اور پیچ کے ذریعے چپکانا۔ ایک سال بعد، نظام ایک راکشس بن جاتا ہے جسے کوئی نہیں سمجھتا۔
| وجہ | وضاحت | عام نتیجہ |
|---|---|---|
| کوئی آرکیٹیکٹ نہیں | ہر ڈویلپر اپنا اسٹیک چنتا ہے | ایک ماڈیول میں 3 مختلف 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 اسکیما دستاویزی نہیں ہے، منتقلیاں تصادم کرتی ہیں۔
آن بورڈنگ کی پیچیدگی پہلا نتیجہ ہے۔ ایک نئے ڈویلپر کو سسٹم کو سمجھنے کے لیے 5 زبانیں، 3 فریم ورکس، 2 آرکیٹیکچرل اسٹائل جاننے چاہئیں۔ آن بورڈنگ ہفتوں سے مہینوں تک پھیل جاتی ہے۔ LinkedIn (2023) کے مطابق، تکنیکی ایکلیکٹسزم والے پروجیکٹس نئے ملازمین کو 2 گنا زیادہ کھوتے ہیں۔
رویے کی غیر متوقعیت دوسرا نتیجہ ہے۔ Python مائیکرو سروس میں تبدیلی غیر متوقع طور پر Java ماڈیول کو توڑ سکتی ہے کیونکہ وہ واضح معاہدوں کے بغیر ڈیٹا بیس شیئر کرتے ہیں۔ ایسے مسائل کو ڈیبگ کرنے کے لیے اسٹیک میں تمام ٹیکنالوجیز کا بیک وقت علم ضروری ہے۔
سیکیورٹی تیسرا نتیجہ ہے۔ اسٹیک میں ہر ٹیکنالوجی کو اپنی سیکیورٹی کنفیگریشن، اپنے پیچ، اپنی نگرانی کی ضرورت ہوتی ہے۔ 5-6 متنوع ٹیکنالوجیز کے لیے قابل قبول سطح پر سیکیورٹی برقرار رکھنا عملی طور پر ناممکن ہے۔ ان میں سے ایک لازمی طور پر کمزور ہوگی۔
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 مختلف کاموں کے لیے مختلف DBs کا شعوری استعمال ہے (PostgreSQL لین دین کے لیے، Redis کیش کے لیے، Elasticsearch تلاش کے لیے)۔ فرینکنسٹائن بغیر حکمت عملی کے افراتفری کا مرکب ہے۔ فرق آرکیٹیکچرل فیصلے کی موجودگی میں ہے: polyglot ایک منصوبہ ہے، فرینکنسٹائن اس کی عدم موجودگی ہے۔
ہاں، اور یہ ایک عام مسئلہ ہے۔ جب ہر مائیکرو سروس مرکزی معیارات کے بغیر اپنی زبان، اپنا DB، اپنا پروٹوکول اور اپنا ڈیپلائمنٹ طریقہ استعمال کرتی ہے — آپ کو ایک تقسیم شدہ فرینکنسٹائن ملتا ہے۔ مائیکرو سروسز کے لیے، مشترکہ معیارات اہم ہیں: متحد پروٹوکول (REST/gRPC)، مشترکہ لاگ فارمیٹ، مرکزی مشاہدہ پذیری۔
منع نہ کریں — رہنمائی کریں۔ مصنف کو RFC لکھنے کا مشورہ دیں: بیان کریں کہ موجودہ حل کیوں مناسب نہیں، کون سے متبادلات پر غور کیا گیا، منتقلی کیسے کی جائے گی۔ اکثر RFC لکھنے کے عمل میں، ڈویلپر خود سمجھ جاتا ہے کہ نئی ٹیکنالوجی ضروری نہیں۔ اگر RFC قائل ہے — نافذ کریں، لیکن منصوبہ اور حدود کے ساتھ۔
پہلے انوینٹری، پھر معیاری بنانا۔ سب کچھ ایک ساتھ دوبارہ لکھنے کی کوشش نہ کریں۔ ایک پرت منتخب کریں (مثلاً HTTP کلائنٹ یا لاگنگ)، ایک آلہ چنیں، ADR لکھیں اور آہستہ آہستہ منتقل کریں۔ Strangler Fig پیٹرن — ایپلیکیشن کو روکے بغیر پرانے اجزاء کو ایک ایک کرکے نئے سے تبدیل کریں۔
جتنی کم، اتنی بہتر۔ مثالی طور پر — ایک زبان، ایک فریم ورک، ایک DB، ایک لاگنگ طریقہ۔ حقیقت پسندانہ طور پر — 2-3 زبانیں (واضح تقسیم کے ساتھ)، 1-2 DB، 1-2 فریم ورک۔ ہر اضافی ٹیکنالوجی ٹیم کا علمی بوجھ اور دیکھ بھال کی لاگت بڑھاتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں