Learn SOLID Principles in Arabic
ููุชููู
ุนู ุงูู SOLID principles ูููุดูู ุฅุฒุงู ุงูู
ุจุงุฏุฆ ุฏู ุจุชุณุงุนุฏูุง ูุญุณู ุฌูุฏุฉ ุงูู software application ุงููู ุจูุจููู. ุงูู SOLID principles ุจุชููุฑููุง ุดููุฉ ููุงุนุฏ ุจุชุฎูู ุงูู software ุจุชุงุนูุง:
- ุงูู
robust: ูุนูู ููู ูู ุชูู. - ุงูู
maintainable: ูุนูู ุณูู ูุนุฏู ููู ููุตูุญู. - ุงูู
reusable: ูุนูู ููุฏุฑ ูุณุชุฎุฏู ุฃุฌุฒุงุก ู ูู ุชุงูู ูู ู ุดุงุฑูุน ุชุงููุฉ.
ุงูู SOLID Principles ุฏู ุนุจุงุฑุฉ ุนู ุฎู
ุณ ู
ุจุงุฏุฆ ุฃุณุงุณูุฉุ ููู ุญุฑู ูู ููู
ุฉ SOLID ุจูุฑู
ุฒ ูู
ุจุฏุฃ ู
ููู
. ููุง ุจููุง ูุดูู ุงูู
ุจุงุฏุฆ ุฏู ูุงุญุฏุฉ ูุงุญุฏุฉ ูุจุฃู
ุซูุฉ ุนู
ููุฉ.
1. Single Responsibility Principle - SRP
ุญุฑู S ูู SOLID ุจูุฑู
ุฒ ููู Single Responsibility Principle ุฃู ู
ุจุฏุฃ ุงูู
ุณุคูููุฉ ุงููุงุญุฏุฉ.
ูุนูู ุฅูู Single Responsibilityุ
ุจุจุณุงุทุฉุ ุงูู principle ุฏู ุจูููู ุฅู:
โุงูู class ุงูู
ูุฑูุถ ูููู ูููุง ุณุจุจ ูุงุญุฏ ุจุณ ููุชุบููุฑ.โ
ูุนูู ุฅูู ุงูููุงู
ุฏูุ ูุนูู ู
ูููุนุด ูููู ุนูุฏู Class ูุงุญุฏุฉ ุจุชุนู
ู ุฃูุชุฑ ู
ู ุญุงุฌุฉ ูู ููุณ ุงูููุช. ู
ุด ู
ุญุชุงุฌูู multi-tasking ููุง. ูู ุงูู class ุจุชุนู
ู ุฃูุชุฑ ู
ู ุญุงุฌุฉุ ููุฌููู ููุช ูู ุญุงุฌุฉ ู
ููู
ุจุงุธุช ุฃู ุญุจูุช ุชุนุฏููุงุ ูุชุถุทุฑ ุชุนุฏู ูู ุงูู class ูููุงุ ูุฏู ู
ู
ูู ูุจูุธ ุญุงุฌุงุช ุชุงููุฉ ู
ุนุชู
ุฏุฉ ุนูููุง ุฌูู ููุณ ุงูู class ูู ููู complex logic ุจูุฑุจุทูู
.
- ุงูุฎูุงุตุฉ: ูุงุฒู
ููุตู ุงูู
ุณุคูููุงุช. ูู
classุชููู ู ุณุคููุฉ ุนู ุญุงุฌุฉ ูุงุญุฏุฉ ุจุณุ ูุจุงูุชุงูู ูููู ูููุง ุณุจุจ ูุงุญุฏ ุจุณ ูุฎูููุง ูุบูุฑ ูููุง. โูุง ููู ุงูุชู ุชุงุณูููุฌ ูู ุงูุฃูุจุฌูุช ุฃูุฑููุชุฏ ุณููุช ููุฑโ. - ููุณ ุงูู
ูููู
ููู
functions: ูู ุนูุฏู Function ุจุชุนู ู ุฃูุชุฑ ู ู ุญุงุฌุฉุ ุญุงูู ุชูุณู ูุง ููfunctionsุฃุตุบุฑุ ูู ูุงุญุฏุฉ ุจุชุนู ู ู ูู ุฉ ู ุญุฏุฏุฉ. ู ุงูููุนุด ู ุซูุงูfunctionุชุถููuserููู ููุณ ุงูููุช ุชุจุนุชููnotificationุฃูemail. ูุฃุ ูุตู ุฅุฑุณุงู ุงููemailููfunctionููุญุฏูุงุ ูุฎูู ุงููfunctionุจุชุงุนุฉ ุฅุถุงูุฉ ุงููuserู ุฎุตุตุฉ ูุฅุถุงูุฉ ุงููusersูุจุณ.
ู
ุซุงู: ุฎุฏู
ุฉ ุงูุฅูู
ููุงุช (EmailingService)
ุชุฎูู ุนูุฏูุง EmailingService ุจุชุนู
ู ุงูุขุชู:
- ุงูู
SendEmail(): ุจุชุจุนุช ุฅูู ูู (ู ู ูู ูููู ูููุง ุงููlogicุจุชุงุน ุงููSMTP server). - ุงูู
LoadEmailTemplate(): ุจุชุญู ู ุดูู ุงูุฅูู ูู (ุงููtemplate). - ุงูู
UpdateEmailTemplate(): ุจุชุนุฏู ูู ุงููtemplate.
ุงูููุฏ ูุจู ุชุทุจูู SRP (ู ุซุงู ุณูุก):
// Assume this class does too much
public class EmailingServiceBeforeSRP
{
public void SendEmail(string recipient, string subject, string body)
{
// Logic to configure SMTP and send email
Console.WriteLine($"C#: Email sent to {recipient} with subject: {subject}.");
}
public string LoadEmailTemplate(string templateName)
{
// Logic to load template from file or DB
Console.WriteLine($"C#: Loading template: {templateName}.");
return $"Template content for {templateName}";
}
public void UpdateEmailTemplate(string templateName, string newContent)
{
// Logic to update template
Console.WriteLine($"C#: Updating template: {templateName}.");
}
}ุงูู
ุดููุฉ ููุง ุฅููุ
ุงูู EmailingServiceBeforeSRP ุฏู ุจุชุนู
ู ุฃูุชุฑ ู
ู ุญุงุฌุฉ:
- ูู ุนุงูุฒ ุฃุบูุฑ ูู ุทุฑููุฉ ุฅุฑุณุงู ุงูุฅูู
ููุงุช (ุงูู
SMTP configuration)ุ ูุนุฏู ูู ุงููclassุฏู. - ูู ุนุงูุฒ ุฃุบูุฑ ูู ุดูู ุงูุฅูู
ูู (ุงูู
templateุ ุณูุงุก ูุงูplain textุฃูHTML rendered templateุฒู ุงููnewsletter)ุ ุจุฑุถู ูุนุฏู ูู ููุณ ุงููclass.
ูุฏู ู
ุจูุงุด ููู โุณุจุจ ูุงุญุฏ ููุชุบููุฑโุ ุจูู ููู ุฃูุชุฑ ู
ู ุณุจุจ. ุฏู ุจูุณู
ูู violation ููู
ุจุฏุฃ.
ุงูุญู ุฅููุ ููุตู ูู ุญุงุฌุฉ ููุญุฏูุง:
- ุงูู
EmailSender: ููclassู ุณุคููุฉ ุจุณ ุนู ุฅุฑุณุงู ุงูุฅูู ููุงุช (ูููุง ุงููSMTP logic).
// Responsible only for sending emails
public class EmailSender
{
public void SendEmail(string recipient, string subject, string body)
{
// SMTP logic to send email
Console.WriteLine($"C#: EmailSender - Email sent to {recipient} with subject: {subject}.");
}
}- ุงูู
EmailTemplateManager: ููclassู ุณุคููุฉ ุนู ุชุญู ูู ูุชุนุฏูู ุงููtemplates.
// Responsible only for template management
public class EmailTemplateManager
{
public string LoadEmailTemplate(string templateName)
{
// Logic to load template
Console.WriteLine($"C#: EmailTemplateManager - Loading template: {templateName}.");
return $"Template content for {templateName}";
}
public void UpdateEmailTemplate(string templateName, string newContent)
{
// Logic to update template
Console.WriteLine($"C#: EmailTemplateManager - Updating template: {templateName}.");
}
}ุงููุงูุฏุฉ ู ู ูุฏู ุฅููุ
- ุงูู
classesุจูุช ุฃุตุบุฑ ูุฃุณูู ูู ุงูููู ูุงููุฑุงุกุฉ (more readable). - ุจูุช ุฃุณูู ูู ุฅุนุงุฏุฉ ุงูุงุณุชุฎุฏุงู
(
reusability). ูุนูู ู ู ูู ุฃุณุชุฎุฏูEmailSenderููุญุฏู ู ู ุบูุฑ ู ุง ุฃููู ู ุฑุจูุท ุจุงููtemplate management.
ู
ุซุงู ุนู
ูู: OrderManager
ูุชูุถูุญ ุงูููุฑุฉุ ูููุชุฑุถ ูุฌูุฏ ุงูููุงุณุงุช ุงูุจุณูุทุฉ ุฏู:
public class Order // Helper class for the example
{
public int OrderId { get; set; }
public decimal TotalAmount { get; set; }
// Other order properties...
}
public class PaymentDetails // Helper class for the example
{
public string PaymentMethod { get; set; } // e.g., "Visa", "Mastercard"
// Other payment details...
}ุชุฎูู ุนูุฏูุง class ุงุณู
ูุง OrderManagerBeforeSRP ุจุชุนู
ู ุงูุขุชู:
- ุงูู
ProcessOrder(Order order): ุจุชุนุงูุฌ ุงูุทูุจ. - ุงูู
ProcessPayment(Order order, PaymentDetails details): ุจุชุนุงูุฌ ุนู ููุฉ ุงูุฏูุน. - ุงูู
SendEmailNotification(Order order, String message): ุจุชุจุนุช ุฅูู ูู ุชุฃููุฏ.
ุงูููุฏ ูุจู ุชุทุจูู ุงูู SRP (ู ุซุงู ุณูุก):
public class OrderManagerBeforeSRP
{
public void ProcessOrder(Order order)
{
Console.WriteLine($"C#: OrderManagerBeforeSRP - Processing order: {order.OrderId}.");
// Complex order processing logic
}
public void ProcessPayment(Order order, PaymentDetails details)
{
Console.WriteLine($"C#: OrderManagerBeforeSRP - Processing payment for order {order.OrderId} via {details.PaymentMethod}.");
// Payment gateway integration, validation, etc.
}
public void SendEmailNotification(Order order, string message)
{
Console.WriteLine($"C#: OrderManagerBeforeSRP - Sending email for order {order.OrderId}: {message}.");
// Email sending logic
}
}ุงูู
ุดููุฉ: ุงูู OrderManagerBeforeSRP ุฏู ุจูุนู
ู ุชูุงุช ุญุงุฌุงุช ู
ุฎุชููุฉุ ูุฏู violation ููู SRP. ูู ุญุตู ุชุบููุฑ ูู ูุธุงู
ุงูู notificationsุ ุฃู ูู ุทุฑููุฉ ุงูุฏูุนุ ุฃู ูู ุทุฑููุฉ ู
ุนุงูุฌุฉ ุงูุทูุจุงุชุ ูู ู
ุฑุฉ ูููุฌู ูุนุฏู ูู ููุณ ุงูู class.
ุงูุญู (ุชุทุจูู ุงูู SRP):
- ุงูู
OrderProcessingService: ู ุณุคููุฉ ุนู ู ุนุงูุฌุฉ ุงูุทูุจุงุช ููุท.
// Handles only order processing logic
public class OrderProcessingService
{
public void ProcessOrder(Order order)
{
Console.WriteLine($"C#: OrderProcessingService - Processing order: {order.OrderId}.");
// Complex order processing logic
}
}- ุงูู
PaymentProcessingService: ู ุณุคููุฉ ุนู ู ุนุงูุฌุฉ ุงูุฏูุน ููุท.
// Handles only payment processing
public class PaymentProcessingService // Renamed from PaymentService for clarity
{
public void ProcessPayment(Order order, PaymentDetails details)
{
Console.WriteLine($"C#: PaymentProcessingService - Processing payment for order {order.OrderId} via {details.PaymentMethod}.");
// Payment gateway integration, validation, etc.
}
}- ุงูู
NotificationSendingService: ู ุณุคููุฉ ุนู ุฅุฑุณุงู ุงูุฅุดุนุงุฑุงุช ููุท.
// Handles only notifications
public class NotificationSendingService // Renamed from NotificationService for clarity
{
public void SendEmailNotification(Order order, string message)
{
Console.WriteLine($"C#: NotificationSendingService - Sending email for order {order.OrderId}: {message}.");
// Email sending logic
}
}ุจูุฏูุ ูู class ุจูุช ู
ุณุคููุฉ ุนู ุญุงุฌุฉ ูุงุญุฏุฉ ุจุณุ ููููู ูููุง ุณุจุจ ูุงุญุฏ ููุชุบููุฑ:
- ุงูู
NotificationSendingService: ุฃู ุชุบููุฑ ูู ูุธุงู ุงูุฅุดุนุงุฑุงุช ููุชู ููุง. ููุฏุฑ ูุณุชุฎุฏู ูุง ูู ุฃู ุญุชุฉ ูู ุงููapplication. - ุงูู
PaymentProcessingService: ุฃู ุชุนุฏูู ูู ุทุฑู ุงูุฏูุน ููุชู ููุง. - ุงูู
OrderProcessingService: ุฃู ุชุนุฏูู ูู ุทุฑููุฉ ู ุนุงูุฌุฉ ุงูุทูุจุงุช ููุชู ููุง.
ูุฏู ูู ุงูู Single Responsibility Principle.
2. Open-Closed Principle - OCP
ุญุฑู O ูู SOLID ุจูุฑู
ุฒ ููู Open/Closed Principle.
ูุนูู ุฅูู Open/Closedุ
ุงูู
ุจุฏุฃ ุฏู ุจูููู ุฅู:
โุงูู software entities (ุฒู ุงูู classes, modules, functions) ุงูู
ูุฑูุถ ุชููู ู
ูุชูุญุฉ ููุชูุณูุน (open for extension)ุ ููู ู
ููููุฉ ุนู ุงูุชุนุฏูู (closed for modification).โ
ูุนูู ุฅูู ุงูููุงู
ุฏูุ ูุนูู ูู ุนูุฏู Function ุฃู Class ุจุชุนู
ู ุญุงุฌุฉ ู
ุนููุฉุ ูุนุงูุฒ ุชุฒูุฏ ุนูููุง functionality ุฌุฏูุฏุฉุ ุงูู
ูุฑูุถ ุชูุฏุฑ ุชุนู
ู ุฏู ู
ู ุบูุฑ ู
ุง ุชุนุฏู ุณุทุฑ ููุฏ ูุงุญุฏ ูู ุงูู source code ุงูุฃุตูู ุจุชุงุนูุง. ุฏู ู
ูู
ุฌุฏุงู ูู ุจุชุชุนุงู
ู ู
ุน legacy code ุฎุงูู ุชุนุฏู ููู ููุจูุธ ุญุงุฌุฉ ุดุบุงูุฉ ูู ุงูู production. ุงูุฃูุชูุชู ุจุชุงุนุช ุงูุณููุชููุฑ ุชููู ุจุชุณู
ุญูู ุชุทูุฑ ูุชุฒูุฏ ูููุง ู
ู ุบูุฑ ู
ุง ุชุบูุฑ ุญุงุฌุฉ ู
ูุฌูุฏุฉ ูู ุงูู source code.
ู
ุซุงู: ุญุงุณุจุฉ ุงูุฎุตูู
ุงุช (DiscountCalculator)
ูุชูุถูุญ ุงูููุฑุฉุ ูููุชุฑุถ ูุฌูุฏ ุงูููุงุณ ุฏู:
public class Product // Helper class
{
public string Type { get; set; } // e.g., "electronics", "clothing", "books"
public decimal Price { get; set; }
}ุชุฎูู ุนูุฏูุง DiscountCalculator ูู e-commerce application:
ุงูููุฏ ูุจู ุชุทุจูู OCP (ู ุซุงู ุณูุก):
public class DiscountCalculatorBeforeOCP
{
public decimal CalculateDiscount(Product product)
{
decimal discount = 0;
// This is often done with a switch statement as well, which is also a violation
if (product.Type == "electronics")
{
discount = product.Price * 0.10m; // 10% for electronics
}
else if (product.Type == "clothing")
{
discount = product.Price * 0.20m; // 20% for clothing
}
else if (product.Type == "books")
{
discount = product.Price * 0.15m; // 15% for books
}
// If we add a new Product type (e.g., "homeappliances"), we MUST modify this class
return discount;
}
}ุงูู class ุฏู ุจุณูุทุฉ ูุจุชุญูู ุงูู SRP (ู
ุณุคูููุชูุง ุญุณุงุจ ุงูุฎุตู
ุจุณ).
ุงูู
ุดููุฉ: ุงูู class ุฏู ุจุชุฎุงูู ุงูู OCP. ูููุ
ูุฃู ูู ุญุจููุง ูุถูู ููุน ู
ูุชุฌ ุฌุฏูุฏ ุจุฎูุตู
ุฌุฏูุฏ (ู
ุซูุงูุ ุฃุฏูุงุช ู
ูุฒููุฉ)ุ ููุถุทุฑ ูุนุฏู ูู ุงูู CalculateDiscount ููุฒูุฏ if-else ุฌุฏูุฏุฉ (ุฃู case ุฌุฏูุฏุฉ ูู ุงููswitch). ูุฏู ุฅุญูุง โุนุฏููุงโ ูู ุงูููุฏ ุงูุฃุตูู.
ุงูุญู (ุชุทุจูู ุงูู OCP ุจุงุณุชุฎุฏุงู Strategy Pattern):
- ูุนู
ู interface ููู
discount strategy:
public interface IDiscountStrategy
{
decimal CalculateDiscount(Product product);
}- ูุนู ู Concrete Class ููู ููุน ุฎุตู :
public class ElectronicsDiscountStrategy : IDiscountStrategy
{
public decimal CalculateDiscount(Product product)
{
return product.Price * 0.10m; // 10%
}
}
public class ClothingDiscountStrategy : IDiscountStrategy
{
public decimal CalculateDiscount(Product product)
{
return product.Price * 0.20m; // 20%
}
}
public class BooksDiscountStrategy : IDiscountStrategy
{
public decimal CalculateDiscount(Product product)
{
return product.Price * 0.15m; // 15%
}
}
// To extend (open for extension): add a new strategy class for a new product type
public class HomeAppliancesDiscountStrategy : IDiscountStrategy
{
public decimal CalculateDiscount(Product product)
{
return product.Price * 0.05m; // 5% for home appliances
}
}- ูุนุฏู ุงูู
DiscountCalculatorุนุดุงู ูุณุชุฎุฏู ุงููstrategy:
public class DiscountCalculatorAfterOCP
{
// Closed for modification: This class doesn't change when new discount types are added.
private readonly IDiscountStrategy _discountStrategy;
public DiscountCalculatorAfterOCP(IDiscountStrategy discountStrategy)
{
_discountStrategy = discountStrategy; // Dependency is Injected
}
public decimal CalculateDiscount(Product product)
{
// Delegates calculation to the injected strategy
return _discountStrategy.CalculateDiscount(product);
}
}ุงููุงูุฏุฉ ู ู ูุฏู ุฅููุ ูู ุนุงูุฒูู ูุถูู ููุน ุฎุตู ุฌุฏูุฏ (ู ุซูุงู ููุฃุฏูุงุช ุงูู ูุฒููุฉ):
- ููุนู
ู
classุฌุฏูุฏุฉHomeAppliancesDiscountStrategy : IDiscountStrategy. - ูู
ุง ููุฌู ูุณุชุฎุฏู
DiscountCalculatorAfterOCPุ ููุณููู ููู ุงููinstanceู ู ุงููstrategyุงูุฌุฏูุฏุฉ ุฏู ูู ุงููconstructor:new DiscountCalculatorAfterOCP(new HomeAppliancesDiscountStrategy()).
ุฅุญูุง ูุฏู โูุณุนูุงโ ุงูู system ุจูุธููุฉ ุฌุฏูุฏุฉ ู
ู ุบูุฑ ู
ุง โูุนุฏูโ ุฃู ุญุงุฌุฉ ูู DiscountCalculatorAfterOCP ุงูุฃุตูู ุฃู ุงูู strategies ุงููุฏูู
ุฉ. ุงูู DiscountCalculatorAfterOCP ุจูู closed for modification ู open for extension.
ุงููู ุนู
ููุงู ุฏู ู
ุซุงู ุนูู ุงุณุชุฎุฏุงู
Strategy Design Pattern.
ู
ุซุงู ุนู
ูู: PaymentProcessor
ูุงูู ุซุงู ุงููู ููู ูู ุฌููุง ูุดูู ูููุงููู ุจูุญูู ุงูู SRP ุจุณ ู ุด ุจูุญูู ุงูู OCP
// Interface for payment strategies
public interface IPaymentStrategy
{
void ProcessPayment(decimal amount);
}
// Concrete payment strategies
public class VisaPaymentStrategy : IPaymentStrategy
{
public void ProcessPayment(decimal amount)
{
Console.WriteLine($"Processing Visa payment of {amount:C}.");
}
}
public class MasterCardPaymentStrategy : IPaymentStrategy
{
public void ProcessPayment(decimal amount)
{
Console.WriteLine($"Processing MasterCard payment of {amount:C}.");
}
}
public class AmericanExpressPaymentStrategy : IPaymentStrategy
{
public void ProcessPayment(decimal amount)
{
Console.WriteLine($"Processing American Express payment of {amount:C}.");
}
}
// New payment strategy (extending functionality)
public class PayPalPaymentStrategy : IPaymentStrategy
{
public void ProcessPayment(decimal amount)
{
Console.WriteLine($"Processing PayPal payment of {amount:C}.");
}
}
// Payment Processor class - closed for modification
public class PaymentProcessor
{
private readonly IPaymentStrategy _paymentStrategy;
// Dependency injection through constructor
public PaymentProcessor(IPaymentStrategy paymentStrategy)
{
_paymentStrategy = paymentStrategy;
}
public void ExecutePayment(Order order) // Assuming Order has a TotalAmount
{
// No if/else or switch for payment type here!
_paymentStrategy.ProcessPayment(order.TotalAmount);
}
}
// Example usage in a Main function or client code
public class OCPClientCode
{
public static void ProcessOrderPayment()
{
Order myOrder = new Order { OrderId = 101, TotalAmount = 150.75m };
// Process with Visa
IPaymentStrategy visaStrategy = new VisaPaymentStrategy();
PaymentProcessor visaProcessor = new PaymentProcessor(visaStrategy);
visaProcessor.ExecutePayment(myOrder);
// Process with PayPal (newly added without modifying PaymentProcessor)
IPaymentStrategy paypalStrategy = new PayPalPaymentStrategy();
PaymentProcessor paypalProcessor = new PaymentProcessor(paypalStrategy);
paypalProcessor.ExecutePayment(myOrder);
}
}ูู ุนุงูุฒูู ูุถูู ุทุฑููุฉ ุฏูุน ุฌุฏูุฏุฉ ุฒู PayPalุ ูู ุงููู ููุนู
ูู ุฅููุง ููุดุฆ class ุฌุฏูุฏุฉ ุฒู PayPalPaymentStrategy ุจุชุนู
ู implement ููู IPaymentStrategy. ุงูู PaymentProcessor ููุณู ู
ุด ููุชุนุฏู.
3. Liskov Substitution Principle - LSP
ุญุฑู L ูู SOLID ุจูุฑู
ุฒ ููู Liskov Substitution Principle.
ูุนูู ุฅูู Liskov Substitutionุ
ุงูู
ุจุฏุฃ ุฏู ุจููุต ุนูู ุฅู:
โูู ุงูู class S ูู subclass ู
ู ุงูู class Tุ ูุจูู ุงูู
ูุฑูุถ ููุฏุฑ ูุณุชุฎุฏู
objects ู
ู ุงูููุน S ู
ูุงู objects ู
ู ุงูููุน T ู
ู ุบูุฑ ู
ุง ูุจูุธ ุฃู ุญุงุฌุฉ ูู ุงูุจุฑูุงู
ุฌ ุฃู ูุบูุฑ ุณูููู ุงูู
ุชููุน.โ
ุจู
ุนูู ุฃุตุญุ ุงูู subclass ูุงุฒู
ุชุญุงูุธ ุนูู โุนูุฏโ ุงูู superclass ุจุชุงุนูุง. ู
ุงูููุนุด ุงูู child class ูุนู
ู ุญุงุฌุฉ ุชุฎุงูู ุงููู ุงูู parent class ุจููุนุฏ ุจููุง. ูู ููู
ุช method ุจูุนู
ููุง ุงูุฃุจุ ุงูู
ูุฑูุถ ุชุชููุฐ ุจุงูุณููู ุงููู ุฃูุง ุดุงููู ูู ุงูุฃุจ.
ู
ุซุงู: ุงูู
ูุธููู ูุญุณุงุจ ุงูู
ุฑุชุจุงุช (Employee & Salary Calculation)
ุชุฎูู ุนูุฏูุง class ุงุณู
ูุง Employee:
public class Employee
{
public string Name { get; set; }
public int HoursWorked { get; set; }
// Base salary calculation logic
public virtual decimal CalculateSalary() // Made virtual to allow override
{
// Default calculation, e.g., for a generic employee or contractor
return HoursWorked * 10.0m; // Example: 10 units per hour
}
}ูุนูุฏูุง ุฃููุงุน ู ุฎุชููุฉ ู ู ุงูู ูุธููู:
FullTimeEmployee:
public class FullTimeEmployee : Employee
{
public decimal FixedSalary { get; set; } = 2000.0m; // Example fixed part
public override decimal CalculateSalary()
{
// Specific calculation for full-time: fixed salary + bonus for extra hours
return (HoursWorked * 10.0m) + FixedSalary;
}
}PartTimeEmployee:
public class PartTimeEmployee : Employee
{
public decimal HourlyWage { get; set; } = 8.0m;
public override decimal CalculateSalary()
{
// Specific calculation for part-time
return HoursWorked * HourlyWage;
}
}ุงูู
ุดููุฉ:
ุฅู ูู ูู subclass ุบูุฑุช ุงูู logic ุจุชุงุน CalculateSalary ุจุดูู ุฌุฐุฑู ูุฏุฑุฌุฉ ุฅููุง ู
ุจูุชุด โุชุญุชุฑู
โ ุงูู
ุนูู ุงูุฃุตูู ููู
ูุซูุฏ ูู ุงูู base classุ ุฏู ู
ู
ูู ูุคุฏู ูู
ุดุงูู. ู
ุซูุงูุ ูู CalculateSalary ูู ุงูู base class ูููุง ู
ุนูู ู
ุนูู (ุฒู ุฅููุง ู
ุฑุชุจุทุฉ ู
ุจุงุดุฑุฉ ุจุนุฏุฏ ุงูุณุงุนุงุช HoursWorked)ุ ูุฌู subclass ุนู
ู override ูุฑุฌุน ููู
ุฉ ุซุงุจุชุฉ ู
ุงููุงุด ุฏุนูุฉ ุจู HoursWorked ุฎุงูุตุ ุฏู ู
ู
ูู ูููู violation ูู ุงููู ุจูุณุชุฎุฏู
ุงูู base class ุจูุชููุน ุณููู ู
ุนูู ุจูุงุกู ุนูู HoursWorked.
ุงูุฎูุงุตุฉ ุฅู ุงูู override ูุงุฒู
ูููู ู
ูุทูู ูู ุณูุงู ุงูู base method.
ุงูุญู :
ูุตู ุงูู salary calculation ูู interface ู
ููุตู ูู ุงูู logic ุจูุฎุชูู ุฌุฏุงู.
public interface ISalaryCalculator
{
decimal CalculateSalary(EmployeeDetails details); // EmployeeDetails could hold HoursWorked, Type, etc.
}
public class EmployeeDetails // Helper for ISalaryCalculator
{
public string EmployeeType { get; set; }
public int HoursWorked { get; set; }
public decimal BaseRate { get; set; }
public decimal FixedComponent { get; set; }
}
// Base Employee class might not have CalculateSalary directly anymore,
// or it could have a default one if ISalaryCalculator is optional.
public class EmployeeBase // Renamed to avoid confusion
{
public string Name { get; set; }
// Other common properties
}
public class FullTimeEmployeeStrategy : ISalaryCalculator
{
public decimal CalculateSalary(EmployeeDetails details)
{
// Logic specific to full-time, e.g. FixedComponent + (details.HoursWorked * bonusRate)
Console.WriteLine("C#: Calculating FullTime Employee Salary using Strategy.");
return details.FixedComponent + (details.HoursWorked * details.BaseRate); // Example logic
}
}
public class PartTimeEmployeeStrategy : ISalaryCalculator
{
public decimal CalculateSalary(EmployeeDetails details)
{
// Logic specific to part-time
Console.WriteLine("C#: Calculating PartTime Employee Salary using Strategy.");
return details.HoursWorked * details.BaseRate;
}
}
// Client code would use the strategy
public class SalaryService
{
private readonly ISalaryCalculator _salaryCalculator;
private readonly EmployeeDetails _employeeDetails;
public SalaryService(ISalaryCalculator salaryCalculator, EmployeeDetails employeeDetails)
{
_salaryCalculator = salaryCalculator;
_employeeDetails = employeeDetails;
}
public decimal GetSalary()
{
return _salaryCalculator.CalculateSalary(_employeeDetails);
}
}ุจูุฏูุ ุงูู Employee class ููุณูุง (ุฃู EmployeeBase ูู ุงูู
ุซุงู ุฏู) ู
ุจูุงุด ูููุง ุงูู CalculateSalary ุจุงูู logic ุงูู
ุฎุชููุ ูุจูู ุงูู logic ุฏู ู
ูุฌูุฏ ูู strategies ู
ููุตูุฉ. ุฏู ุจูุถู
ู ุฅู ุฃู EmployeeBase object ููู ููุณ ุงูุฎุตุงุฆุต ุงูุฃุณุงุณูุฉุ ูุงูู calculation ุจูุชู
ุจุทุฑููุฉ ูุงุถุญุฉ ูู
ูุตููุฉ.
ู
ุซุงู ุนู
ูู: ุงูุทูุจุงุช ูุชูุงููู ุงูุดุญู (Order & ShippingCost)
// Base Order class
public class OrderLSP
{
public string Name { get; set; }
public decimal Price { get; set; }
// protected decimal ShippingCost { get; set; } // Made protected
public virtual decimal GetTotalPrice()
{
// Base implementation might assume some default shipping or that shipping is added by subclasses
Console.WriteLine($"C#: OrderLSP - GetTotalPrice called for {Name}. Price: {Price}");
return Price; // Default: price without shipping
}
}
// DeliveryOrder expects shipping to be added
public class DeliveryOrder : OrderLSP
{
public decimal ShippingCost { get; private set; } = 25.0m; // Example shipping cost
public DeliveryOrder(string name, decimal price)
{
Name = name;
Price = price;
}
public override decimal GetTotalPrice()
{
decimal basePrice = base.GetTotalPrice(); // Good practice to call base if relevant
decimal totalPrice = basePrice + ShippingCost;
Console.WriteLine($"C#: DeliveryOrder - Total for {Name}: {basePrice} + Shipping {ShippingCost} = {totalPrice}");
return totalPrice;
}
}
// PickupOrder should NOT have shipping costs.
public class PickupOrder : OrderLSP
{
public PickupOrder(string name, decimal price)
{
Name = name;
Price = price;
}
// By inheriting GetTotalPrice from OrderLSP, it correctly returns just the Price,
// which is what we want for a PickupOrder (no shipping).
// If OrderLSP's GetTotalPrice always added a base shipping, PickupOrder would have
// to override it to *remove* or *zero-out* shipping, which could be an LSP violation
// if clients expect GetTotalPrice to always behave in one way w.r.t shipping.
// If OrderLSP.GetTotalPrice implicitly included a default non-zero shipping cost,
// PickupOrder would violate LSP if it just returned Price.
// The current structure is okay.
}ุงูู
ุดููุฉ (ูู ุงูู base class ุงูุชุฑุถุช ุณููู ุฏุงูู
ุงู ููู ุดุญู):
ูู ุงูู OrderLSP.GetTotalPrice() ูุงูุช ุฏุงูู
ุงู ุจุชุถูู ุฑูู
ุดุญู (ุญุชู ูู ุตูุฑ)ุ ูุฌู ุงูู PickupOrder ุญุจ ููุบู ุงูุดุญู ุฏู ุฎุงูุต ุจุทุฑููุฉ ุบูุฑ ู
ุชููุนุฉ (ู
ุซูุงู ูุทุฑุญ ููู
ุฉ ุฃู ูุฑุฌุน ุงูู Price ุจุณ ูู
ุง ุงูู client ู
ุชููุน ุฅู ุงูุดุญู ู
ุญุณูุจ)ุ ุฏู ู
ู
ูู ูุจูู LSP violation.
ุงูุญู ุงูู ูุชุฑุญ (ูุตู ุญุณุงุจ ุงูุดุญู):
public interface IShippingCostCalculator
{
decimal CalculateShippingCost(OrderLSP order);
}
public class StandardShippingCalculator : IShippingCostCalculator
{
public decimal CalculateShippingCost(OrderLSP order)
{
// Logic for standard shipping, maybe based on weight, distance, or a flat fee
return 25.0m; // Example flat fee
}
}
public class NoShippingCalculator : IShippingCostCalculator // For Pickup Orders
{
public decimal CalculateShippingCost(OrderLSP order)
{
return 0m; // No shipping cost
}
}
// Modified OrderLSP to use the calculator strategy
public class OrderLSP_Refactored
{
public string Name { get; set; }
public decimal Price { get; set; }
private readonly IShippingCostCalculator _shippingCalculator;
public OrderLSP_Refactored(string name, decimal price, IShippingCostCalculator shippingCalculator)
{
Name = name;
Price = price;
_shippingCalculator = shippingCalculator;
}
public decimal GetTotalPrice()
{
decimal shipping = _shippingCalculator.CalculateShippingCost(this); // 'this' might not be needed if calculator has all info
Console.WriteLine($"C#: OrderLSP_Refactored - Price: {Price}, Shipping: {shipping}");
return Price + shipping;
}
}
// Client code would then provide the correct calculator
// var deliveryOrder = new OrderLSP_Refactored("Laptop", 1200, new StandardShippingCalculator());
// var pickupOrder = new OrderLSP_Refactored("Mouse", 25, new NoShippingCalculator());
// Console.WriteLine(deliveryOrder.GetTotalPrice());
// Console.WriteLine(pickupOrder.GetTotalPrice());ูุฏู ุงูู base class (OrderLSP_Refactored) ููุณูุง ู
ุจูุชุด ู
ุณุคููุฉ ุนู ุงูู logic ุงูุฎุงุต ุจุญุณุงุจ ุชูููุฉ ุงูุดุญูุ ูุงูู Subtypes (DeliveryOrder ู PickupOrder) ุจูุชู
ุชุญุฏูุฏ ุณููู ุงูุดุญู ุจุชุงุนูู
ุนู ุทุฑูู IShippingCostCalculator ุงููู ุจูุชู
ุญููู. ุฃู object ู
ู OrderLSP_Refactored ููุชุตุฑู ุจุดูู ู
ุชููุน ุจูุงุกู ุนูู ุงูู calculator ุงููู ู
ุนุงู.
4. Interface Segregation Principle - ISP
ุญุฑู I ูู SOLID ุจูุฑู
ุฒ ููู Interface Segregation Principle.
ูุนูู ุฅูู Interface Segregationุ
ุงูู
ุจุฏุฃ ุฏู ุจุณูุท ูุจูููู:
โู
ููุด code ุงูู
ูุฑูุถ ูููู ู
ุฌุจุฑ ุฅูู ูุนุชู
ุฏ ุนูู methods ูู ู
ุด ููุณุชุฎุฏู
ูุง ุฃู ู
ุด ููุนู
ููุง implementation.โ
ุงูู ISP ุจููููู ูุณู
ุงูู interfaces ุงููุจูุฑุฉ (ุงููู ูููุง methods ูุชูุฑุ ุจูุณู
ููุง โfat interfacesโ) ูู interfaces ุฃุตุบุฑ ูุฃูุซุฑ ุชุฎุตุตูุง (ุจูุณู
ููุง โrole interfacesโ ุฃู โfine-grained interfacesโ). ูู class ุชุนู
ู implement ููู interface ุงููู ููู ุงูู methods ุงููู ูู ู
ุญุชุงุฌุงูุง ูุนูุงู ุจุณ.
ู
ุซุงู: ู
ุฏูุฑ ุงูู
ูุงู
(TaskManager)
ูุชูุถูุญ ุงูููุฑุฉุ ูููุชุฑุถ ูุฌูุฏ ุงูููุงุณุงุช ุฏู:
public class TaskItem // Helper class
{
public int Id { get; set; }
public string Description { get; set; }
}
public class User // Helper class
{
public string Name { get; set; }
}ุชุฎูู ุนูุฏูุง interface ุงุณู
ู ITaskManagerFat ุจูุนู
ู ุญุงุฌุงุช ูุชูุฑ:
// "Fat" interface - Bad example
public interface ITaskManagerFat
{
void CreateTask(TaskItem task);
void AssignTask(TaskItem task, User user);
void SendNotification(TaskItem task, string message); // Notification-related method
}ูุนูุฏูุง TaskService ุจูุนู
ู implement ููู interface ุฏู:
public class TaskServiceUsingFatInterface : ITaskManagerFat
{
public void CreateTask(TaskItem task)
{
Console.WriteLine($"C#: TaskService - Task '{task.Description}' created.");
}
public void AssignTask(TaskItem task, User user)
{
Console.WriteLine($"C#: TaskService - Task '{task.Description}' assigned to {user.Name}.");
}
// This TaskService might not be responsible for sending notifications,
// but it's forced to implement it because of the fat interface.
public void SendNotification(TaskItem task, string message)
{
Console.WriteLine($"C#: TaskService - (Forced Impl) Notification for '{task.Description}': {message}. Maybe not its job.");
// Or it might throw new NotSupportedException("SendNotification is not supported by TaskService.");
// Or leave it empty. All are bad signs.
}
}ุงูู ุดููุฉ ููุง ุฅููุ
- ุงูู
SRP violation(ู ุญุชู ู): ุงููTaskServiceุจูู ู ุณุคูู ุนู ุฅุฏุงุฑุฉ ุงูู ูุงู ููู ุงู ุฅุฑุณุงู ุงูุฅุดุนุงุฑุงุช (ูู ูู ุงููู ุจูููุฐูุง ูุนูุงู). ISP violation:- ุงูู
TaskServiceUsingFatInterfaceู ุฌุจุฑ ูุนู ูimplementูููSendNotificationุญุชู ูู ู ุด ููุณุชุฎุฏู ูุง ุฃู ู ุด ุฏู ู ุณุคูููุชู. ู ู ูู ูุณูุจ ุงููmethod bodyูุงุถู ุฃู ูุฑู ูNotSupportedException. - ูู ุนูุฏูุง
classุชุงููุฉ ูู ูู ูุง ุฅุฑุณุงู ุงูุฅุดุนุงุฑุงุช (ู ุซูุงูStandaloneNotificationService)ุ ูุชุถุทุฑ ุชุนู ูimplementูููITaskManagerFatูููุ ุจู ุง ูููCreateTaskูAssignTaskุงููู ูู ู ุด ู ุญุชุงุฌุงูู ุ ุจุณ ุนุดุงู ุชุณุชุฎุฏูSendNotification.
- ุงูู
ุงูุญู (ุชุทุจูู ุงูู ISP):
ููุณู
ุงูู interface ุงููุจูุฑ ูู interfaces ุฃุตุบุฑ ูุฃูุซุฑ ุชุฎุตุตูุง:
- ุงูู
ITaskOperations: ููุนู ููุงุช ุงูุฎุงุตุฉ ุจุงูู ูุงู ููุท.
// Interface for task operations
public interface ITaskOperations
{
void CreateTask(TaskItem task);
void AssignTask(TaskItem task, User user);
}- ุงูู
INotificationService: ูุนู ููุงุช ุฅุฑุณุงู ุงูุฅุดุนุงุฑุงุช ููุท.
// Interface for notification sending
public interface INotificationService // Renamed for clarity from INotificationSender
{
void SendNotification(string recipientIdentifier, string message); // More generic now
}ุงูู classes ุจุนุฏ ุงูุชุนุฏูู:
- ุงูู
TaskManagementServiceููุนู ูimplementูููITaskOperations:
public class TaskManagementService : ITaskOperations // Implements only what it needs
{
public void CreateTask(TaskItem task)
{
Console.WriteLine($"C#: TaskManagementService - Task '{task.Description}' created.");
}
public void AssignTask(TaskItem task, User user)
{
Console.WriteLine($"C#: TaskManagementService - Task '{task.Description}' assigned to {user.Name}.");
}
// Not forced to implement SendNotification
}- ูู ููู
classู ุณุคููุฉ ุนู ุงูุฅุดุนุงุฑุงุช (ุฒูEmailNotificationService)ุ ูุชุนู ูimplementูููINotificationService:
public class EmailNotificationService : INotificationService
{
public void SendNotification(string emailAddress, string message)
{
Console.WriteLine($"C#: EmailNotificationService - Email sent to {emailAddress}: {message}");
}
}- ูู ุงูู
TaskManagementServiceู ุญุชุงุฌ ูุจุนุช ุฅุดุนุงุฑุงุชุ ู ู ูู โูุณุชุฎุฏู โ (ูุนู ูcompositionููุญููdependency) ููinstanceู ูINotificationServiceุ ุฃู ู ู ูู ุญุชู ูุฎุชุงุฑ ูุนู ูimplementููINotificationServiceูู ูู ุงู ูู ุฏู ู ูุทูู ูู ุณูุงูู (ู ุน ุงูุญุฐุฑ ู ู ู ุฎุงููุฉ SRP). ุงููTaskManagementServiceู ุจูุงุด ู ุฌุจุฑ ูุนู ูimplementูุญุงุฌุฉ ู ุด ููุณุชุฎุฏู ูุง.
ู
ุซุงู ุนู
ูู: UserManagement
ูุชูุถูุญ ุงูููุฑุฉุ ูููุชุฑุถ ูุฌูุฏ ุงูููุงุณุงุช ุฏู:
// Helper class for User
// public class User { public string Name { get; set; } /* ... other properties ... */ } already defined
// Helper class for Product
// public class Product { public string Name { get; set; } /* ... other properties ... */ } already definedุชุฎูู ุนูุฏูุง IUserManagementFat interface:
// Original "fat" interface
public interface IUserManagementFat
{
void UpdateUserProfile(User user);
void ChangePassword(User user, string newPassword);
void SubscribeToNewProductAvailability(User user, Product product);
void SubscribeToSmsNotifications(User user, string topic);
}ูุนูุฏูุง Customer ุจูุนู
ู implement ููู ุฏูู.
ููู ุนูุฏูุง GuestSubscriber (ู
ู
ูู ูููู guest user ุนู
ู subscribe ู
ู ุบูุฑ account ูุงู
ู)ุ ูู ุจุณ ุนุงูุฒ ูุนู
ู subscribe ูู product availability ุฃู SMS notificationsุ ูู
ุด ู
ุญุชุงุฌ UpdateUserProfile ุฃู ChangePassword.
ููุง ุงูู GuestSubscriber ู
ุฌุจุฑ ูุนู
ู implement ูู methods ู
ุด ููุณุชุฎุฏู
ูุง.
ุงูุญู (ุชุทุจูู ุงูู ISP):
- ุงูู
IAccountManagement: ููุนู ููุงุช ุงูุฎุงุตุฉ ุจุงูุญุณุงุจ.
// Interface for account specific actions
public interface IAccountManagement
{
void UpdateUserProfile(User user);
void ChangePassword(User user, string newPassword);
}- ุงูู
ISubscriptionManagement: ููุนู ููุงุช ุงูุฎุงุตุฉ ุจุงูุงุดุชุฑุงูุงุช.
// Interface for subscription actions
public interface ISubscriptionManagement // Renamed from ISubscriptionService for clarity
{
void SubscribeToNewProductAvailability(User user, Product product);
void SubscribeToSmsNotifications(User user, string topic);
}ุงูู classes ุจุนุฏ ุงูุชุนุฏูู:
- ุงูู
RegisteredCustomerููุนู ูimplementููุงุชููู:IAccountManagementูISubscriptionManagement.
public class RegisteredCustomer : IAccountManagement, ISubscriptionManagement
{
private User _user;
public RegisteredCustomer(User user) { _user = user; }
// From IAccountManagement
public void UpdateUserProfile(User user) { Console.WriteLine($"C#: RegisteredCustomer {_user.Name} profile updated."); }
public void ChangePassword(User user, string newPassword) { Console.WriteLine($"C#: RegisteredCustomer {_user.Name} password changed."); }
// From ISubscriptionManagement
public void SubscribeToNewProductAvailability(User user, Product product) { Console.WriteLine($"C#: RegisteredCustomer {_user.Name} subscribed to product {product.Name}."); }
public void SubscribeToSmsNotifications(User user, string topic) { Console.WriteLine($"C#: RegisteredCustomer {_user.Name} subscribed to SMS for {topic}."); }
}- ุงูู
GuestSubscriberููุนู ูimplementูููISubscriptionManagementุจุณ.
public class GuestSubscriber : ISubscriptionManagement // Only needs subscription capabilities
{
private User _user; // Could be a simpler representation like just an email or phone
public GuestSubscriber(User user) { _user = user; }
// From ISubscriptionManagement
public void SubscribeToNewProductAvailability(User user, Product product) { Console.WriteLine($"C#: GuestSubscriber for {_user.Name} subscribed to product {product.Name}."); }
public void SubscribeToSmsNotifications(User user, string topic) { Console.WriteLine($"C#: GuestSubscriber for {_user.Name} subscribed to SMS for {topic}."); }
// Not forced to implement account management methods
}ูุฏู ูู class ุจุชุงุฎุฏ ุงูู interface ุงููู ููุงุณุจูุง ูู
ุจูุงุด ูู ุฅุฌุจุงุฑ ุนูู methods ู
ุด ูุชุณุชุฎุฏู
ูุง.
5. Dependency Inversion Principle - DIP
ุญุฑู D ูู SOLID ุจูุฑู
ุฒ ููู Dependency Inversion Principle. ุฑูุฒูุง ูู ุฏู ุนุดุงู ู
ูู
ููุงุณ ูุชูุฑ ุจุชุชูุฎุจุท ููู.
ูุนูู ุฅูู Dependency Inversionุ
ุงูู ุจุฏุฃ ุฏู ุจููุต ุนูู ุญุงุฌุชูู:
- ุงูู high-level modules ู ูููุนุด ุชุนุชู ุฏ ู ุจุงุดุฑุฉ ุนูู ุงูู low-level modules. ุงูุงุชููู ูุงุฒู ูุนุชู ุฏูุง ุนูู Abstraction (ุฒู ุงูู interfaces ุฃู abstract classes).
- ุงูู abstractions ููุณูุง ู ูููุนุด ุชุนุชู ุฏ ุนูู ุงูุชูุงุตูู (ุงูู concrete implementations). ุงูุนูุณ ูู ุงูุตุญูุญ: ุงูุชูุงุตูู (ุงูู concrete classes) ูู ุงููู ุงูู ูุฑูุถ ุชุนุชู ุฏ ุนูู ุงูู abstractions (ุนู ุทุฑูู ุฅููุง ุชุนู ููุง implement ุฃู ุชูุฑุซ ู ููุง).
ูุนูู ุฅูู ุงูููุงู
ุฏูุ
ุชุฎูู ุนูุฏู OrderProcessingService (ุฏู high-level module ูุฃูู ููู business logic ูู
ุณุคูู ุนู ุชูุณูู ุนู
ููุฉ ูุจูุฑุฉ).
ูุนูุฏู MySqlOrderDataAccess (ุฏู low-level module ูุฃูู ุชูุตููุฉ ุชูููุฉ ูููุตูู ููุฏุงุชุง ุจูุฒ).
ูู ุงูู OrderProcessingService ุจูุนู
ู new MySqlOrderDataAccess() ุฌูุงู ู
ุจุงุดุฑุฉุ ูุฏู ุงูู high-level ุจูุนุชู
ุฏ ุนูู ุชูุตููุฉ low-level (concrete implementation). ุฏู ุจูุฎูู ุงูู service ุจุชุงุนุชู ู
ุฑุจูุทุฉ ุฌุงู
ุฏ ุจุงูู MySQL. ูู ุญุจูุช ุชุบูุฑ ูู PostgreSQL ุฃู ุชุณุชุฎุฏู
mock ูู ุงูู testingุ ูุชุจูู ู
ุดููุฉ.
ุงูู DIP ุจููููู ูุฃุ ู ุชุนู ูุด ูุฏู. ุฎูู ุงูุงุชููู ูุนุชู ุฏูุง ุนูู abstraction:
- ุงูู
OrderProcessingService(high-level) ูุนุชู ุฏ ุนูู interface (ู ุซูุงูIOrderDataAccess). - ุงูู
MySqlOrderDataAccess(low-level) ูุนู ู implement ูููinterfaceIOrderDataAccess. - ูุชู
โุญููโ (inject) ุงูู concrete implementation (ุฒู
MySqlOrderDataAccess) ุฌูู ุงููOrderProcessingService(ุนุงุฏุฉู ุนู ุทุฑูู ุงููconstructor).
ูุฏู ุงูุงุชููู (ุงูู high-level ูุงูู low-level) ุจููุง ุจูุนุชู
ุฏูุง ุนูู abstraction ุฒู (IOrderDataAccess).
ูุงูุงุนุชู
ุงุฏูุฉ ุงุชุนูุณุช: ุจุฏู ู
ุง ุงูู business logic ุจูุดุงูุฑ ุนูู ุงูู data accessุ ุจูู ุงูู data access ูู ุงููู ุจูุดุงูุฑ (ุจูุนู
ู implement) ููู abstraction ุงููู ุงูู business logic ุจูุนุฑููุง ูุจูุณุชุฎุฏู
ูุง.
ู
ุซุงู: OrderManagementService ู OrderDataAccess
ุงูุดูู ุงูุบูุท (ู ุฎุงููุฉ ุงูู DIP) - ูุงู ูููู ุจูุนุชู ุฏ ุนูู ูู ูููู:
// Low-level module (concrete data access implementation)
public class MySqlOrderDataAccessNoDIP
{
public List<Order> FetchAllOrdersFromDB()
{
Console.WriteLine("C#: MySqlOrderDataAccessNoDIP - Fetching all orders from MySQL.");
// Actual database query logic here
return new List<Order>();
}
// Other methods like SaveOrder, etc.
}
// High-level module directly depending on the low-level concrete class
public class OrderManagementServiceNoDIP
{
private readonly MySqlOrderDataAccessNoDIP _dataAccess; // Direct dependency on a CONCRETE class
public OrderManagementServiceNoDIP()
{
// Instantiation of concrete class inside the high-level module
_dataAccess = new MySqlOrderDataAccessNoDIP();
}
public List<Order> GetAndProcessOrders()
{
Console.WriteLine("C#: OrderManagementServiceNoDIP - Getting and processing orders.");
List<Order> orders = _dataAccess.FetchAllOrdersFromDB();
// Further processing logic on orders...
return orders;
}
}ููุง ุงูู OrderManagementServiceNoDIP (high-level) ุจูุนุชู
ุฏ ู
ุจุงุดุฑุฉ ุนูู MySqlOrderDataAccessNoDIP (low-level).
ุงูุญู (ุชุทุจูู ุงูู DIP) - ุงูุงุชููู ุจูุนุชู ุฏูุง ุนูู ุฃุจุณุชุฑุงูุดู:
- ูุนู ู abstraction (interface) ููุฏุงุชุง ุฃูุณุณ:
// Abstraction (Interface) for data access
public interface IOrderDataAccess // Renamed from IOrderRepository for consistency with video's naming flow
{
List<Order> FetchAllOrders();
// void SaveOrder(Order order); // Example of other methods
}- ุงูู low-level modules (ุงูุชูุงุตูู) ุชุนู ู implement ููู interface:
// Low-level module (concrete MySQL implementation) implementing the abstraction
public class MySqlOrderDataAccess : IOrderDataAccess
{
public List<Order> FetchAllOrders()
{
Console.WriteLine("C#: MySqlOrderDataAccess - Fetching all orders from MySQL (via IOrderDataAccess).");
return new List<Order>();
}
}
// Another possible low-level module (concrete MongoDB implementation)
public class MongoDbOrderDataAccess : IOrderDataAccess
{
public List<Order> FetchAllOrders()
{
Console.WriteLine("C#: MongoDbOrderDataAccess - Fetching all orders from MongoDB (via IOrderDataAccess).");
return new List<Order>();
}
}- ุงูู high-level module ูุนุชู ุฏ ุนูู ุงูู interface (ุนุงุฏุฉู ุนู ุทุฑูู ุงูู constructor injection):
// High-level module depending on the abstraction (IOrderDataAccess)
public class OrderManagementServiceWithDIP
{
private readonly IOrderDataAccess _dataAccessProvider; // Depends on ABSTRACTION
// Dependency is injected via constructor (Constructor Injection)
public OrderManagementServiceWithDIP(IOrderDataAccess dataAccessProvider)
{
_dataAccessProvider = dataAccessProvider;
}
public List<Order> GetAndProcessOrders()
{
Console.WriteLine("C#: OrderManagementServiceWithDIP - Getting and processing orders using injected provider.");
List<Order> orders = _dataAccessProvider.FetchAllOrders(); // Uses the abstraction
// Further processing logic on orders...
return orders;
}
}ุจูุทุจู ุงูู DIP ุนู ุทุฑูู ุงูู Dependency Injection (DI) ูุงููู ุนู ููุงู ููู ุฏุง ุงุณู ู Constructor Injection ูุฏุง ููุน ู ู ุงููุงุนู
ุงููุงูุฏุฉ ู ู ูุฏู ุฅููุ
- ุงูู
OrderManagementServiceWithDIPู ุจูุงุด ู ุฑุจูุท ุจููุน database ู ุนูู. ููุฏุฑ ูุฏููู ุฃู class ุจุชุนู ู implement ูููIOrderDataAccess(ุณูุงุกMySqlOrderDataAccessุฃูMongoDbOrderDataAccessุฃู ุญุชูInMemoryDataAccessุนุดุงู ุงูู testing). - ุฏู ุจูุณูู ุงูู testing ุฌุฏุงู (ุจุงุณุชุฎุฏุงู
mock objects ููู
IOrderDataAccess). - ุจูุฒูุฏ ุงูู flexibility ู ุงูู extensibility ููู system.
- ุงูุงุนุชู ุงุฏูุฉ ุงุชุนูุณุช: ุจุฏู ู ุง ุงูู high-level module (ุงููService) ุจูุนุฑู ูุจูุนู ู instantiate ููู low-level module (ุงูู Data Access)ุ ุจูู ุงูู high-level module ุจูุนุชู ุฏ ุนูู abstraction ุงููู ูู (interface)ุ ูุงูู low-level module ูู ุงููู ุจูุนู ู implement ููู abstraction ุฏู. ูุงูู client ุฃู ุงูู Dependency Injection Container ูู ุงููู ุจูุฑุจุทูู ุจุจุนุถ.
ู
ุซุงู ุนู
ูู ุณุงุจู (PaymentProcessor ู IPaymentStrategy):
ู
ุซุงู ุงูู PaymentProcessor ุงููู ุงุณุชุฎุฏู
ูุงู ูู ุดุฑุญ ุงูู OCP ูู ูู
ุงู ุจูุทุจู ุงูู DIP ุจุดูู ูููุณ:
- ุงูู
PaymentProcessor(high-level module) ูุงู ุจูุนุชู ุฏ ุนููIPaymentStrategy(abstraction). - ุงูู concrete strategies ุฒู
VisaPaymentStrategyุMasterCardPaymentStrategy(low-level modules/ุงูุชูุงุตูู) ูุงููุง ุจูุนู ููุง implement ูููIPaymentStrategy. - ููุง ุจูุนู
ู inject (ุญูู) ููู concrete strategy ูู ุงูู constructor ุจุชุงุน ุงูู
PaymentProcessor.
// class PaymentProcessor
// {
// private readonly IPaymentStrategy _paymentStrategy; // Depends on ABSTRACTION
//
// public PaymentProcessor(IPaymentStrategy paymentStrategy) // DIP happens here via Constructor Injection
// {
// _paymentStrategy = paymentStrategy;
// }
//
// public void ExecutePayment(Order order)
// {
// _paymentStrategy.ProcessPayment(order.TotalAmount); // Uses the abstraction
// }
// }ุจูุฏูุ ูุตููุง ุงูุงุนุชู
ุงุฏูุฉ ุจุชุงุนุฉ ุงูู PaymentProcessor ุนู ููุน ุงูุฏูุน ุงููู ููุฌูููุ ูุฎูููุง ุงูุงุชููู (ุงูู high-level ูุงูู low-level) ูุนุชู
ุฏูุง ุนูู abstraction.
ุฎูุงุตุฉ ู ุจุงุฏุฆ SOLID
ูุฏู ุฅุญูุง ุดูููุง ู
ุน ุจุนุถ ุงูุฎู
ุณ ู
ุจุงุฏุฆ ุจุชูุน SOLID ูุฃูู
ูุชูู
:
- ุงูู S -
Single Responsibility Principle: ุงูู class ูููู ูููุง ุณุจุจ ูุงุญุฏ ุจุณ ููุชุบููุฑ. - ุงูู O -
Open/Closed Principle: ุงูู code ูููู ู ูุชูุญ ููุชูุณูุน (ุจุฅุถุงูุฉ functionality ุฌุฏูุฏุฉ ู ู ุบูุฑ ุชุนุฏูู ุงูููุฏ ุงููุฏูู ) ูู ูููู ุนู ุงูุชุนุฏูู ุงูู ุจุงุดุฑ (ูู ุงูููุฏ ุงููุฏูู ุงููู ุดุบุงู ูุซุงุจุช). - ุงูู L -
Liskov Substitution Principle: ููุฏุฑ ูุณุชุฎุฏู object ู ู subclass ู ูุงู object ู ู parent class ู ู ุบูุฑ ู ุง ุงูุจุฑูุงู ุฌ ูุถุฑุจ ุฃู ุณูููู ูุชุบูุฑ ุจุดูู ุบูุฑ ู ุชููุน. ุงููchild ูุงุฒู ูุญุชุฑู โุนูุฏโ ุงูู parent. - ุงูู I -
Interface Segregation Principle: ู ุชุฌุจุฑุด class ุฅููุง ุชุนู ู implement ูู methods ูู ู ุด ู ุญุชุงุฌุงูุงุ ูุณู ุงูู interfaces ุงููุจูุฑุฉ ูู interfaces ุฃุตุบุฑ ูุฃูุซุฑ ุชุฎุตุตูุง. - ุงูู D -
Dependency Inversion Principle: ุงูู high-level modules ู ุชุนุชู ุฏุด ุนูู low-level modules ู ุจุงุดุฑุฉุ ุงูุงุชููู ูุนุชู ุฏูุง ุนูู abstractions. ูุงูุชูุงุตูู ูู ุงููู ุชุนุชู ุฏ ุนูู ุงูู abstractionsุ ู ุด ุงูุนูุณ.
ุชุทุจูู ุงูู
ุจุงุฏุฆ ุฏู ุจูุฎูู ุงูู software ุจุชุงุนูุง ุฃุญุณู ุจูุชูุฑ ู
ู ุญูุซ ุงูุฌูุฏุฉุ ูุณูููุฉ ุงูุตูุงูุฉุ ูุงููุงุจููุฉ ููุชูุณุน ูุงูุงุฎุชุจุงุฑ.