Хорошо, допустим, у меня есть два класса, класс A и класс B. Им обоим нужно выполнить общую операцию, но не имеет смысла, чтобы они оба были производными от одного и того же объекта, поэтому вместо этого мы приступим к составлению. По сути, «имеет» имеет смысл, когда «есть» не имеет.
Теперь каждый из двух классов создает экземпляр этого объекта и использует его для выполнения обычной операции, и все хорошо. Теперь все хорошо.
Проблема возникает, когда каждый из этих двух классов должен представить событие, которое должна вызвать общая процедура. Ооо И что теперь?
Ну, мы могли бы сделать что-то подобное в каждом из двух классов:
public event EventHandler CommonEvent
{
add { theCommonObject.CommonEvent += value; }
remove { theCommonObject.CommonEvent -= value; }
}
Но теперь этот код должен дублироваться в каждом из двух классов, и читатели кода могут быть несколько смущены этим кодом. add
и remove
не очень часто встречающиеся ключевые слова, по крайней мере.
Тем не менее, в обоих классах есть повторяющийся код, и не только это, но это решение не всегда будет работать!
Например, что если theCommonObject
создается локально в одном методе, и его область действия находится только в этом методе.
Что ж, в таком случае мы даже не можем использовать код быстрого доступа, размещенный ранее, и мы должны полностью продублировать код в обоих классах. Мало того, это просто кричит о неуравновешенности, потому что мы просто переоцениваем копию мероприятия для клиентов.
Пример кода, который в этом случае должен дублироваться в каждом классе:
public event EventHandler SomeCommonEvent;
private void SomeMethod()
{
theCommonObject = new theCommonObject();
theCommonObject.DoSomething();
theCommonObject.SomeCommonEvent += thisClass_SomeCommonEvent;
}
private void thisClass_SomeCommonEvent(object sender, EventArgs e)
{
var handler = SomeCommonEvent;
if (handler != null)
{
handler(this, e);
}
}
Как вы можете видеть, в обоих случаях есть дублирующийся код, но во втором - даже больше, потому что объект является локальным для метода, а не для переменной-члена.
Я не могу придумать, как обойти это, кроме использования наследования, но я не думаю, что в этом есть смысл, и многие часто утверждают, что композиция превосходит наследование с точки зрения уменьшения сложности, простоты понимания и так далее.