несколько классов с одинаковыми методами - лучший образец - PullRequest
8 голосов
/ 05 апреля 2010

У меня есть несколько классов в моем текущем проекте, где необходима проверка адресов электронной почты / веб-сайтов. Методы для этого все одинаковы.

Мне стало интересно, как лучше всего это реализовать, поэтому мне не нужно, чтобы эти методы копировались везде?

Сами классы не обязательно связаны, у них есть только те общие методы проверки.

Ответы [ 9 ]

17 голосов
/ 05 апреля 2010

Как насчет добавления интерфейса и использования метода расширения?

public interface IFoo { }

public class A : IFoo {}
public class B : IFoo {}
public class C : IFoo {}

public static class FooUtils {
    public static void Bar(this IFoo foo) { /* impl */ }
}

Таким образом:

  • нет ненужного наследования
  • без дублирования
7 голосов
/ 05 апреля 2010

Возможно, вы захотите поместить весь код проверки в класс Validator, а затем использовать этот класс везде, где требуется проверка. Доступ к валидации должен быть одним способом, возможно Validate(object Something). Я думаю, что это называется «Композиция» (что касается шаблонов проектирования).

Позже у вас могут быть подклассы Validator, которые могут быть более конкретными или выполнять различные виды проверки.

Вы также можете иметь все классы, требующие проверки, расширять базовый класс или абстрактный класс, который содержит 90% проверки.

5 голосов
/ 05 апреля 2010

Похоже, вам просто нужен статический класс со статическим методом

public static class Utilities{
    public static bool validEmail(string email)
    {
        //Your code here
    }
}
2 голосов
/ 05 апреля 2010

Да, дублирование этого кода будет неприятным запахом, вы можете извлечь эти методы в один класс Helper в статических методах или определить класс интерфейса «Validator», и с помощью этого интерфейса вы можете связать различные методы проверки с цепочкой схема ответственности.

1 голос
/ 05 апреля 2010

Вам действительно нужно внимательно изучить методику аспектно-ориентированного программирования (AoP). Корпоративная библиотека 4.1 имеет реализацию AoP, называемую перехватом Unity.

http://msdn.microsoft.com/en-us/library/dd140045.aspx

Эта структура позволяет вам кодировать один класс обработчика для проверки электронной почты. Так что это влечет за собой то, что код проверки входит в класс обработчика, и больше не является частью класса (ов). Следующее, что вы делаете - помечаете классы для перехвата.

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

1 голос
/ 05 апреля 2010

Создайте класс Utility и определите эти методы как методы расширения для соответствующего класса / интерфейсов.

0 голосов
/ 05 апреля 2010

Я бы порекомендовал вам создать интерфейс IValidator, а затем создать несколько разных валидаторов, которые обрабатывают разные сценарии. Вот один пример:

public interface IValidator {
    bool CanValidateType(string type);
    bool Validate(string input);
}

Метод CanValidateType () может быть немного более сложным, но я надеюсь, что вы поняли идею. Это в основном определяет, может ли валидатор обрабатывать предоставленный ввод. Вот пара реализаций:

public class UrlValidator : IValidator {
    bool CanValidateType(string type) {
        return type.ToLower() == "url";
    }

    bool Validate(string input) {
        /* Validate Url */
    }
}

public class EmailValidator : IValidator {
    bool CanValidateType(string type) {
        return type.ToLower() == "email";
    }

    bool Validate(string input) {
        /* Validate Email */
    }
}

Теперь вы будете использовать инъекцию конструктора для внедрения зависимости в ваш класс:

public class SomeSimpleClass {
    private IValidator validator;

    public SomeComplexClass(IValidator validator) {
        this.validator = validator;
    }

    public void DoSomething(string url) {
        if (validator.CanValidateType("url") && 
            validator.Validate(url))
            /* Do something */
    }
}

CanValidateType пригодится, когда у вас есть класс, который может использовать несколько валидаторов. В этом сценарии вы передаете список или массив валидаторов конструктору.

public class SomeComplexClass {
    private List<IValidator> validators;

    public SomeComplexClass (List<IValidator> validators) {
        this.validators = validators;
    }

    public bool ValidateUrl(string url) {
        foreach (IValidator validator in this.validators)
            if (validator.CanValidateType("url"))
                return validator.Validate(url);
        return false;
    }


    public bool ValidateEmail(string email) {
        foreach (IValidator validator in this.validators)
            if (validator.CanValidateType("email"))
                return validator.Validate(email);
        return false;
    }
}

Затем вам нужно будет как-то передать требуемый экземпляр валидатора (ов) вашим классам. Это часто делается с помощью контейнера IoC (например, Castle Windsor) или выполняется самостоятельно.

IValidator emailValidator = new EmailValidator();
IValidator urlValidator = new UrlValidator();
SomeSimpleClass simple = new SomeSimpleClass(urlValidator);
SomeComplexClass complex = new SomeComplexClass(new List<IValidator> { emailValidator, urlValidator });

Вышеприведенный код становится утомительным, и поэтому контейнеры IoC так удобны. С контейнером IoC вы можете сделать что-то вроде следующего:

SomeSimpleClass simple = container.Resolve<SomeSimpleClass>();
SomeComplexClass complex = container.Resolve<SomeComplexClass();

Все отображения интерфейсов выполняются в вашем app.config или web.config.

Вот классное руководство по внедрению зависимостей и контейнеру The Castle Windsor IoC.

0 голосов
/ 05 апреля 2010

Создать Email как отдельный класс.
Используйте Email как свойства / параметры / возвращаемые значения в ваших классах вместо String.
Создайте EmailValidator для проверки строк в качестве адресов электронной почты.
Создайте EmailFactory, который возвращает Email, если передан действующий адрес электронной почты, и NULL, если нет.

(сделать то же самое для веб-сайта).

0 голосов
/ 05 апреля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...