Estoy tratando de refactorizar el código a continuación para adherirme al principio de apertura y cierre
Es un poco de código extraído con el propósito de hacer una pregunta, pero básicamente aquí el método de cálculo se comporta de manera diferente según el tipo de factura.
public class Invoice { private string _type; public double Calculate(double amount) { if(_type == "invoice") { return amount + 10; } else { return amount - 10; } } }lo he hecho hasta aquí
public interface IInvoice { double Calculate(double amount); } public class Invoice : IInvoice { public double Calculate(double amount) { return amount + 10; } } public class DiscountInvoice : IInvoice { public double Calculate(double amount) { return amount - 10; } }Obtengo el modelo a continuación desde un punto final de API, donde "Tipo" determina el clima para usar Factura o Factura de descuento. Me gusta evitar poner la condición if en el campo de tipo
public class InvoiceModel { public int Id { get; set; } public string Type { get; set; } public double Amount { get; set; } } static void Main(string[] args) { private IInvoice _invoice; //I am not sure how to detect and use the correct invoice type here. without doing below //based on something i have to assign _invoice = new Invoice() or new DiscountInvoice() }En primer lugar, su estructura se ve bien y cumple con el principio abierto-cerrado.
En términos de determinación de qué implementación de la abstracción usar, debe considerar la lógica comercial, ya que la decisión depende directamente de eso. Si tiene varias implementaciones de IInvoice, supongo que las necesitará todas en algún momento de su aplicación. Entonces, según su lógica comercial, debe decidir cuál usar. Puede considerar el patrón Factory, que se encargará de eso y le devolverá el tipo correcto. Toda la lógica empresarial se encapsulará allí. Justo cuando implemente su fábrica, también tenga en cuenta el LSP ( principio de sustitución de Liskov ), ya que es bastante fácil romperlo.