Я использовал троичный оператор в подобных случаях. Это будет выглядеть примерно так:
String oddEven="";
<c:forEach items="${element}" var="myCollection">
oddEven = (oddEven == "even") ? "odd" : "even";
<tr class='"'+oddEven+'"'>
<td><c:out value="${element.field}"/></td>
...
</tr>
</c:forEach>
Вы действительно должны обрабатывать это на уровне приемника, а не на уровне источника. То есть не предписывайте логику обработчика событий в источнике события - оставьте это самим обработчикам (приемникам).
Как разработчик службы, кто вы такой, чтобы утверждать, что приемники могут регистрироваться только один раз? Что, если они по какой-то причине захотят зарегистрироваться дважды? И если вы пытаетесь исправить ошибки в приемниках путем изменения источника, это снова хорошая причина для исправления этих проблем на уровне приемников.
Я уверен, что у вас есть свои причины; источник событий, для которого дублирование приемников недопустимо, не является непостижимым. Но, возможно, вам следует рассмотреть альтернативную архитектуру, которая не затрагивает семантику события.
Это может звучать одинаково, но по-разному, кто говорит, в обоих случаях говорит ваш «мастер-класс», и это имеет значение.
Обратите внимание, что если ваши подчиненные классы имеют метод доступен, который подходит для вызова, когда что-то происходит в вашем мастер-классе, вам не нужно, чтобы подчиненный класс содержал код для его подключения, вы можете так же легко сделать это в своем методе CreateSlaveClass:
SlaveClass sc = new SlaveClass();
ChangeHappenedEvent += sc.ChangeHappened;
return sc;
Это в основном используйте систему событий, но позвольте коду MasterClass выполнять всю проводку событий.
Живут ли объекты SlaveClass столько же, сколько и одноэлементный класс? Если нет, то вам нужно обработать случай, когда они устарели / больше не нужны, как в приведенном выше случае (в основном как в вашем, так и в моем), вы держите ссылку на эти объекты в своем MasterClass, и, следовательно, они никогда не будут иметь право на сборку мусора, если вы не удалите эти события принудительно или не отмените регистрацию интерфейсов.
Чтобы решить проблему с SlaveClass, который не живет так долго, как MasterClass, вы столкнетесь с той же связью проблема, как вы также отметили в комментарии.
Один из способов «обработать» (обратите внимание на кавычки), это могло бы заключаться в том, чтобы на самом деле не связывать напрямую с правильным методом объекта SlaveClass, а вместо этого создать объект-оболочку, который внутренне будет вызовите этот метод. Преимущество этого заключается в том, что объект-оболочка может использовать объект WeakReference внутри, так что, как только ваш объект SlaveClass имеет право на сборку мусора, он может быть собран, а затем в следующий раз, когда вы попытаетесь вызвать для него правильный метод, вы заметили бы это, и, следовательно, вам пришлось бы очистить.
Поскольку у вас, похоже, есть одноэлементный экземпляр MasterClass, почему бы не подписаться на MasterClass.Instance.ChangeHappenedEvent? Это все еще тесная связь, но относительно аккуратная.
I think it's just a matter of personal preference... personnally I like to use events, because it fits better in .NET "philosophy".
In your case, if the MasterClass is a singleton, you don't need to pass it to the constructor of the SlaveClass, since it can be retrieved using the singleton property (or method) :
public SlaveClass ()
{
MasterClass.Instance.ChangeHappenedEvent += ChangeHappened;
}