ظرافت راهحل
وقتی در حوزه IT کار میکنید، بسیار آسان است که روی راهحلهای بزرگ و پیچیده تمرکز کنید. به نظر میرسد که راهحلهای خوب باید در همینجا باشند – راهحلهای بزرگ، نرمافزارهای فراوان، همه جدیدترین ابزارها. کاری که انجام میدهیم هیجانانگیز است و خیلی راحت میشود در این جریان غرق شد. انجام پروژههای بزرگ و چالشبرانگیز لذتبخش است. شنیدن اینکه سایر متخصصان IT چه میکنند، شرکتهای دیگر چگونه با چالشها روبرو میشوند، و صحبت با فروشندگانی که سیستمهای بزرگ برای فروش دارند، همه به این هیجان میافزاید و خیلی راحت میشود حس هدف و دامنه را از دست داد؛ و بسیار رایج است که راهحلهای بزرگ و افراطی برای مشکلات ساده دیده شوند، به طوری که به نظر میرسد IT همیشه اینگونه بوده است.
اما لازم نیست اینگونه باشد. پیچیدگی دشمن هر دوی قابلیت اطمینان و امنیت است. راهحلهای پیچیده غیرضروری هزینه را هم در مرحله خرید و هم در پیادهسازی و هم در نگهداری افزایش میدهند، در حالی که عموماً کندتر، شکنندهتر هستند و سطح حمله بزرگی دارند که درک و حفاظت از آن دشوارتر است. راهحلهای ساده، یا دقیقتر بگوییم، ظریف، بهترین رویکرد هستند. این به معنای ساده بودن همه طرحها نیست، نه اصلاً. طرحهای پیچیده اغلب ضروری هستند. IT به هیچ وجه حوزهای نیست که فاقد پیچیدگی باشد. در واقع اغلب اعتقاد بر این است که توسعه نرمافزار ممکن است پیچیدهترین تلاش بشری باشد، حداقل از میان آنهایی که در هر مقیاسی انجام میشوند. یک نصب معمول IT شامل میلیونها خط کد، صدها یا هزاران پروتکل، تعداد زیادی سیستم به هم متصل، لایههایی از پیکربندیهای نرمافزاری منحصربهفرد، تنظیماتی بیشتر از آنچه هر تیمی بتواند بشناسد، میشود و تازه بعد از آن پیچیدگی صدها یا هزاران یا صدها هزار انسان غیرقابل پیشبینی و غیرمنطقی را که تلاش میکنند از این سیستمها به شیوهای منحصربهفرد استفاده کنند اضافه میکنیم. IT بدون شک پیچیده است.
آنچه مهم است این است که بپذیریم IT پیچیده است، که این را نمیتوان به طور کامل اجتناب کرد، اما تمرکز کنیم بر طراحی و مهندسی راهحلهایی که تا حد ممکن ساده، باوقار... و ظریف باشند. این ایده طراحی، حداقل در ذهن من، از مهندسی نرمافزار میآید، جایی که کد پیچیده به عنوان اشتباه تلقی میشود و کد ساده و زیبا که خواندن و درک آن آسان است موفق محسوب میشود. یکی از بالاترین افتخاراتی که میتوان به یک مهندس نرمافزار داد این است که کدش «ظریف» تلقی شود. چقدر مناسب است که این نقل قول مشهور به Blaise Pascal نسبت داده میشود، که یکی از محبوبترین زبانهای برنامهنویسی دهههای ۱۹۷۰ و ۱۹۸۰ به نام او نامگذاری شد (ترجمه ناقص از فرانسه): «متأسفم که مجبور شدم نامهای چنین طولانی برایتان بنویسم، اما وقت نداشتم نامهای کوتاهتر بنویسم.»
اغلب طراحی راهحلهای پیچیده و پیچیدهتر بسیار آسانتر از تعیین رویکرد سادهای است که کافی باشد. خواه در عجله باشیم یا ندانیم از کجا شروع کنیم، ظرافت همیشه یک چالش است. جریان صنعت به سمت ترویج مسیر دشوارتر است. به نفع فروشندگان است که تجهیزات بیشتری بفروشند، نه تنها برای انجام فروش اولیه، بلکه میدانند که با تجهیزات بیشتر، درآمد پشتیبانی بیشتری میآید و اگر تجهیزات جدید و پیچیده کافی فروخته شود، نیازهای پشتیبانی به جای افزایش خطی، به شکل هندسی افزایش مییابند، زیرا پشتیبانی اضافی نه تنها برای خود تجهیزات یا نرمافزار، بلکه برای پیکربندی و پشتیبانی تعاملات سیستم یا سفارشیسازی بیشتر هم لازم است. تأثیرات مالی پشت پیچیدگی زیاد است و به فروشندگان ختم نمیشود. متخصصان IT امنیت شغلی زیادی، یا توهم آن را، از طریق مدیریت مجموعههای بزرگ سختافزار و نرمافزاری که انتقال یکپارچه آنها به متخصص IT دیگری دشوار است به دست میآورند.
اغلب پیچیدگی چنان مفروض و مورد انتظار است که فرآیند انتخاب راهحل با پیچیدگی زیاد به عنوان یک نتیجه از پیش تعیین شده شروع میشود، بدون هیچ توجهی به این احتمال که راهحل کمتر پیچیده ممکن است کافی باشد، یا حتی خارج از پرسش پیچیدگی و هزینه برتر باشد. پیچیدگی گاهی حتی کاملاً به مفاهیم خاصی گره خورده است تا آنجا که من واقعاً با ناباوری در مورد این ایده روبرو شدهام که یک راهحل ساده ممکن است از نظر قیمت، عملکرد و قابلیت اطمینان از یک راهحل پیچیده بهتر عمل کند.
بلاغت آسان است، اما یک مثال واقعی چیست؟ بهترین مثالهایی که امروز میبینم اغلب به مجازیسازی مربوط هستند، خواه در رابطه با ذخیرهسازی یا یک لایه مدیریت ابری یا نرمافزار یا صرفاً خود مجازیسازی. اغلب میبینم که گفتگویی که فقط درباره مجازیسازی برای یک نفر است فوراً تداعی میکند که به ذخیرهسازی بلاک شبکهای اشتراکی، نرمافزار مدیریت مجازیسازی گرانقیمت، گرههای مجازیسازی زیاد و افزونه، و نرمافزار پیچیده دسترسپذیری بالا نیاز است – که هیچ کدام ذاتی مجازیسازی نیستند و اکثرشان به ندرت برای پشتیبانی یا واقعاً حتی به نفع کسبوکاری هستند که برای آن پیادهسازی خواهند شد. به جای کار از الزامات کسبوکار، این مفاهیم عمدتاً از پیشداوریهای فناوری ناشی میشوند. اشاره به پیچیدگی و ظاهر حل مشکل آسان است – پیچیدگی احساس آرامش ایجاد میکند. بسیاری از استدلالها را تجزیه کنید و میشنوید «چگونه ممکن است کار نکند، وقتی پیچیده است؟» پیچیدگی توهم کامل بودن یا حل مشکل را ایجاد میکند، اما این میتواند به طور معمول این واقعیت را پنهان کند که یک راهحل ممکن است واقعاً کامل یا حتی کارآمد نباشد، اما درجه پیچیدگی دیدن این را دشوار میکند. ذهن ما سپس به راحتی رویکرد سادهتری را که کاملتر است و مشکل را حل میکند در حالی که یک رویکرد پیچیده نمیکند نمیپذیرد، زیرا بسیار غیرشهودی به نظر میرسد.
یک مثال عالی این است که به جای قابلیت اطمینان، به افزونگی میپردازیم. قابلیت اطمینان اندازهگیری دشواری دارد، افزونگی کمیتسازی سادهای دارد. یک آجر بسیار قابل اطمینان است، حتی وقتی تنها باشد. برای پایدار و محکم بودن آجر نیازی به افزونگی نیست. طراحی آن ساده است. میتوانید یک سازه حمایتی از چوبهای زیاد افزونه بسازید که به هیچ وجه به اندازه یک آجر منفرد قابل اطمینان نباشد. اگر از قابلیت اطمینان صحبت کنید – شانس خراب نشدن سازه – روشن است که آجر انتخاب برتری نسبت به چندین چوب است. اما اگر بگویید «اما هیچ افزونگیای وجود ندارد، آجر ممکن است خراب شود و هیچ چیزی جایش را نمیگیرد» احمقانه به نظر میرسد. اما وقتی درباره کامپیوترها و سیستمهای کامپیوتری صحبت میکنیم، سیستمهایی مییابیم که آنقدر پیچیده هستند که به ندرت مردم میتوانند ببینند که آجر دارند یا چوب، بنابراین، از آنجا که نمیتوانند قابلیت اطمینانی که مهم است را تعیین کنند، روی افزونگی که به راحتی کمیتسازی میشود اما مهم نیست تمرکز میکنند. کل سیستم بیش از حد پیچیده است، اما جستجو برای راهحل ساده، آنی که مستقیماً به هسته مشکل برای حل رسیدگی میکند، میتواند پیچیدگی را کاهش دهد و در نهایت پاسخ بسیار بهتری به ما بدهد.
این حتی در RAID هم دیده میشود. RAID آینهای ساده است، فقط یک دیسک یا مجموعهای از دیسکها که نسخه دقیق مجموعه دیگری هستند. آنقدر ساده است. RAID توازنبند با محاسبات روی یک نوار متغیر در دستگاههای متعددی که هنگام نوشتن باید رمزگذاری شوند و در صورت خرابی دستگاه رمزگشایی شوند، پیچیده است. RAID آینهای فاقد این پیچیدگی است و مشکل قابلیت اطمینان دیسک را از طریق عملیات کپی ساده و ظریفی که بسیار قابل اطمینان و به خوبی قابل درک هستند حل میکند. RAID توازنبند بیدلیل پیچیده است که آن را شکننده میکند. با این حال با انجام این کار و تضعیف توانایی خود برای حل مشکلی که برای آن طراحی شده، همزمان به نظر بر اساس هیچ عاملی جز پیچیدگی خودش قابل اطمینانتر به نظر میرسد. ذهن انسان فوراً به «پیچیده است، بنابراین پیشرفتهتر است، بنابراین قابل اطمینانتر است» میرسد اما هیچکدام از این پیشرفتها منطقی نیستند. پیچیدگی پیشرفتهتر بودن را نشان نمیدهد و پیشرفته بودن قابل اطمینان بودن را نشان نمیدهد، اما ذهن انسان خودش پیچیده است و به راحتی گمراه میشود.
هیچ پاسخ سادهای برای یافتن سادگی وجود ندارد. دانستن اینکه پیچیدگی ذاتاً بد است اما گاهی اجتنابناپذیر، ما را آگاه میکند، اما به ما نمیآموزد که چه زمانی به پیچیدگی بیش از حد مشکوک باشیم. باید هوشیار باشیم، همیشه به دنبال تعیین اینکه آیا پاسخ ظریفتری وجود دارد و پیچیدگی را صرفاً به این دلیل که پیچیده است به عنوان پاسخ درست نپذیریم. باید راهحلهای پیشنهادی را زیر سوال ببریم و خودمان را زیر سوال ببریم. «آیا این راهحل واقعاً به اندازه کافی ساده است؟» «آیا این پیچیدگی ضروری است؟» «آیا این به پیچیدگیای که فرض کردهام نیاز دارد؟»
در اکثر توصیههای طراحی سیستم که میدهم، اولین مرحله تعیین فنی که معمولاً برمیدارم، پس از مرحله استفسار از نیاز کسبوکاری که باید حل شود، زیر سوال بردن پیچیدگی است. اگر از پیچیدگی نتوان دفاع کرد، احتمالاً غیرضروری است و به طور فعال هدفی را که برایش انتخاب شده شکست میدهد.
«آیا واقعاً ضروری است آن درایوها را به آرایههای جداگانه بسیاری تقسیم کنیم؟ اگر چنین است، توجیه فنی برای این کار چیست؟»
«آیا ذخیرهسازی اشتراکی واقعاً برای وظیفهای که آن را برای آن پیشنهاد میکنید ضروری است؟»
«آیا کسبوکار واقعاً استفاده از فناوریهای دسترسپذیری بالای توزیعشده را توجیه میکند؟»
«چرا یک سیستم ساده که دیروز کافی بود را با یک سیستم به مراتب پیچیدهتر فردا جایگزین میکنیم؟ چه چیزی تغییر کرده که یک بهبود عمده، در حالی که ساده باقی میماند، بیش از کافی نیست بلکه به درجاتی از پیچیدگی بیشتر و هزینهای نیاز دارد که قبلاً توجیه نداشت؟»
اینها فقط مثالهای رایج هستند، پیچیدگی در هر جنبهای از صنعت ما وجود دارد. به دنبال سادگی باشید. برای ظرافت تلاش کنید. بدون بررسی دقیق، پیچیدگی را نپذیرید. آن را از آزمایش سختی عبور دهید. اجازه ندهید پیچیدگی در جایی که توجیه ندارد نفوذ کند. در طرف پیچیدگی اشتباه نکنید – در صورت شک، به سادگی شکست بخورید. سادهسازی بیش از حد یک راهحل معمولاً منجر به شکستی کوچک میشود در حالی که پیچیدهتر کردن بیش از حد آن امکان درجه بسیار بالاتری از شکست را فراهم میکند. شرط مطمئنتر با راهحل سادهتر است. و اگر راهحل ساده انتخاب شود و ناکافی بودن آن ثابت شود، افزودن پیچیدگی بسیار آسانتر از حذف آن است.
