معرفی
اکنون که پاسخ سؤال خود را داریم " چرا کدهای جفت شده آزاد؟ "، بیایید سعی کنیم مشکلاتی را که در یک برنامه کاربردی جفت شده یافتیم حل کنیم . در این پست، از تزریق وابستگی مبتنی بر سازنده استفاده خواهیم کرد، اما فعلاً از هیچ ظرف DI استفاده نمی کنیم.
تزریق وابستگی (DI) تکنیکی است که به ما کمک میکند تا به جفت آزاد بین اشیا و همکاران آنها دست یابیم. به طور کلی، ما به این همکاران به عنوان وابستگی برای یک شی اشاره می کنیم. برای دستیابی به اتصال شل، باید از قانون طلایی " جدید نکردن " وابستگی های خود در کلاس پیروی کنیم، یا از داشتن ارجاعات ثابت بیش از حد در کد خودداری کنیم.
با در نظر گرفتن این موضوع، کلاس ها وابستگی های خود را از طریق سازنده خود به دنبال الگوی وابستگی صریح اعلام می کنند. این رویکرد به " تزریق سازنده " معروف است.
برای نشان دادن مفهوم، از یک برنامه بسیار ساده با مولفه زیر استفاده خواهیم کرد.
در برنامه ما، کلاس Commerce یک سفارش از مشتری دارد. برای پردازش Order به سه همکار نیاز دارد، یعنی به سه کلاس دیگر وابستگی دارد.
همانطور که در کد بالا مشاهده می شود، کلاس Commerce تمام وابستگی های خود را از طریق سازنده خود آشکار می کند. در نتیجه، در زمان نمونه سازی شی، کلاس User از تمام الزامات کلاس Commerce آگاه خواهد بود. علاوه بر این، این به عنوان Constructor Injection شناخته می شود، زیرا کلاس User تمام وابستگی ها را از طریق یک سازنده ارائه می دهد.
در این مثال، اگر به برنامه خود نگاه کنیم، همه چیز خوب به نظر می رسد. چرا؟ زیرا ما اجزای خود را به خوبی از یکدیگر جدا کرده ایم. همچنین تمامی کلاس های ما از اصل مسئولیت واحد پیروی می کنند. هیچ یک از همکاران با کلاس Commerce پیوند محکمی ندارند، بلکه همه آنها از طریق سازنده آن تزریق می شوند.
اکنون که پاسخ سؤال خود را داریم " چرا کدهای جفت شده آزاد؟ "، بیایید سعی کنیم مشکلاتی را که در یک برنامه کاربردی جفت شده یافتیم حل کنیم . در این پست، از تزریق وابستگی مبتنی بر سازنده استفاده خواهیم کرد، اما فعلاً از هیچ ظرف DI استفاده نمی کنیم.
تزریق وابستگی
تزریق وابستگی (DI) تکنیکی است که به ما کمک میکند تا به جفت آزاد بین اشیا و همکاران آنها دست یابیم. به طور کلی، ما به این همکاران به عنوان وابستگی برای یک شی اشاره می کنیم. برای دستیابی به اتصال شل، باید از قانون طلایی " جدید نکردن " وابستگی های خود در کلاس پیروی کنیم، یا از داشتن ارجاعات ثابت بیش از حد در کد خودداری کنیم.
با در نظر گرفتن این موضوع، کلاس ها وابستگی های خود را از طریق سازنده خود به دنبال الگوی وابستگی صریح اعلام می کنند. این رویکرد به " تزریق سازنده " معروف است.
مثال
برای نشان دادن مفهوم، از یک برنامه بسیار ساده با مولفه زیر استفاده خواهیم کرد.
- سفارش - نشان دهنده سفارشی است که توسط کاربر ارسال شده است
- تجارت - یک سفارش را می پذیرد و از سایر اجزا برای پردازش آن استفاده می کند
- PaymentProcessor - پرداخت کاربر را پردازش می کند
- CurrencyConverter - مبلغ پرداختی را به ارز محلی تبدیل می کند
- NotificationManager - کاربر را از تایید سفارش مطلع می کند
- Logger - خطاها را ثبت می کند (مانند شکست تراکنش)
- public class Program
- {
- Order customerOrder = new Order { Id = 1, ProductName = "Product", Quantity = 3, UnitPrice = 75 };
- Commerce commerce = new Commerce(new CreditCardProcessor(new CurrencyConverter()),
- new EmailNotifier(), new TextLogger());
- commerce.ProcessOrder(customerOrder);
- }
- public class Commerce
- {
- private PaymentProcessor _paymentProcessor;
- private NotificationManager _notificationManager;
- private Logger _logger;
- public Commerce(PaymentProcessor paymentProcessor, NotificationManager notificationManager, Logger logger)
- {
- _paymentProcessor = paymentProcessor;
- _notificationManager = notificationManager;
- _logger = logger;
- }
- public void ProcessOrder(Order order)
- {
- decimal paidAmount = order.UnitPrice * order.Quantity;
- bool paymentSuccessful = _paymentProcessor.ProcessPayment(paidAmount);
- if(paymentSuccessful)
- {
- _notificationManager.NotifyCustomer(notification: "payment successful");
- }
- else
- {
- _notificationManager.NotifyCustomer(notification: "payment failed");
- _logger.Log(errorMessage: "payment failed");
- }
- }
- }
در برنامه ما، کلاس Commerce یک سفارش از مشتری دارد. برای پردازش Order به سه همکار نیاز دارد، یعنی به سه کلاس دیگر وابستگی دارد.
همانطور که در کد بالا مشاهده می شود، کلاس Commerce تمام وابستگی های خود را از طریق سازنده خود آشکار می کند. در نتیجه، در زمان نمونه سازی شی، کلاس User از تمام الزامات کلاس Commerce آگاه خواهد بود. علاوه بر این، این به عنوان Constructor Injection شناخته می شود، زیرا کلاس User تمام وابستگی ها را از طریق یک سازنده ارائه می دهد.
مشکل
در این مثال، اگر به برنامه خود نگاه کنیم، همه چیز خوب به نظر می رسد. چرا؟ زیرا ما اجزای خود را به خوبی از یکدیگر جدا کرده ایم. همچنین تمامی کلاس های ما از اصل مسئولیت واحد پیروی می کنند. هیچ یک از همکاران با کلاس Commerce پیوند محکمی ندارند، بلکه همه آنها از طریق سازنده آن تزریق می شوند.