حالت تاریک
فصل ۱۵ — مهندس نرمافزار مدرن
همهٔ ایدههای این کتاب عمیقاً درهم تنیدهاند. همپوشانی و تکرار همهجا وجود دارد. واقعاً نمیتوانید separation of concerns را بدون بهبود modularity انجام دهید.
modularity، cohesion و separation of concerns توانایی جمعآوری feedback را تقویت میکنند و در نتیجه experimentation را تسهیل میکنند.
در نتیجه، در طول این کتاب بارها از هر یک از این موضوعات گذشتهام. این هم عمدی و هم اجتنابناپذیر است، اما فکر میکنم دربارهٔ این ایدهها چیز مهمتری میگوید.
نهتنها این ایدهها عمیقاً به هم پیوند خوردهاند، بلکه تقریباً همهجا اعمال میشوند — و این در واقع همان نکتهٔ اصلی است.
خیلی آسان است در جزئیات زودگذر گم شویم. اینکه کدام language، operating system، text editor یا framework انتخاب کنیم جزئیاتی است که در نهایت باید برای ما کمتر از مهارتهای قابلانتقال در همهٔ اینها اهمیت داشته باشد.
همانطور که جای دیگر گفتهام، بهترین توسعهدهندگان نرمافزاری که با آنها کار کردهام هر ابزاری که انتخاب میکردند نرمافزار خوب مینوشتند. قطعاً بسیاری از آنها تخصص و مهارت عمیقی با ابزارهای انتخابیشان داشتند، اما این مهارت اصلی، استعداد یا ارزشی که برای سازمانهایی که استخدامشان کرده بودند میآوردند نبود.
احتمالاً همهٔ این ایدهها برای شما آشنا هستند، اما شاید آنها را بهعنوان رویکردی برای سازماندهی کار در نظر نگرفتهاید. قصد این کتاب همین بوده. نمیخواهم فقط یادآوری کنم این چیزها وجود دارند، بلکه توصیه میکنم آنها را بهعنوان اصل محرک زیر همهٔ کاری که انجام میدهید بپذیرید.
بنیاد یک رشتهٔ مهندسی
این ایدهها، که حول اصول بهینهسازی همهٔ کارمان برای بیشینهکردن توانایی یادگیری و مدیریت پیچیدگی سیستمهایی که میسازیم سازماندهی شدهاند، واقعاً بنیاد رشتهای هستند که میتوانیم بهحق آن را رویکرد مهندسی برای حل مسائل با نرمافزار بنامیم.
اگر این کارها را انجام دهیم، احتمال موفقیت بالاتر از اگر نکنیم است.
این رویکرد «چرخاندن دسته» نیست. نرمافزار عالی با فقط دنبال کردن دستورالعمل من یا هرکس دیگر نمیگیرید، بیش از آنکه ماشین عالی با دستورالعمل افسانهای dot-to-dot-car-builder بسازید.
نیاز به فکرکردن، دقت، احتیاط و هوشمندی دارید. توسعهٔ نرمافزار کاری آسان برای انجام خوب نیست. بعضی اشکال coding شاید باشد، اما همانطور که توضیح دادم، توسعهٔ نرمافزار بسیار فراتر از فقط coding است.
این مدل سادهای برای مهندسی نرمافزار است، اما کاربردش دشوار است.
سادگیاش در این است که ده ایدهٔ بنیادی در دو گروه و سپس چند ابزار مثل testability، deployability، speed، controlling the variables و continuous delivery که به دستیابی به اصول بنیادی کمک میکنند — و همین است. اما پیامدهای این ده چیز اغلب برانگیزانندهٔ تفکر و پیچیده است؛ کاربرد را دشوار میکند.
تسلط بر استفاده از این ابزارها و بهکار بردن این ایدهها بهعنوان اصول بنیادین زیر طراحیها و تصمیمها شانس موفقیت را تقویت میکند. مبنای تصمیمگیری دربارهٔ نرمافزاری که میسازیم به نظر من در قلب رشتهٔ توسعهٔ نرمافزار است.
هدف این کتاب نگفتن «نرمافزار آسان است» بلکه پذیرفتن «نرمافزار دشوار است، پس با دقت به آن نزدیک شویم» است.
برای من یعنی با کمی دقت بیشتر، در چارچوب فکری که به ما امکان میدهد پاسخهای بهتری به سؤالاتی که هنوز به آنها فکر نکردهایم بیابیم. رویکردی برای یافتن راهحل مسائلی که اصلاً نمیدانیم چگونه حل کنیم.
این ده چیز این چارچوب را به من میدهد و افراد و تیمهای زیادی از بهکار بردن آنها سود بردهاند.
درک ماهیت رشتهٔ ما توانایی پیشرفت را تحتتأثیر قرار میدهد. بهرسمیت شناخت پیچیدگی سیستمهایی که میسازیم و ماهیت ذاتی نرمافزار برای موفقیت مهم است. سبک گرفتن آن بهعنوان تمرین سادهٔ coding دنبالهٔ نیمهخطی دستورالعملها همیشه محکوم به شکست است، جز در سادهترین تمرینهای برنامهنویسی.
باید ابزارهای فکری را به کار ببریم که با هر شرایطی که روبهرو میشویم سازگار شوند. به نظر من این در قلب هر چیزی است که میتوانیم رشتهٔ مهندسی واقعی برای نرمافزار بنامیم.
مهندسی بهعنوان فرایند انسانی
اصطلاح engineering میتواند لغزنده باشد، چون اغلب در زمینهٔ توسعهٔ نرمافزار بهاشتباه به کار میرود.
بیشتر تعاریف engineering با چیزی مثل «مطالعهٔ کار یک مهندس» شروع میشوند و سپس استفاده از ریاضی و علمی را که آن کار را راهنمایی میکند توصیف میکنند. پس واقعاً دربارهٔ فرایند، رویکرد ما به انجام کار است.
تعریف کاری که در ابتدای این کتاب معرفی کردم برای من به هدف میخورد:
Engineering is the application of an empirical, scientific approach to finding efficient, economic solutions to practical problems.
مهندسی empirical است — انتظار نداریم هر بار نتایج کامل بگیریم. (در واقع علم هم اینطور کار نمیکند؛ فقط تلاش میکند به آن نزدیک شود.)
مهندسی دربارهٔ تصمیمگیریهای آگاهانهٔ منطقی است، اغلب با اطلاعات ناقص، و سپس دیدن اینکه ایدهها در واقعیت چگونه عمل میکنند بر اساس feedbackی که از تجربهٔ دنیای واقعی جمع میکنیم.
بر پایهٔ سبک استدلال علمی است. میخواهیم آنچه منطقی است اندازه بگیریم. رویکرد آزمایشی به ایجاد تغییرات بگیریم. variables را کنترل کنیم تا اثر تغییراتمان را بفهمیم. مدل یا فرضیه بسازیم و نگه داریم تا بتوانیم پیوسته درکمان را با رشد آن ارزیابی کنیم.
مهم است که راهحلهایی که پیدا میکنیم و نحوهٔ کار برای دستیابی به آنها کارآمد باشند.
میخواهیم سیستمهایی که میسازیم تا حد ممکن ساده باشند و تا حد ممکن سریع اجرا شوند در حالی که حداقل منابع لازم برای موفقیت مصرف کنند.
همچنین میخواهیم بتوانیم آنها را سریع و با کمترین میزان کار بسازیم. این برای دلایل اقتصادی مهم است، اما بهشدت مهم است اگر بخواهیم بهطور مؤثر یاد بگیریم. بهموقع بودن feedback معیار خوبی از کارایی کاری است که انجام میدهیم. بهموقع بودن feedback، همانطور که در فصل ۵ بررسی کردیم، بنیادی برای توانایی ما برای یادگیری مؤثر است.
علاوه بر کاربردپذیری عمومی engineering thinking به توسعه، مهم است بشناسیم سازمانها و تیمهایی که در آن کار میکنیم information systems هم هستند، پس ایدههای managing complexity به همان اندازه — اگر نه بیشتر — به آنها هم اعمال میشوند.
سازمانهای digitally disruptive
رایج است کسبوکارها و رهبران کسبوکار دربارهٔ ایدههایی مثل digital disruption صحبت کنند — یعنی فناوریهای دیجیتال برای بازآفرینی و مختل کردن کسبوکارهای سنتی. به Amazon فکر کنید که زنجیرهٔ تأمین خردهفروشی را مختل میکند، Tesla که اصول تولید خودرو را تغییر میدهد، یا Uber که خدمات تاکسی را به gig economy تبدیل میکند. این ایدهها برای کسبوکارهای سنتی و تفکر تجاری سنتی چالشبرانگیزند.
یکی از ویژگیهای تعیینکنندهٔ چنین سازمانهایی این است که تقریباً همیشه engineering-led هستند. توسعهٔ نرمافزار مرکز هزینه یا تابع پشتیبانی نیست؛ خودِ «کسبوکار» است.
حتی شرکتی مثل Tesla، که محصولش دستگاه فیزیکی است، سازمانش را حول ایدههای نرمافزاری شکل داده.
Tesla تا حدی شرکت continuous delivery است که اگر کسی ایدهٔ جدیدی داشته باشد، میتواند کارخانه را — اغلب از طریق نرمافزار — برای اعمال ایدهٔ جدید پیکربندی مجدد کند.
نرمافزار نحوهٔ انجام کسبوکار را تغییر میدهد و برای این کار بسیاری از فرضهای سنتی را به چالش میکشد.
یکی از مدلهای مورد علاقهٔ من از Jan Bosch است؛ آن را «BAPO در برابر OBAP» توصیف میکند.¹ شکل ۱۵.۱ و ۱۵.۲ ایده را توضیح میدهند.
B O
A
Pشکل ۱۵.۱ — چگونه بیشتر کسبوکارها برنامهریزی میکنند (OBAP)
بیشتر شرکتها مدل OBAP را دنبال میکنند (شکل ۱۵.۱): نخست سازمان — بخشها، تیمها، مسئولیتها — را ثابت میکنند. سپس استراتژی کسبوکار و نحوهٔ ایجاد درآمد و سود یا سایر نتایج تجاری را بر اساس محدودیتهای تصمیمات سازمانی تعیین میکنند. بعد معماری مناسب را انتخاب میکنند و در نهایت فرایندی که آن معماری را تحویل دهد.
این تا حدی دیوانه است. چشمانداز و اهداف کسبوکار توسط ساختار سازمانی محدود میشوند.
مدل منطقیتر این است که ساختار سازمانها را بهعنوان ابزار در نظر بگیریم: BAPO.
چشمانداز و اهداف کسبوکار را مشخص میکنیم، تصمیم میگیریم از نظر فنی چگونه به آن برسیم (architecture)، میفهمیم چگونه چنین چیزی بسازیم (process)، و سپس ساختار سازمانی را انتخاب میکنیم که فعالیتهای لازم را پشتیبانی کند.
B O
A
Pشکل ۱۵.۲ — چگونه کسبوکار باید سازماندهی شود (BAPO)
وقتی شروع به فکر کردن دربارهٔ روشهای سازماندهی گروههای افراد بهعنوان ابزاری برای دستیابی به هدف میکنیم، بهکار بردن نوع engineering thinking که در این کتاب توصیف شد برای بهکارگیری مؤثر آن ابزار محوری است.
همانطور که برای هر information system دیگر، مدیریت coupling در سازمانها یکی از کلیدهای موفقیت است. همانطور که برای نرمافزار درست است، برای سازمانها هم درست است. سازمانهای modular و cohesive با separation of concerns منطقی و تیمهایی که بهگونهای abstract شدهاند که اطلاعات را از بخشهای دیگر پنهان کنند، مقیاسپذیرتر و کارآمدتر از گروههای tightly coupled هستند که فقط در قدم هماهنگ پیشرفت میکنند.
این یکی از دلایلی است که scale کردن سازمانها اینقدر سخت است. با رشد، هزینههای coupling افزایش مییابد. طراحی سازمانها برای به حداقل رساندن coupling بین گروههای مختلف افراد، استراتژی مدرن شرکتهای بزرگ و سریعالرشد است.
تصادفی نیست که پژوهش پشت کتاب Accelerate یکی از ویژگیهای تعیینکنندهٔ تیمهای با عملکرد بالا — بر اساس معیارهای stability و throughput — را این یافته که میتوانند درون تیم تصمیم بگیرند بدون اینکه اجازه بگیرند یا با گروههای دیگر هماهنگ کنند. چنین تیمهایی از نظر اطلاعاتی decoupled هستند.
این موضوع مهم است. تفاوت بین سازمانی مثل Amazon که با دو برابر شدن اندازه بیش از دو برابر بهرهور میشود، و شرکتی با ساختار سنتیتر که با دو برابر شدن اندازه فقط ۸۵ درصد بهرهورتر میشود.²
Outcomes در برابر Mechanisms
وقتی به نوشتن نتیجهگیریهای این کتاب نزدیک شدم، در بحث آنلاینی دربارهٔ اهمیت outcomes و mechanisms شرکت کردم. از قطعیت مطلق شروع کردم که همه موافق خواهند بود outcomes مهمتر از mechanism است. بهسرعت از این فرض بیرون آمدم.
با این حال، فکر نمیکنم مخاطبانم بهخاطر اختلاف نظر احمق بودند. با نگاه به پاسخها، فکر میکنم در نهایت با نکتهٔ من موافق شدند. اهمیت «outcomes» را رد نمیکردند؛ نگران چیزهای ضمنی بودند که ارزش مینهادند، یا mechanismهایی که ترجیح میدادند و به دستیابی به outcomes مطلوب کمک میکردند.
outcome موفق برای توسعهٔ نرمافزار ایدهٔ پیچیدهای است. با چیزهای قابلاندازهگیری آشکار شروع میکنیم. outcomes تجاری برای برخی کسبوکارها/نرمافزارها — یک معیار. اعداد استفاده؛ موفقیت پروژهٔ open source اغلب با تعداد download اندازهگیری میشود. معیارهای DORA productivity و quality، stability و throughput را اندازه میگیرند — تیمهای موفق نرمافزار با کیفیت بسیار بالا و بسیار کارآمد تولید میکنند. رضایت مشتری از طریق معیارهای مختلف.
امتیاز خوب در همهٔ ابعاد تا حدی outcome مطلوب است. بعضی بسترمند، بعضی نه. کار کردن کارآمد با کیفیت (امتیاز خوب stability و throughput) در هر بستری موفقتر است — به همین دلیل این معیارها را ابزار مؤثری میدانم.
بستر بحث «outcomes مهمتر از mechanisms»: مناظرهٔ continuous delivery بهعنوان ایده در مقایسه با DevOps.³ نکتهٔ من: continuous delivery outcome مطلوب را تعریف میکند نه mechanism — بهعنوان اصل سازماندهندهٔ عمومی برای هدایت استراتژی توسعه مفیدتر است.
DevOps مجموعهٔ بسیار مفیدی از practices است؛ اگر همه را بپذیرید و خوب انجام دهید، میتوانید بهطور پیوسته value تحویل دهید. اما اگر شرایطی خارج از دامنهٔ DevOps پیش آید — چون بیشتر مجموعهای از practices است — کمتر مشخص است چگونه برخورد کنیم.
continuous delivery اما میگوید «طوری کار کنید که نرمافزار همیشه releasable باشد»، «برای fast feedback بهینه کنید»، «هدف ما کارآمدترین feedback از ایده تا نرمافزار ارزشمند در دست کاربران است.»
اگر این ایدهها را جدی بگیریم، میتوانیم راهحلهای نوآورانهٔ منحصربهفرد برای مسائلی که قبلاً با آنها روبهرو نشدهایم بیابیم.
Durable و Generally Applicable
وقتی من و دیگران شروع به تدوین continuous delivery کردیم، هرگز ماشین یا فضاپیما یا شبکهٔ مخابراتی نساخته بودیم. هر کدام چالشهای بسیار متفاوتی دارند. بهعنوان مشاور به مشتریانم اهداف مشخصی برای deployment pipelineها توصیه میکنم: پنج دقیقه برای commit stage و کمتر از یک ساعت برای کل pipeline. «هدف: هر ساعت چیزی releasable بسازید.»
اگر Tesla ماشین میسازد یا SpaceX موشک یا Ericsson زیرساخت جهانی موبایل — احتمالاً ممکن نیست چون فیزیک سوزاندن سیلیکون یا ساختن چیزها از فلز مانع میشود.
با این حال اصول continuous delivery همچنان برقرارند: «طوری کار کنید که نرمافزار همیشه releasable باشد.» بهطور کامل test کنید، اگر یک test شکست خورد فوراً رد کنید. «برای fast feedback بهینه کنید.» همهچیز را automate کنید. عمیقتر: ایدههایی از علم که continuous delivery بر آنها بنا شده پایدارتریناند.
- Characterize: مشاهدهٔ وضعیت فعلی.
- Hypothesize: توصیف/نظریهای که مشاهده را توضیح دهد.
- Predict: پیشبینی بر اساس hypothesis.
- Experiment: test کردن پیشبینی.
برای فهمیدن آنچه یاد میگیریم باید variables را کنترل کنیم. گامهای کوچک، کنترل کامل configuration، محدود کردن دامنهٔ تغییر با تکنیکهای managing complexity.
این همان engineering است — ایدهها، روشها و ابزارهایی که بهطور اثباتشده شانس موفقیت بالاتری میدهند.
شاید به اهداف feedback که معمولاً توصیه میکنم نرسیم، اما میتوانیم آنها را بهعنوان هدف در محدودیتهای فیزیکی یا اقتصادی دنبال کنیم.
اگر در تعریف رشتهٔ engineering برای توسعهٔ نرمافزار موفق شویم، مستقل از فناوری خواهد بود. اصولش پایدار، برای پاسخ به سؤالات پیشبینینشده و فهم فناوریهایی که هنوز اختراع نشدهاند مفیدند.
میتوانیم این را امتحان کنیم!
حرفهٔ من صرف توسعهٔ نرمافزاری شده که همکاران و من طراحی کردهایم، اما آیا میتوانیم این نوع تفکر را به شکل دیگری از توسعهٔ نرمافزار — machine learning (ML) — اعمال کنیم؟
شکل ۱۵.۳ workflow معمول ML را نشان میدهد.
Preparation Training Production
Data Data Model Production
Training
Collection Preparation Development Use
Accuracy
Achieved
Validation
Accuracy/
Fitness
Not Achieved
Monitoring
Retrainشکل ۱۵.۳ — workflow معمول ML
اگر accuracy بهدست نیاید، فرایند با تغییر training data و fitness functionها توسط developerها/data scientistها دوباره میچرخد.
وقتی به production رسید، monitor میشود؛ اگر مشکلی باشد → به چرخهٔ retrain برمیگردد.
مدل engineering ما چگونه جا میگیرد؟
واضح است توسعهٔ ML همهاش دربارهٔ learning است — نه فقط برای ماشین. developerها باید کار و رویکردشان را بهینه کنند تا یاد بگیرند چه دادهای برای train استفاده کنند و چه چیزی در fitness functionها کار میکند.
train کردن دادهٔ زیادی میخواهد — پس managing complexity ضروری است. آسان و رایج است data scientistها در انبوه داده گم شوند و پیشرفت reproducible نداشته باشند.
فرایند توسعه بهترین حالت وقتی است که تکراری باشد. مونتاژ/آمادهسازی training data و تعریف/پالایش fitness functionها اساساً تکراری هستند. feedback به شکل دقت تطابق با fitness function است. وقتی iterationها کوتاه و feedback سریع و واضح باشد بهترین کار را میکند. کل فرایند iteration و پالایش آزمایشی است.
فکر کردن اینطور فرصتهایی برای کار بهتر میدهد. منطقی است فرایند را بهینه کنیم تا developerها سریع دور بزنند و کیفیت یادگیری در هر iteration بهبود یابد. یعنی گامهای کوچکتر و وضوح دربارهٔ ماهیت و کیفیت feedback.
فکر کردن به هر گام کوچک بهعنوان experiment تشویق میکند کنترل بیشتری روی variables داشته باشیم — مثلاً version control اسکریپتها و training data.
تا حدی عجیب است تصور کنیم این بخش برنامهریزی شده، غیرپویا، غیرتکراری و بدون کشف تجربی مبتنی بر feedback باشد.
چرا empirical؟ چون دادهها messy هستند و outcomes آنقدر پیچیدهاند که در سطح کنترلی که معمولاً در توسعهٔ ML اعمال میشود deterministic نیستند.
سؤال جالبی: آیا میتوان کنترل بیشتری اعمال کرد؟ در گفتگو با یک متخصص ML، تصویر سادهٔ من (شکل ۱۵.۳) زیر سؤال رفت. «monitoring یعنی چه؟ چگونه ممکن است نتیجه را بدانیم؟»
با رویکرد engineering، release مدل به production را بهعنوان experiment میبینیم. اگر experiment است، پیشبینیای داریم و باید test کنیم. در نقطهٔ ساخت سیستم ML میتوانیم توصیف کنیم چه میخواهیم انجام دهیم. نوع outcomes مورد انتظار را پیشبینی کنیم. این فراتر از fitness function است — مثل تعریف error-bounds، محدودهای که پاسخهای منطقی باید در آن بیفتند.
اگر ML برای فروش کتاب بیشتر طراحی شده، احتمالاً کار خوبی نمیکند اگر پاسخ به سمت «سعی کن دنیا را تصاحب کنی» منحرف شود.
managing complexity؟ یکی از مشکلات این است که افراد ML اغلب پیشینهٔ software ندارند. بسیاری از تکنیکهای عادی توسعهٔ نرمافزار — حتی version control — هنجار نیست.
آسان است ببینیم اصول engineering چگونه اعمال میشوند. رویکرد modular به نوشتن اسکریپتهای مونتاژ، پاکسازی داده و تعریف fitness functionها واضح است. این کد است — از ابزارهای لازم برای نوشتن کد خوب استفاده کنید. variables را کنترل کنید، با cohesion ایدههای مرتبط را نزدیک نگه دارید، با modularity/separation/abstraction/coupling کاهش coupling. برای داده هم درست است. training data modular (متمرکز بر جنبههای درست مسئله) به تکرار سریعتر، محدود کردن تغییرات و تمرکز فرایند train کمک میکند — یک برداشت از data cleansing.
separation of concerns درون داده و fitness functionها هم مهم است. میتوان تصمیمهای بد ML بر اساس «فرضیات» درونساخته بین شرایط اقتصادی/گروههای قومی یا حقوق/جنسیت را poor separation of concerns در training data و بیانی تلخ از جامعهٔ ما دانست.
اینجا متوقف میشوم، قبل از آنکه بیشتر جهل خودم دربارهٔ ML را آشکار کنم. نکتهٔ من: اگر این ابزارهای فکری بهطور عمومی قابلاعمال باشند، راههای مفیدی برای نزدیک شدن به مسائل میدهند حتی وقتی نادان هستیم. ادعا نمیکنم پاسخهای درست دادهام، اما مدل من اجازه داد سؤالاتی بپرسم که تا جایی که میفهمم در حلقههای ML معمولاً پرسیده نمیشوند — سؤالاتی که میتوان بررسی کرد و شاید به بهینهسازی فرایند، بهبود کیفیت تولید سیستمهای ML و حتی بهبود خود سیستمها کمک کنند.
از فرایند engineering واقعی انتظار داریم پاسخ ندهد، اما رویکردی به سمت پاسخهای بهتر راهنمایی کند.
Foundations of an Engineering Discipline
ایدههای این کتاب بنیاد رشتهٔ engineering را میسازند که شانس موفقیت را تقویت میکند.
زبان برنامهنویسی که انتخاب میکنید واقعاً مهم نیست. framework که بهکار میبرید واقعاً مهم نیست. methodology که برمیگزینید کمتر از ایدههایی که outline کردم اهمیت دارد.
نه اینکه چیزهای دیگر بیتأثیر باشند — هستند. به اندازهٔ مدل چکشی که نجار انتخاب میکند اهمیت دارند. برای نرمافزار کمی بیش از ترجیح شخصی است — بر نحوهٔ کار تیم اثر میگذارد — اما در جوهره انتخاب یک فناوری بر دیگری کمتر از نحوهٔ بهکارگیری آن فناوری بر outcome اثر میگذارد.
قصد من توصیف ایدههایی است که بهطور کلی راهنمایی برای بهکارگیری مؤثرتر ابزارهایمان ارائه میدهند.
با تمرکز بر اصول بهینهسازی برای یادگیری و managing complexity، شانس موفقیت را هر فناوری که انتخاب کنیم افزایش میدهیم.
خلاصه
ایدههای این کتاب سالها مبنای رویکرد من به توسعهٔ نرمافزار بودهاند. فرایند نوشتن این کتاب به من کمک کرد تفکرم را متبلور کنم — امیدوارم ارتباط آسانتر شده باشد.
در مراحل پایانی حرفهام تقریباً منحصراً روی سیستمهای پیچیده کار کردهام. خوششانس بودهام روی چند مسئلهای کار کنم که شاید هیچکس یا تقریباً هیچکس قبلاً حل نکرده باشد. هر وقت تیم و من گیر میکردیم، به این اصول بنیادی رجوع میکردیم. بهعنوان نردههای راهنما به سمت نتایج بهتر عمل میکردند، هرچه ماهیت مسئله باشد، حتی وقتی اصلاً نمیدانستیم چگونه پیش برویم.
این روزها عمدتاً با مشاوره به شرکتهای چندملیتی بزرگ زندگی میکنم، اغلب کارهای نوآورانه در مقیاسهای بیسابقه. این ایدهها همچنان برقرارند و به حل مسائل واقعاً دشوار راهنمایی میکنند.
وقتی برای خودم کد مینویسم — هنوز لذت بزرگی است — همان ایدهها را در کوچکترین و اغلب سادهترین مقیاسها بهکار میبرم.
اگر همیشه کار و نحوهٔ انجام آن را برای بیشینهکردن توانایی یادگیری مؤثر بهینه کنید، کار بهتری خواهید کرد.
اگر همیشه در هر مقیاس برای مدیریت پیچیدگی کار جلویتان کار کنید، میتوانید توانایی انجام کار بهتر را بهطور نامحدود حفظ کنید.
اینها ویژگیهای رشتهٔ engineering واقعی برای توسعهٔ نرمافزار است. وقتی آن رشته را بهکار ببریم، شانس ساخت نرمافزار بهتر و سریعتر را بهشکل چشمگیر بهبود میدهیم.
چیز مهمی و ارزشمندی اینجاست. امیدوارم توانسته باشم آن را بهگونهای بیان کنم که در کار شما مفید باشد.
¹ Jan Bosch «Structure Eats Strategy» https://bit.ly/33GBrR1 و کتاب Speed, Data and Ecosystems https://amzn.to/3x5Ef6T
² James Lewis، inventor microservices: https://youtu.be/tYHJgvJzbAk
³ CD versus DevOps: https://youtu.be/-sErBqZgKGs
فهرست
A
- abstraction(s)، ۱۵۵، ۱۵۹، ۱۷۰، ۱۷۷
- accidental complexity، ۱۶۶–۱۶۸
- information hiding، ۱۵۱–۱۵۲
- isolating third-party systems، ۱۶۸–۱۶۹
- leaky، ۱۶۲–۱۶۳، ۱۶۷
- maps، ۱۶۳–۱۶۴
- models، ۱۶۳، ۱۶۴
- picking، ۱۶۳–۱۶۵
- plain text، ۱۶۱–۱۶۲
- power of، ۱۶۰–۱۶۲
- pragmatism، ۱۵۷–۱۵۸
- from problem domain، ۱۶۵
- raising level of، ۱۵۶–۱۵۷
- storage، ۱۶۸
- testing، ۱۵۹–۱۶۰
- Accelerate: The Science of Lean Software & DevOps، ۹، ۳۳، ۳۴، ۱۵۳، ۲۰۹
- acceptance test-driven development، ۹۷
- accidental complexity
- abstracting، ۱۶۶–۱۶۸
- separation of concerns، ۱۳۹–۱۴۲
- agile development، ۳۲، ۴۴–۴۵، ۴۶، ۵۰، ۵۳، ۵۴، ۶۹، ۷۴، ۷۷
- waterfall approach، ۵۳
- Agile Manifesto، ۴۴، ۵۰
- algorithms، ۸۶–۸۷
- alphabet، ۵۲
- Amdahl's law، ۸۸
- APIs، ۱۰۸، ۱۱۵، ۱۱۷، ۱۴۷، ۱۴۸
- functions، ۱۴۸–۱۴۹
- Ports and Adapters pattern، ۱۴۹
- Apollo space program، ۱۵–۱۶
- modularity، ۷۲–۷۳
- architecture, feedback، ۶۵–۶۷
- Armstrong, N.، ۱۶
- asynchronous programming، ۱۸۰–۱۸۲
- automated testing، ۹۷–۹۸، ۱۱۲، ۱۹۹، ۲۱۱
- aviation
- designing for testability، ۱۰۹–۱۱۱
- modularity، ۷۲
B
- Barker, M.، ۸۶
- BDD (behavior-driven development)، ۱۸۸
- Beck, H.، ۱۶۴
- Beck, K.، ۱۲۱
- Extreme Programming Explained، ۵۳، ۱۰۸، ۱۵۵
- big balls of mud، ۱۷۲. See also quality, causes of
- fear of over-engineering، ۱۵۷–۱۵۹
- organizational and cultural problems، ۱۵۲–۱۵۴
- technical and design problems، ۱۵۴–۱۵۷
- birth of software engineering، ۷–۸
- Bosch, J.، ۲۰۸
- bounded context، ۱۲۶، ۱۴۴، ۱۴۷، ۱۶۵. See also DDD
- bridge building، ۳۱
- software development، ۱۱، ۱۲
- Brooks, F.، ۷، ۸، ۱۸–۱۹، ۳۲، ۱۱۹، ۱۵۵
- The Mythical Man Month، ۵۰، ۷۴
C
- cache-misses، ۸۵–۸۶
- carbon fiber، ۲۵–۲۶
- CI (continuous integration)، ۵۴، ۷۶
- FB (feature branching)، ۶۲–۶۳
- feedback، ۶۱–۶۳
- cloud computing, abstraction، ۱۶۱
- code، ۱۷، ۳۸، ۶۹، ۷۵، ۸۳، ۸۸، ۹۵، ۱۱۵
- big balls of mud, causes of، ۱۵۲، ۱۵۴–۱۵۷. See also quality
- fear of over-engineering، ۱۵۷–۱۵۹
- organizational and cultural problems، ۱۵۲–۱۵۴
- technical and design problems، ۱۵۴–۱۵۷
- cache-misses، ۸۵–۸۶
- cohesive، ۱۲۲–۱۲۵
- compilers، ۱۲۸
- concurrency، ۲۰۱
- coupling، ۲۶، ۳۷، ۶۷، ۱۱۷، ۱۱۹، ۱۶۴، ۱۶۸، ۱۶۹، ۱۷۱، ۱۸۴
- cohesion، ۱۲۹
- cost of، ۱۷۱–۱۷۲
- DRY، ۱۷۹
- loose، ۱۷۵–۱۷۶، ۱۷۷–۱۷۸، ۱۸۰–۱۸۴
- microservices، ۱۷۳–۱۷۴
- Nygard model، ۱۷۶–۱۷۷
- separation of concerns، ۱۷۸–۱۷۹
- feedback، ۶۰–۶۱
- formal methods، ۱۳
- future-proofing، ۱۵۸–۱۵۹
- information hiding، ۱۵۱–۱۵۲، ۱۵۵، ۱۶۹–۱۷۰
- isolating third-party systems، ۱۶۸–۱۶۹
- managing complexity، ۷۸–۷۹
- messaging، ۸۳، ۱۴۸
- quality، ۶۳–۶۴
- readability، ۱۷۶
- «round-trip»، ۱۵۶
- seams، ۱۶۷
- separation of concerns، ۱۲۷، ۱۳۱، ۱۳۵–۱۳۶، ۱۳۷–۱۳۸
- complexity، ۱۳۹–۱۴۲
- DDD، ۱۴۲–۱۴۴
- dependency injection، ۱۳۹
- Ports and Adapters pattern، ۱۴۵–۱۴۷
- testability، ۱۳۸، ۱۴۴
- third-party، ۱۶۹
- cohesion، ۱۲۵، ۱۳۳، ۱۴۰، ۱۶۶، ۱۶۷، ۱۷۵
- in coding، ۱۲۲–۱۲۵
- coupling، ۱۲۹
- in human systems، ۱۳۳
- modularity، ۱۲۱–۱۲۲
- poor، ۱۳۲–۱۳۳
- in software، ۱۳۰–۱۳۲
- TDD، ۱۲۹
- compare-and-swap، ۸۷
- complexity، ۴–۵، ۲۱–۲۲، ۳۲، ۵۹، ۷۰، ۷۷–۷۸، ۱۲۷. See also coupling; separation of concerns
- accidental، ۱۳۹–۱۴۰
- abstracting، ۱۶۶–۱۶۸
- separation of concerns، ۱۳۹–۱۴۲
- Conway's law، ۳۷
- coupling، ۱۷۱
- determinism، ۱۱۲–۱۱۴
- managing، ۳۶، ۳۷–۳۸، ۷۴، ۷۸–۷۹، ۱۲۷، ۱۵۲، ۲۱۴
- modularity، ۷۲، ۷۳، ۱۰۵–۱۰۶، ۱۰۷–۱۰۸، ۱۱۸
- precision، ۱۱۲
- productivity، ۴۹–۵۰
- separation of concerns، ۱۳۹–۱۴۲
- accidental، ۱۳۹–۱۴۰
- computers، ۱۳، ۲۰، ۹۹، ۱۶۶، ۲۰۱. See also abstraction(s); programming
- abstraction، ۱۶۲
- evolution of programming languages، ۱۸–۱۹
- concurrency، ۳۷، ۸۶، ۸۸، ۲۰۱
- compare-and-swap، ۸۷
- determinism، ۱۱۳
- continuous delivery، ۳۳، ۴۸، ۶۰، ۶۵، ۶۶، ۶۷، ۷۰، ۷۷، ۹۶، ۱۶۰، ۱۸۰، ۱۸۳، ۱۹۹، ۲۰۱–۲۰۲، ۲۰۸، ۲۱۰
- deployment pipeline، ۱۷۹، ۱۹۷–۱۹۹
- continuous integration (CI)، ۷۰
- Conway's law، ۳۷
- Cost of Change model، ۴۶–۴۸، ۱۵۹
- coupling، ۲۶، ۳۷، ۶۷، ۱۱۷، ۱۱۹، ۱۶۴، ۱۶۸، ۱۶۹، ۱۷۱، ۱۸۴. See also abstraction(s); cohesion; separation of concerns
- cohesion، ۱۲۹
- cost of، ۱۷۱–۱۷۲
- developmental، ۱۷۴، ۱۷۹، ۱۸۳
- DRY، ۱۷۹، ۱۸۰
- loose، ۱۷۴، ۱۷۵–۱۷۶، ۱۷۷–۱۷۸
- asynchronous programming، ۱۸۰–۱۸۲
- designing for، ۱۸۲
- in human systems، ۱۸۲–۱۸۴
- microservices، ۱۷۳–۱۷۴، ۱۸۳–۱۸۴
- Nygard model، ۱۷۶–۱۷۷
- scaling up development، ۱۷۲–۱۷۳
- separation of concerns، ۱۷۸–۱۷۹
- CPU, clock cycle، ۸۶–۸۷
- craftsmanship، ۱۹
- complexity، ۲۱–۲۲
- creativity، ۲۴–۲۵
- engineering، ۲۷–۲۸
- limits of، ۱۹–۲۰
- repeatability، ۲۳
- creativity، ۷۰، ۷۴
D
- DDD (domain-driven design)، ۱۲۵–۱۲۶، ۱۴۲–۱۴۴
- bounded context، ۱۲۶، ۱۴۴
- dependency injection، ۱۱۸، ۱۳۹
- dependency management، ۱۷۹
- deployability، ۱۹۷–۱۹۹
- controlling the variables، ۲۰۰–۲۰۱
- feedback، ۱۹۹
- independent، ۱۷۴
- microservices، ۱۷۴
- modularity، ۱۱۶–۱۱۷
- deployment pipeline، ۱۱۶–۱۱۷، ۱۳۶، ۱۷۹
- releasability، ۱۹۸
- design engineering، ۱۲–۱۳، ۱۴–۱۵، ۲۶
- feedback، ۶۳–۶۴
- design principles. See also complexity; DDD; feedback; iteration; software development
- cohesion، ۱۲۵، ۱۳۳
- in coding، ۱۲۲–۱۲۵
- coupling، ۱۲۹
- in human systems، ۱۳۳
- modularity، ۱۲۱–۱۲۲
- poor، ۱۳۲–۱۳۳
- in software، ۱۳۰–۱۳۲
- TDD، ۱۲۹
- incrementalism، ۷۱، ۷۹
- iteration، ۷۱–۷۲
- limiting impact of change، ۷۶–۷۷
- modularity، ۷۲–۷۳
- organizational، ۷۳–۷۴
- Ports and Adapters pattern، ۷۶–۷۷
- tools of، ۷۴–۷۶
- modularity، ۷۲–۷۳، ۷۵، ۱۰۶، ۱۰۸، ۱۱۳، ۱۲۰. See also incrementalism
- Apollo space program، ۷۲–۷۳
- cohesion، ۱۲۱–۱۲۲
- complexity، ۷۳، ۱۰۵–۱۰۶، ۱۰۷–۱۰۸، ۱۱۸
- deployability، ۱۱۶–۱۱۷
- at different scales، ۱۱۸
- hallmarks of، ۱۰۶
- in human systems، ۱۱۸–۱۱۹
- microservices، ۷۳
- organizational incrementalism، ۷۳–۷۴
- services، ۱۱۵–۱۱۶
- testability، ۱۰۹–۱۱۲
- testing، ۱۱۳
- undervaluing importance of طراحی خوب، ۱۰۷–۱۰۸
- separation of concerns، ۱۲۷، ۱۳۱، ۱۳۵–۱۳۶، ۱۳۷–۱۳۸
- complexity، ۱۳۹–۱۴۲
- DDD، ۱۴۲–۱۴۴
- dependency injection، ۱۳۹
- Ports and Adapters pattern، ۱۴۵–۱۴۷
- TDD، ۱۴۹–۱۵۰
- testability، ۱۳۸، ۱۴۴
- cohesion، ۱۲۵، ۱۳۳
- determinism, complexity، ۱۱۲–۱۱۴
- Deutsch, D.، ۸۵
- The Beginning of Infinity، ۵۱–۵۳
- DevOps، ۵۹، ۶۷، ۱۵۳، ۲۱۰
- diagram-driven development، ۱۵۶–۱۵۷، ۱۶۵
- digitally disruptive organizations، ۲۰۷–۲۰۹
- Dijkstra, E.، ۲۲
- DRY («Don't Repeat Yourself»)، ۱۷۹، ۱۸۰
- DSL (domain-specific language)، ۱۶۵
E
- empiricism، ۱۶، ۱۷، ۴۵، ۸۱، ۸۲، ۲۰۷، ۲۱۳
- avoiding self-deception، ۸۴–۸۵
- experimentation، ۸۲
- parallelism، ۸۸
- software testing، ۸۲–۸۴
- engineering، ۶، ۹، ۲۹–۳۰، ۸۱، ۸۲، ۸۹، ۹۹، ۲۱۱. See also software engineering
- bridge building، ۳۱
- complexity، ۲۱–۲۲
- craftsmanship، ۲۷–۲۸
- creativity، ۲۴–۲۵
- design، ۱۲–۱۳، ۱۴–۱۵
- empiricism، ۱۶
- experimentation، ۹۲
- as human process، ۲۰۷
- math، ۱۳–۱۴
- models، ۱۲–۱۳، ۱۴
- over-engineering، ۱۵۷–۱۵۹
- pragmatism، ۱۵۸
- precision، ۲۰–۲۱
- production، ۱۱، ۱۹، ۴۹
- progress، ۲۶–۲۷
- rationalism، ۲۶
- repeatability، ۲۲–۲۳
- scalability، ۲۰–۲۱، ۲۵
- software development، ۱۳
- solutions، ۱۷
- tools، ۲۰۲
- trade-offs، ۲۶
- working definition، ۱۷
- Evans, E., Domain Driven Design، ۱۴۷
- event storming، ۱۶۵
- experimentation، ۸۱، ۸۵، ۸۸، ۹۱–۹۲، ۹۳، ۱۰۰، ۱۱۰، ۱۹۹
- automated testing، ۹۷–۹۸
- controlling the variables، ۹۶–۹۷
- empiricism، ۸۲
- engineering، ۹۲
- feedback، ۹۳، ۹۴
- hypotheses، ۹۴–۹۵، ۹۷
- measurement، ۹۵–۹۶
- results of testing، ۹۸–۱۰۰
- scope of experiment، ۱۰۰
- exploration، ۴۵
- Extreme Programming، ۴۵، ۵۰، ۶۴
F
- Farley, D., Continuous Delivery، ۱۱۶، ۱۸۳، ۱۹۷
- FB (feature branching)، ۶۲
- CI، ۶۲–۶۳
- feedback، ۵۷، ۵۹–۶۰، ۷۰، ۷۶، ۸۷، ۹۷، ۱۰۸، ۱۸۳، ۱۸۹، ۲۰۷، ۲۱۱
- in architecture، ۶۵–۶۷
- in coding، ۶۰–۶۱
- in design، ۶۳–۶۴
- early، ۶۷
- experimentation، ۹۳، ۹۴
- importance of، ۵۸–۵۹
- in integration، ۶۱–۶۳
- in organization and culture، ۶۸–۷۰
- in product design، ۶۸
- speed of، ۷۷، ۹۳–۹۴، ۱۹۹
- Feynman, R.، ۷۸، ۸۴–۸۵، ۹۲، ۹۴
- formal methods، ۱۳
- Fosgren, N.، ۳۳، ۳۵
- Fowler, M.، ۳۲–۳۳
- functions, APIs، ۱۴۸–۱۴۹
- future-proofing، ۱۵۸–۱۵۹
G–H
- good example science، ۶
- Gorman, C.، ۳۱
- Hamilton, M.، ۷، ۱۵–۱۶، ۱۶۸
- hardware، ۸۵
- software، ۷
- Helms, H. J.، ۵۹
- Hibernate، ۳۱، ۳۲
- high-performance software. See also software
- Hopper, G.، ۱۹
- Humble, J.، ۳۳، ۹۶
- Continuous Delivery، ۱۱۶
I
- incrementalism، ۷۱، ۷۹
- iteration، ۷۱–۷۲
- limiting impact of change، ۷۶–۷۷
- modularity، ۷۲–۷۳
- organizational، ۷۳–۷۴
- Ports and Adapters pattern، ۷۶–۷۷
- tools of، ۷۴–۷۶
- information hiding، ۱۵۵، ۱۶۹–۱۷۰
- abstraction، ۱۵۱–۱۵۲
- iteration، ۴۳، ۴۵، ۵۱، ۵۲، ۵۳–۵۴، ۵۵، ۱۹۹. See also incrementalism
- as defensive strategy، ۴۶–۴۸
- incrementalism، ۷۱–۷۲
- learning، ۴۳
- ML، ۴۳
- practical advantages، ۴۵–۴۶، ۵۴
- TDD، ۵۴–۵۵
J–K–L
- Kim, G.، ۳۳
- Kuhn, T.، ۸
- lead time، ۳۴
- leaky abstractions، ۱۶۲–۱۶۳، ۱۶۷
- Lean، ۶۹
- learning، ۴، ۳۶–۳۷، ۱۵۵، ۱۸۹، ۲۱۴
- feedback، ۵۷
- iteration، ۴۳
- LOR (lunar orbit rendezvous)، ۷۲
- low code development، ۱۵۶
M
- maps، ۱۶۳–۱۶۴
- mass production، ۲۲
- math، ۱۷
- engineering، ۱۳–۱۴
- measurement، ۲۲–۲۳، ۳۹
- experimentation، ۹۵–۹۶
- points of، ۱۱۱
- stability، ۳۳–۳۴
- testing، ۱۱۱–۱۱۲، ۱۱۳–۱۱۴
- throughput، ۳۴
- mechanisms, outcomes، ۲۱۰–۲۱۱
- messaging، ۱۷۴
- abstraction، ۱۶۱
- microservices، ۶۶، ۶۷، ۱۱۷، ۱۱۹
- coupling، ۱۷۳–۱۷۴، ۱۸۳–۱۸۴
- deployability، ۱۷۴
- DRY، ۱۸۰
- modularity، ۷۳
- scalability، ۱۷۴
- ML (machine learning)، ۴۳، ۲۱۲–۲۱۴. See also learning
- models، ۱۲–۱۳، ۱۴، ۲۸، ۵۱–۵۲، ۸۵، ۱۶۷
- abstraction، ۱۶۳، ۱۶۴
- Cost of Change، ۴۶–۴۸، ۱۵۹
- stability and throughput، ۳۵
- modularity، ۷۲–۷۳، ۷۵، ۱۰۶، ۱۰۸، ۱۱۳، ۱۲۰، ۱۶۷. See also coupling; incrementalism
- Apollo space program، ۷۲–۷۳
- cohesion، ۱۲۱–۱۲۲
- complexity، ۷۳، ۱۰۵–۱۰۶، ۱۰۷–۱۰۸، ۱۱۸
- deployability، ۱۱۶–۱۱۷
- at different scales، ۱۱۸
- hallmarks of، ۱۰۶
- in human systems، ۱۱۸–۱۱۹
- microservices، ۷۳
- organizational incrementalism، ۷۳–۷۴
- services، ۱۱۵–۱۱۶
- testability، ۱۰۹–۱۱۲
- testing، ۱۱۳
- undervaluing importance of طراحی خوب، ۱۰۷–۱۰۸
- Moore's law، ۷
- Musk, E.، ۲۵
N
- NASA, Apollo space program، ۱۵–۱۶
- NATO، ۷
- natural selection، ۸
- North, D.، ۴۶، ۴۷، ۱۵۵
- Nygard model of coupling، ۱۷۶–۱۷۷
O–P
- organizational incrementalism، ۷۳–۷۴
- outcomes, mechanisms، ۲۱۰–۲۱۱
- paradigm shift، ۸
- parallel programming، ۸۵–۸۶، ۸۷
- Parnas, D.، ۲۳
- performance. See also quality; speed
- incrementalism، ۷۱
- measuring، ۳۲–۳۴
- stability، ۳۴–۳۵
- testability، ۱۲۸
- throughput، ۳۴–۳۵
- Perlis, A. J.، ۵۹–۶۰
- physics، ۹۸–۹۹
- pictograms، ۵۲
- plain text، ۱۶۱
- Ports and Adapters pattern، ۷۶–۷۷، ۱۱۵
- APIs، ۱۴۹
- separation of concerns، ۱۴۵–۱۴۷
- when to use، ۱۴۷–۱۴۸
- pragmatism, abstraction، ۱۵۷–۱۵۸
- precision، ۹۶
- measurement، ۲۲–۲۳
- scalability، ۲۰–۲۱
- in software engineering، ۲۰
- speed، ۳۴
- predictability، ۴۵
- predictive approach، ۵۸
- problem-solving, experimentation، ۹۱–۹۲
- production، ۱۱–۱۲، ۱۴
- complexity، ۲۱–۲۲، ۴۹–۵۰
- craft، ۱۹–۲۰
- repeatability، ۲۲–۲۳
- speed of، ۳۴
- production engineering، ۱۱، ۴۹
- productivity, measuring، ۳۳
- programming، ۱۸–۱۹، ۵۹، ۶۰، ۱۰۸. See also code
- abstraction(s)، ۱۵۹، ۱۷۰، ۱۷۷
- leaky، ۱۶۲–۱۶۳
- maps، ۱۶۳–۱۶۴
- models، ۱۶۳، ۱۶۴
- picking، ۱۶۳–۱۶۵
- power of، ۱۶۰–۱۶۲
- pragmatism، ۱۵۷–۱۵۸
- raising level of، ۱۵۶–۱۵۷
- storage، ۱۶۸
- asynchronous، ۱۸۰–۱۸۲
- complexity، ۲۲
- DDD، ۱۲۵–۱۲۶
- feedback، ۶۰–۶۱
- parallel، ۸۵–۸۶
- professional، ۱۸۲
- separation of concerns، ۱۲۷، ۱۳۱
- abstraction(s)، ۱۵۹، ۱۷۰، ۱۷۷
- programming languages، ۳۲، ۸۶، ۹۲، ۱۰۸، ۱۸۲. See also code
- domain-specific، ۱۶۵
Q
- quality، ۷۰، ۱۵۵، ۱۵۷
- coding، ۶۳–۶۴
- measuring، ۳۴–۳۵
- organizational and cultural problems، ۱۵۲–۱۵۴
- speed، ۳۴
R
- rationalism، ۲۵، ۲۶، ۹۸
- RDBMS، ۱۳۶
- refactoring tools، ۷۵
- releasability، ۱۹۸
- repeatability، ۲۲–۲۳
- Rhumb-lines، ۱۶۳
S
- scalability، ۲۵
- precision، ۲۰–۲۱
- science، ۹۲
- experimentation، ۹۱–۹۲
- physics، ۹۸–۹۹
- rationalism، ۹۸
- scientific method، ۳–۴، ۶، ۸۴
- hypotheses، ۹۴–۹۵
- Scrum، ۴۵، ۵۰
- self-deception, avoiding، ۸۴–۸۵
- Selig, F.، ۶۰
- separation of concerns، ۱۲۷، ۱۳۱، ۱۳۵–۱۳۶، ۱۳۷–۱۳۸، ۱۵۰. See also cohesion
- complexity، ۱۳۹–۱۴۲
- coupling، ۱۷۸–۱۷۹
- DDD، ۱۴۲–۱۴۴
- dependency injection، ۱۳۹
- Ports and Adapters pattern، ۱۴۵–۱۴۷
- swapping out database، ۱۳۶
- TDD، ۱۴۹–۱۵۰
- testability، ۱۳۸، ۱۴۴
- serverless computing، ۲۶–۲۷
- services، ۱۷۴. See also microservices
- modularity، ۱۱۵–۱۱۶
- soak test، ۲۳
- software، ۵
- cohesive، ۱۳۰–۱۳۲
- craftsmanship، ۲۴–۲۵
- crisis، ۷
- formal methods، ۱۳
- طراحی خوب، ۱۲۱
- half-life of، ۱۵۵
- hardware، ۷
- high-performance، ۱۲۸
- mass production، ۲۲
- precision، ۲۱
- software development، ۳، ۶، ۸، ۹، ۳۱، ۳۲، ۴۹–۵۰، ۵۱، ۱۲۷، ۱۸۸–۱۸۹، ۲۰۵–۲۰۶، ۲۱۵. See also cohesion; continuous delivery; experimentation; incrementalism; modularity; programming; separation of concerns
- abstraction، ۱۶۰–۱۶۲
- agile، ۴۴–۴۵، ۴۶، ۵۰، ۵۳، ۵۴، ۶۹، ۷۴، ۷۷
- bridge building، ۱۲
- cache-misses، ۸۵–۸۶
- CI، ۵۴
- complexity، ۷۰
- continuous delivery، ۳۳، ۴۸، ۹۶
- coordinated approach، ۱۸۳
- coupling، ۱۱۹
- creativity، ۷۴
- diagram-driven، ۱۵۶–۱۵۷، ۱۶۵
- distributed approach، ۱۸۳–۱۸۴
- empiricism، ۸۲–۸۴
- engineering، ۱۳، ۱۷
- experimentation، ۹۱–۹۲
- feedback، ۵۹، ۶۰–۶۴، ۶۵–۶۷، ۶۸–۷۰، ۱۸۹
- incremental design، ۷۷–۷۹
- iteration، ۴۳، ۴۵–۴۸، ۵۱، ۵۲، ۵۳–۵۵
- learning، ۳۷
- managing complexity، ۳۷–۳۸، ۷۸–۷۹
- measuring performance، ۳۲–۳۴
- modularity، ۱۰۶
- organizational and cultural problems، ۱۵۲–۱۵۴
- outcomes vs. mechanisms، ۲۱۰–۲۱۱
- predictive approach، ۵۸
- progress، ۵۱
- scaling up، ۱۷۲–۱۷۳
- services، ۱۱۵
- solutions، ۵۱–۵۲
- stability، ۳۴–۳۵
- TDD، ۵۴–۵۵، ۶۳–۶۴، ۶۵
- testability، ۱۰۸–۱۱۲
- testing، ۶۴–۶۵، ۶۶–۶۷، ۷۵، ۱۸۸، ۱۸۹
- throughput، ۳۴–۳۵
- undervaluing importance of طراحی خوب، ۱۰۷–۱۰۸
- waterfall approach، ۳۷، ۴۴، ۴۶، ۴۸–۴۹، ۵۱–۵۲، ۱۰۹
- software engineering، ۴، ۵، ۶، ۲۸–۳۰، ۱۰۱، ۱۸۰، ۲۰۶
- academic approach، ۱۵
- Apollo space program، ۱۵–۱۶
- birth of، ۷–۸
- bridge building، ۱۱
- complexity، ۴–۵
- creativity، ۲۴–۲۵
- definition، ۴
- foundational ideas، ۳۶
- iteration، ۴۵–۴۸
- learning، ۳۶–۳۷
- models، ۱۴
- NATO conference، ۵۹–۶۰
- precision، ۲۰
- production، ۱۱–۱۲
- programming languages، ۱۸–۱۹
- repeatability، ۲۲–۲۳
- rethinking، ۲۸–۳۰
- serverless computing، ۲۶–۲۷
- tools، ۱۸۷
- trade-offs، ۲۶
- waterfall approach، ۱۲
- SpaceX، ۱۴، ۱۷، ۲۵، ۲۶
- speed، ۹۳–۹۴
- feedback، ۷۷، ۹۳–۹۴، ۱۹۹
- quality، ۳۴
- Spolsky, J.، ۱۶۲
- spontaneous generation، ۸
- SQL، ۳۱
- stability، ۳۴–۳۵، ۷۰
- measuring، ۳۳–۳۴
- «State of DevOps» report، ۱۵۳، ۱۸۴
- storage، ۱۶۸
- stored programs، ۷
- SUT (system under test)، ۱۱۱
- synchronous communication، ۱۸۰–۱۸۱
T
- TDD (test-driven development)، ۵۴–۵۵، ۶۳–۶۴، ۶۵، ۶۷، ۹۷–۹۸، ۱۰۰، ۱۰۷، ۱۰۸، ۱۱۴، ۱۱۸، ۱۴۳، ۱۶۴، ۱۹۶. See also software development
- cohesion، ۱۲۹
- separation of concerns، ۱۴۹–۱۵۰
- telemetry، ۶۸
- Tesla، ۲۰۸، ۲۱۱
- testability، ۱۰۸–۱۰۹، ۱۱۴، ۱۲۷، ۱۶۴، ۱۸۹–۱۹۲
- improving، ۱۹۶–۱۹۷
- measurement points، ۱۹۲–۱۹۳
- modularity، ۱۰۹–۱۱۲
- performance، ۱۲۸
- problems achieving، ۱۹۳–۱۹۶
- separation of concerns، ۱۴۴
- testing، ۶۴–۶۵، ۶۶–۶۷، ۷۵، ۹۳، ۱۱۸، ۱۸۴، ۱۸۸، ۱۸۹، ۱۹۵. See also feedback
- abstraction، ۱۵۹–۱۶۰
- automated، ۹۷–۹۸، ۱۱۲، ۱۹۹، ۲۱۱
- coupled systems، ۱۱۱
- feedback، ۶۷
- hypotheses، ۹۴–۹۵، ۹۷
- measurement، ۱۱۱–۱۱۲، ۱۱۳–۱۱۴
- modules، ۱۱۳
- results of، ۹۸–۱۰۰
- third-party code، ۱۶۹
- throughput، ۷۰، ۹۵–۹۶
- measuring، ۳۴
- tools of incrementalism، ۷۴–۷۶
U–V
- undervaluing importance of طراحی خوب، ۱۰۷–۱۰۸
- value، ۴۶، ۵۱. See also quality
- Vanderburg, G., «Real Software Engineering»، ۱۵
- version control، ۹۶
W–X–Y–Z
- waterfall approach، ۳۷، ۴۴، ۴۶، ۴۸–۴۹، ۵۱–۵۲، ۱۰۹
- agile development، ۵۳
- Cost of Change model، ۴۶–۴۸
- feedback، ۵۸
- waterfall development approach، ۳۷
- Watson, T. J.، ۵۱