c# - que - Agregar nuevas funciones a una interfaz
interfaz asp net (6)
Creo que mantener una sola interfaz es más fácil, pero el segundo enfoque con 2 interfaces es mejor porque no todas las clases necesitan implementar bool Add(int a, int b, int c);
Necesito crear sobrecargas para funciones en una interfaz existente sin afectar a los componentes que actualmente implementan o hacen uso de la interfaz (idealmente).
Me imagino que tengo un par de opciones:
Interfaz original simplificada:
public interface IServerComponent
{
bool Add(int a, int b);
}
Puedo agregar las nuevas funciones sobrecargadas a la interfaz y forzar a cada clase que implementa la interfaz a implementar las nuevas funciones.
public interface IServerComponent
{
bool Add(int a, int b);
bool Add(int a, int b, int c);
}
O puedo crear una nueva interfaz que implemente la interfaz original. Entonces otras clases que hagan uso del original no tendrán que cambiar y cualquier clase nueva puede implementar la nueva interfaz ...
public interface IServerComponent2 : IServerComponent
{
bool Add(int a, int b, int c);
}
¿Cuál es la mejor práctica es esta situación? ¿Hay otras opciones disponibles?
Gracias
Depende del contexto: si hay muchas clases que implementan la interfaz original, o si está publicada, entonces la única manera práctica es introducir la nueva. Por otro lado, tener solo una interfaz es mucho más limpio a largo plazo, por lo que yo diría que refactorice la existente si puede pagarla.
Me doy cuenta de que su ejemplo es artificial, pero quiero darle una respuesta artificial que es diferente de la que está expresando para que tal vez pueda pensar de otra manera. En lugar de tener su método de interfaz operando en algo concreto, podría tener sentido trabajar en algo abstracto.
Por ejemplo
public interface IAddableThings
{
int a;
int b;
}
public interface IOtherAddableThings : IAddableThings
{
int a;
int b;
}
public interface IServerComponent
{
bool Add(IAddableThings things);
}
Si esto realmente es un Add, creo que tiene mucho más sentido, pero si realmente se trata más de Calculate (), entonces querrás mover una parte o la totalidad de esa operación de métodos a los objetos de IAddableThings.
public interface IAddableThings
{
int a;
int b;
bool CalculateMe();
}
Si los nuevos métodos se pueden expresar en términos de los métodos anteriores, puede usar métodos de extensión:
// Original interface
public interface IServerComponent
{
bool Add(int a, int b, int c);
}
// New overload
public static class MyServerMethods
{
public static bool Add(this IServerComponent component, int a, int b)
{
return component.Add(a, b, 0);
}
}
Si los métodos no se pueden expresar así (es decir, realmente necesitan ser implementados por los componentes mismos), entonces recomendaría definir una nueva interfaz. Este enfoque tiene la máxima compatibilidad con versiones anteriores.
Si no necesita o no quiere cambiar las clases (ahora o en el futuro) que ya implementan la interfaz anterior, debe crear una segunda interfaz. Sin embargo, se siente más como un truco, y podría darte un código menos intuitivo.
Además, posponer una refactorización nunca es una buena idea en mi experiencia. Entonces, si sospecha que necesitará implementar la interfaz más adelante, también puede modificar la existente y ahorrarse un poco de dolor de cabeza. Definitivamente la forma más limpia de hacerlo.
Si su interfaz IServerComponent no se ha enviado aún o si la interfaz interna solo está implementada por sus propias clases, y los nuevos miembros de la interfaz tienen sentido para todas las clases existentes que implementan la interfaz, cambie la interfaz existente.
De lo contrario, cree una interfaz IServerComponent2 que amplíe IServerComponent. IIRC esto es lo que recomiendan las Pautas de diseño del marco. Un ejemplo de esto se puede encontrar en .NET Framework en la forma de la clase X509Certificate2 .
Sin embargo, si los miembros nuevos se pueden implementar en términos de los miembros originales, también puede usar métodos de extensión :
public interface IServerComponent
{
bool Add(int a, int b);
}
public static class ServerComponentExtensions
{
public static bool Add(this IServerComponent isc, int a, int b, int c)
{
return isc.Add(a, b) && isc.Add(b, c) && isc.Add(c, a);
}
}