در این نوشتار فاولر سعی دارد به تعریف دقیقی از معماری نرمافزار برسد و ویژگیهای یک معمار خوب را بر این اساس بیان کند. علی رغم تغییرات زیاد فضای نرمافزار از زمان نگارش مقاله تا امروز، مطلب همچنان خواندنی است و نکات مهمی برای آموختن دارد. هر جا که ممکن بود معادل فارسی گویا نباشد عبارت انگلیسی را هم آوردهام. برای ترجمه صحیح عنوان مقاله خیلی فکر کردم و نهایتا به این نتیجه رسیدم که عنوان حاضر از ترجمهی کلمه به کلمهی «چه کسی به یک معمار نیاز دارد؟» مناسبتر است. علت ترجمه، اشتراک دغدغهی شخصیام دربارهی درک جایگاه معمار در تیم توسعه بود.
چندی پیش در حالی که داشتم با سرخوشی از راهرو پایین میرفتم، همکارم دیو رایس را با پریشانحالی خاصی دیدم. سوال کوتاهم جواب دندانشکنی گرفت؛
دیگر نباید با هیچکس با عنوان معمار در رزومه مصاحبه کنیم!
در برخورد اول، این حرف سابقهداری بود، چون ما همیشه دیو را به عنوان یکی از معماران رهبریکنندهی خود میشناختیم، اما در ورای این جمله، حقایق بسیار مهمی نهفته بود.
علت این لقب هراسی، این واقعیت بود که با وجود استانداردهای صنعت ما، عناوین معمار و معماری به طرز وحشتناکی دستمالی شدهاند. برای بسیاری عنوان معمار نرمافزار کاملا با تصویر کاراکتر مغرور و کنترلکنندهی پایان فیلم ماتریکس (Matrix Reloaded) تطابق دارد. حتی در شرکتهایی که بیشتر از همه این نقش را مسخره میکنند، یک جایگاه حیاتی برای رهبری فنی وجود دارد که بر عهدهی یک معمار مانند دیو است.
وقتی داشتم روی عنوان Patterns of Enterprise Application Architecture – کتابی از نویسنده همین مقاله – با خودم کلنجار میرفتم، هرکسی آن را بررسی میکرد تایید میکرد که عبارت معماری برای عنوان آن مناسب است. اما همچنان من در تعریف این عبارت احساس عدم اعتماد به نفس میکردم. از آنجایی که بحث کتابم در میان بود، خودم را وادار کردم تا برای تعریف آن اقدام جدی کنم.
در اولین حرکت با کنار گذاشتن شکاکیتم از نگاه فازی صرف نظر کردم. از یک نظر معماری را لغتی تعریف کردم که وقتی میخواهیم از طراحی حرف بزنیم از آن استفاده میکنیم فقط با این تفاوت که میخواهیم آن را باد کنیم تا مهمتر به نظر برسد. (بله، حق دارید همین پدیده را مشابها برای عنوان معمار متصور شوید). به هر حال، همیشه در زنگار شکاکیت پرتوی حقیقت نهفته است. بالاخره وقتی داشتم نوشتهی رالف جانسون (Ralph Johnson) را در گروه ایمیلی Extreme Programming میخواندم، فهم برایم حاصل شد. خوب است که همهی آن را نقل قول کنم:
گروه RUP که در حال کار روی تعاریف IEEE هستند، معماری را این گونه تعریف میکند: «بالاترین سطح مفهوم یک سیستم در محیط (environment) آن. معماری یک سیستم نرمافزاری (در یک نقطه زمانی مشخص) سازماندهی یا ساختار مهمترین اجزای سازندهی (components) آن است که از طریق رابطهایی (interfaces) با هم در ارتباط هستند، این اجزای سازنده به نوبهی خود از اجزا و رابطهای کوچکتری تشکیل شدهاند».
جانسون ادامه میدهد:
من یکی از ناظران استاندارد IEEE بودم که از آن استفاده میکرد و مشاجرهی بینتیجهای کردم که به وضوح این تعریف قلابی است. هیچ بالاترین سطح مفهومی از سیستم وجود ندارد. کاربران و توسعهدهندگان سیستم فهم کاملا متفاوتی از آن دارند. کاربران به هیج وجه اهمیتی به ساختار اجزای سازندهی اساسی سیستم نمیدهند. پس شاید یک معماری بالاترین سطح مفهوم سیستم از نگاه توسعهدهندگان در محیط آن باشد. حال بیایید توسعهدهندگانی که تنها بخش کوچک خودشان را متوجه میشوند کنار بگذاریم. معماری میشود بالاترین سطح مفهوم سیستم از نگاه توسعهدهندگان متخصص. چه چیزی باعث میشود یک بخش سازندهی سیستم مهم باشد؟ مهم است چون توسعهدهندگان متخصص این طور میگویند.
بنابراین یک تعریف بهتر میتواند این باشد: «در بیشتر پروژههای موفق نرمافزاری، توسعهدهندگان متخصص که در حال پیشبرد آن پروژه هستند، یک فهم مشترک از طراحی سیستم دارند. این فهم مشترک معماری نامیده میشود. این فهم شامل اجزای سازندهی سیستم و نحوهی تعامل آن با واسطها میشود. این اجزای سازنده معمولا از اجزای کوچکتری ساخته شدهاند، با این توضیح که معماری تنها شامل اجزایی میشود که توسط توسعهدهندگان تایید شود».
این تعریف بهتری است زیرا روشنگر این واقعیت است که معماری یک برساخت اجتماعی است (خوب، نرمافزار هم اینگونه است، اما معماری حتی بیشتر) چون فقط به نرمافزار وابسته نیست، بلکه به آن بخش نرمافزار که گروه متخصصان روی اهمیت آن اجماع دارند وابسته است.
یک شیوهی دیگر هم برای تعریف معماری وجود دارد که میگوید «معماری مجموعهای از تصمیمات طراحی است که باید در ابتدا پروژه انجام شوند». من با این تعریف هم مخالفت کردم. معماری تصمیماتی است که تو آرزو داری کاش میتوانستی به درستی در ابتدای پروژه اتخاذ کنی، اما لزوما به نظر نمیرسد که چنین اتفاقی بیافتد.
بگذریم. در این تعریف دوم، انتخاب زبان برنامهنویسی باید یکی از تصمیمات معماری بیشتر پروژهها باشد در حالی که در تعریف اول چنین نیست.
این که چیزی یک تصمیم معماری محسوب شود بستگی به نظر توسعهدهندگان آن دارد. برای مثال آدمهایی که اپلیکیشن سازمانی (Enterprise Application) میسازند معتقدند که مانایی (persistance) یکی از بخشهای حیاتی است. وقتی آنها شروع به کشیدن نمودار سیستم خود میکنند با یک مدل سه لایه آغاز کرده و توضیح میدهند «و ما برای لایه دادهها (persistance) از دیتابیس اوراکل استفاده خواهیم کرد و تصمیم داریم لایه تناظر اشیای دامنه و جداول را (object mapping) خودمان پیادهسازی کنیم». اما یک نرمافزار تصویربرداری پزشکی که ممکن است از دیتابیس اوراکل استفاده کرده باشد بدون این که آن را بخشی از معماری آن بدانیم. چرا؟ چون پیچیدگی اصلی این اپلیکیشن پردازش تصویر است نه ذخیرهسازی آن. در چنین سیستمی خواندن و نوشتن تصاویر توسط بخش کوچکی از اپلیکیشن انجام خواهد شد به همین خاطر بیشتر توسعهدهندگان از آن صرف نظر میکنند.
با این اوصاف این که از آدمها بخواهیم که معماری خود را توضیح بدهند کار سختیست. «به ما بگو چه مهم است؟» معماری یعنی چیزهای مهم، هر چه که باشد!
حال که روی این تعریف که معماری یعنی چیزهای مهم توافق کردیم، پس معمار کسی است که نگران چیزهای مهم است. اینجاست که به تفاوت ماهیت معمار از نوع فیلم ماتریکس و معماری که دیو رایس نماد آن است پی میبریم.
از بسیاری از جهات، مهمترین فعالیت معمار اوریزوس در واقع مربیگری تیم توسعه است تا رشد کنند و بتوانند مسالههای پیچیدهتری را حل کنند. بهبود توانایی تیم توسعه تکیهگاه بسیار بهتری به معمار میدهد در مقایسه با این که معمار تکرویکننده همهی تصمیمات را خودش بگیرد و خودش به یک گلوگاه معماری (architectural bottleneck) تبدیل شود. این واقعیت ما را به یک قاعدهی سرانگشتی راضیکننده میرساند:
اخیرا در جلسهای که در ThoughtWorks داشتیم با تعدادی از همکاران راجع به چالشهای معمارها گفتگو میکردیم. جالب بود که سریع روی این که طبیعت شغل معمار باید شبیه معمار اوریزوس باشد به توافق رسیدیم اما نتوانستیم یک اسم رویش بگذاریم. معمار ریلودوس خیلی برایمان آشناتر بود. مایک تو (Mike Two) بهترین نامی که تا به حال شنیدم را مطرح کرد: راهنما، مثل راهنمای کوهپیمایی.
یک راهنما یک همتیمی باتجربهتر و ماهرتر است که به بقیهی همتیمی ها یاد میدهد چطور بهتر از پس کارها بربیایند و همیشه برای مسایل خاص حاضر است.
من عاشق شروع با یک عنوان درخشانم عالیتر میشود وقتی منظور مهمی هم از آن داشته باشم، مثل همین مقاله که هنوز آشکار نشده است. تعریف دوم جانسون را در نظر بگیرید: «معماری تصمیماتی است که آرزو میکردی کاش میشد همان اول پروژه به درستی اتخاذ کنی». چرا مردم میخواهند چیزی را همان اول پروژه به درستی به انجام برسانند؟ پاسخ البته این است: چون درک میکنند که تغییر دادن آنچیزها در ادامه بسیار سخت است. احتمالا حالا به این نتیجه رسیدید که معماری را اینگونه تعریف کنید: «چیزهایی که آدمها تغییر دادنشان را سخت میدانند».
باور رایج بر این است که اگر دارید یک اپلیکیشن سازمانی را پیادهسازی میکنید باید همان اول شمای پایگاه داده را طراحی کنید چون بعدا تغییر دادن آن سخت است – مخصوصا اگر نرمافزار تحت استفادهی کاربران قرار گرفته باشد. در یکی از پروژههای ما، مدیر دیتابیس (database administrator)، پارمد سالژ (Pramod Sadlage)، سیستمی ابداع کرده بود که ما را قادر میساخت به آسانی شمای پایگاه داده را تغییر بدهیم (و دادههای قبلی را نیز به شمای جدید انتقال بدهیم). با این کار، او باعث شده بود دیگر شمای دیتابیس برای ما بخشی از معماری نباشد. من این عمل را عالی میدانم چون به ما این امکان را میداد که بهتر تغییر را مدیریت کنیم.
در یک سخنرانی جذاب در کنفرانس XP 2002، Enrico Zaninotto، یک اقتصاددان، ایدههای زیربنایی چابکی در تولید و در توسعه نرمافزار را تحلیل کرد. جنبهای که برای من واقعا جالب بود این دیدگاه او بود که برگشتناپذیری (Irreversibility) یکی از منابع اصلی ایجاد پیچیدگی است. او روش های چابک (agile methods) را رویکردی در محدود کردن پیچیدگی میبیند که سعی دارد با کاهش برگشتناپذیری با منابع ایجاد پیچیدگی بجنگد. از این رو من معتقدم یکی از مهمترین وظایف یک معمار، حذف معماری است. او باید راهی بیابد تا با کوچک کردن معماری برگشتناپذیری را در طراحی نرمافزار کاهش دهد.
باز به سراغ جانسون میرویم، این بار در جواب ایمیلی که برای او فرستادم:
یکی از تفاوتهای معماری ساختمان و معماری نرمافزار این است که بسیاری از تصمیمات مربوط به ساختمان به سختی قابل تغییرند. بسیار سخت است که برگردی و زیربنای خود را تغییر دهی، هرچند ممکن است.
هیچ دلیل نظری (theoretical) برای سخت بودن تغییرات در نرمافزار وجود ندارد. اگر هر یک از جنبههای نرمافزار را به تنهایی در نظر بگیری، به راحتی قابل تغییر است، اما بلد نیستیم همهچیز را قابلتغییر پیادهسازی کنیم. ایجاد سهولت تغییر در یک بخش سیستم باعث افزودن اندکی پیچیدگی به کل سیستم میشود و در نتیجه این که بخواهی همهچیز را قابل تغییر طراحی کنی کلیت سیستم بسیار پیچیده میشود. پیچیدگی چیزی است که تغییر نرمافزار را دشوار میکند. این جاست که دور (duplication) رخ میدهد.
ایدهی برنامهنویسی جنبهگرا (Aspect-Oriented Programming) اینجاست که اهمیت مییابد. ما تکنیکهای قدرتمندی برای جدا کردن جنبههای مختلف یک برنامه داریم در حالی که از آن استفاده نمیکنیم. گمان نمیکنم مشکل اصلی ما با یافتن تکنیکهای بهتر برای جداسازی جنبهها حل شود. ما نمیدانیم کدام جنبههاست که باید از یکدیگر جدا شود و ما نمیدانیم کی این جداسازی میارزد و کی نمیارزد.
نرمافزار مثل ساختمان محدودیت فیزیکی ندارد. محدودیتهای نرمافزار قوهی تخیل، طراحی، و سازماندهی ماست. خلاصهی کلام، نرمافزار با ویژگیهای آدمها محدود شده است نه با ویژگیهای جهان. «ما دشمن را شناسایی کردیم، او خود ماییم.»
لینک وبلاگ مارتین فاولر در ادامه موجود است. اصل مقاله را میتوانید اینجا ببینید.