Я также должен спросить, почему Customer
наследует CustomerValidator
, но также и почему CustomerValidator
абстрактный?Я бы предложил вам изменить интерфейс и реализацию следующим образом:
public interface ICustomerValidator {
void Validate(Customer customer);
}
public abstract class CustomerValidator : ICustomerValidator {
public abstract void Validate(Customer customer);
}
Затем, если вы настаиваете на возможности сделать что-то вроде
Customer customer = new Customer();
customer.Validate();
, я бы предложил вам использовать Методы расширения C # , например:
public static class CustomerExentions {
public static ICustomerValidator CustomerValidator { get; set; }
internal static void Validate(this Customer c) {
if(CustomerValidator == null) {
throw new InvalidOperationException("CustomerValidator cannot be NULL");
}
CustomerValidator.Validate(c);
}
}
Обратите внимание на область действия internal
, чтобы клиенты не могли использовать этот вызов.
Что касается использования композиции, я не думаю, Customer
должен знать что-нибудь о CustomerValidator
или ICustomerValidator
.Эти внешние обязанности выходят за рамки Customer
класса.Во всяком случае, CustomerValidator
может иметь свойство Customer
, если вы настаиваете на использовании композиции, но я думаю, что интерфейс должен принимать вместо него параметр Customer
.