Вопрос о дизайне объекта / класса - PullRequest
0 голосов
/ 22 октября 2009

У меня есть класс следующим образом: -

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
}

Обратите внимание, что только если он помечен как FilterFirstName, ему потребуется свойство StartCharacter.

Правильно ли указано выше, или я должен отделить фильтры FirstName и LastName, поскольку они требуют разных свойств? Потому что я думаю, что в этом случае необходимо ввести некоторые бизнес-правила при вводе данных в этот класс.

Пожалуйста, совет, Спасибо

Ответы [ 3 ]

2 голосов
/ 22 октября 2009

Перечисления часто являются запахом кода, что ваш дизайн не совсем правильный. В этом случае вы могли бы добиться большего успеха путем рефакторинга функциональности списка исключений в базовый класс, а затем добавления отдельных производных классов для фильтров имени и фамилии. Фильтр фамилии не будет ничего отличать от универсального фильтра, но фильтр имени также будет проверять начальный символ.

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
{
}
1 голос
/ 22 октября 2009

Это похоже на неправильный факторинг. Очевидно, что фильтр тесно связан со значением перечисления, а тип определяет, какие конкретные критерии ему нужны, и значения данных для этого смешиваются в один класс.

Более "чисто" иметь отдельные классы фильтров, в которых содержатся только соответствующие данные. Перечисление может быть удалено, если вы сделаете это изменение.

1 голос
/ 22 октября 2009

Глядя на то, что у вас есть, кажется, что было бы наиболее разумно иметь несколько классов, которые наследуются от IFilterCondition, которые определяют, что каждый полностью реализует свою собственную версию ApplyFilter() - FirstNameFilter, LastNameFilter, PhoneNumberFilter и др.

Чтобы сохранить код, вы можете просто извлечь его из конкретной реализации, если и когда вам потребуется повторно использовать аналогичную логику для определения фильтра. Например, у вас может быть [abstract] StartCharacterFilter, который определяет этот символ и усекает список в его методе ApplyFilter(), тогда FirstNameFilter просто переопределит ApplyFilter(), вызовет базовую реализацию и передаст результат в свою собственную логику .

...