Абстрактный класс обеспечит сортов того, что код очистки всегда вызывался, и это уменьшает дублирование, так что, на мой взгляд, это лучше, чем ваша существующая структура.Конечно, вы не можете знать, что реализация подкласса disposeManagers
убьет именно тех менеджеров, которые были созданы ранее, - но у вас та же проблема с написанием стандартных finally
блоков.
Я думаю, что я 'Я бы сделал еще один шаг вперед.Во-первых, метод execute
требует, чтобы эти два менеджера выполняли работу, поэтому я бы определил его как
public void execute(HttpServletRequest req, TrafficManager t, CargoManager c);
Теперь давайте предположим, что большинство ваших действий используют одинаковые реализации менеджера.Мы определяем эти методы в суперклассе (но не делаем их окончательными) следующим образом:
public TrafficManager createTrafficManager() { return new TrafficManager(); }
public CargoManager createCargoManager() { return new CargoManager(); }
Так что теперь суперкласс может сам создавать эти экземпляры, вызывая метод и передавая их в execute.И если подклассу нужна реализация, отличная от стандартной, он может переопределить метод по своему усмотрению.
Глядя на очистку - мы могли бы применить аналогичный подход к описанному выше и определить абстрактные реализации.Однако, если менеджерам необходимо очистить , то, вероятно, они реализуют метод close()
или аналогичный.В этом случае мы можем просто вызвать это - что гарантирует, что они будут утилизированы должным образом, независимо от реализаций подклассов, и для try
и finally
невозможно выйти из синхронизации.
Или вы можете просто позвонить removeManager
на каждого, если этого требует ваша логика.(Это может быть улучшено и дальше, но это зависит от семантики этого метода и от того, где он «живет».)
В целом тогда основной код BasicAction выглядит как
BasicAction action = mapping.get(actionName);
// (It's a shame that these need the initial assignment to null due to being
// referenced in the finally block - it's pretty ugly)
TrafficManager tMan = null;
CargoManager cMan = null;
try {
tMan = createTrafficManager();
cMan = createCargoManager();
action.execute(request, tMan, cMan);//Handle the http request from the JSP page
} catch (Exception ex) {
// Handle here any exceptions
} finally {
if (tMan != null) {
removeManager(tMan); // Is this necessary, did it get registered somewhere after creation?
tMan.close(); // If they're closeable
}
if (cMan != null) {
// Of course this block could be a tiny method to further remove duplication,
// so long as you have a common superinterface for both *Manager classes
removeManager(cMan);
cMan.close();
}
}