Pregunta de diseño de objeto / clase
-
05-07-2019 - |
Pregunta
Tengo una clase de la siguiente manera: -
interface IFilterCondition
{
List<Name> ApplyFilter(List<Name> namesToFilter);
}
class FilterName : IFilterCondition
{
public NameFilterEnum NameFilterEnum{ get; set; }
public List<Name> ExcludeList { get; set; }
public char StartCharacter{ get; set; }
#region IFilterCondition Members
public List<Name> ApplyFilter(List<Name> namesToFilter)
{
switch (NameFilterEnum)
{
case NameFilterEnum.FilterFirstName:
// Check Exclude List
// Check Start Character
break;
case NameFilterEnum.FilterLastName:
// Check Exclude List only
break;
default:
break;
}
return namesToFilter;
}
#endregion
}
enum NameFilterEnum
{
None,
FilterFirstName,
FilterLastName
}
Tenga en cuenta que solo si está marcado como FilterFirstName, requerirá la propiedad StartCharacter.
¿Es correcto lo anterior o debo separar el filtro de Nombre y el de Apellido, ya que requieren propiedades diferentes? Considero que, en este caso, es necesario aplicar algunas reglas de negocios al ingresar datos a esta clase.
Por favor, consejo, Gracias
Solución
Las enumeraciones son a menudo un olor a código que su diseño no está del todo bien. En este caso, podría hacerlo mejor al refactorizar la funcionalidad de la lista de exclusión en una clase base y luego agregar clases derivadas separadas para los filtros de nombre y apellido. El filtro de apellido no haría nada diferente al filtro genérico, pero el filtro de nombre también verificará el carácter de inicio.
interface IFilterCondition
{
List<Name> ApplyFilter(List<Name> namesToFilter);
}
abstract class FilterName : IFilterCondition
{
public List<Name> ExcludeList { get; set; }
public virtual List<Name> ApplyFilter(List<Name> namesToFilter)
{
// Check Exclude List
return namesToFilter;
}
}
class FilterFirstName : FilterName
{
public char StartCharacter{ get; set; }
public override List<Name> ApplyFilter(List<Name> namesToFilter)
{
namesToFilter = base.ApplyFilter(namesToFilter);
// Check Start Character
return namesToFilter;
}
}
class FilterLastName : FilterName
{
}
Otros consejos
Mirando lo que tienes allí, parece que tendría más sentido tener varias clases heredadas de IFilterCondition definidas que cada una implemente completamente su propia versión de ApplyFilter ()
- FirstNameFilter
, LastNameFilter
, PhoneNumberFilter
, etc.
Para guardar el código, simplemente puede derivar de una implementación concreta que cree si y cuando necesita reutilizar una lógica similar para definir el filtro. Por ejemplo, podría tener un [abstract] StartCharacterFilter
que define ese carácter y trunca la lista en su método ApplyFilter ()
entonces, FirstNameFilter
simplemente invalide ApplyFilter ()
, llame a la implementación base y pase el resultado a su propia lógica.
Esto parece una factorización impropia. Al parecer, el filtro está fuertemente acoplado con un valor enum, y el tipo determina qué criterios específicos necesita, y los valores de los datos para eso se mezclan en una sola clase.
Es más " puro " tener clases de filtro separadas con solo datos relevantes contenidos dentro de cada una. Es probable que la enumeración se pueda eliminar si realiza ese cambio.