Целесообразно ли вызывать абстрактные методы из метода в этом абстрактном классе
Я долго об этом думал.
Я должен выполнить этот процесс -
process(){
bool allow=checkForPermission();
if(allow) {
processRequest();
}
sendResponse();
}
Теперь я создал абстрактный класс X с тремя абстрактными методами:
abstract class X {
public abstract sendResponse();
public abstract checkPermission();
public abstract sendResponse();
public abstract example(); // some example which is called from sendResponse() from where it is implemented.
public void process() {
bool allow=checkForPermission();
if(allow) {
processRequest();
}
sendResponse();
}
}
Класс А расширяет X; это где я не уверен. Когда A реализует все абстрактные методы, а в методе sendResponse() он вызывает функцию IfError(), это хороший дизайн?
Мой друг предлагает следующее: его подобный компилятор сначала вызовет X.process(), затем - к реализованным методам A, и снова A - X (где sendResponse() будет вызывать метод example ()), что, как сказал мой друг, не является хорошим дизайном:
X obj = new A();
obj.process();
Это будет хороший дизайн?
2 ответа
Это в основном нормально, за исключением некоторых моментов:
- если абстрактные методы должны вызываться только изнутри
process()
метод, а не независимо от любого другого внешнего класса, то они должны быть защищены, а не публично. - если подклассы не должны изменить реализацию
process()
потому что каждый процесс должен следовать этому шаблону, тоprocess()
метод должен быть окончательным - если
example()
метод не должен вызываться из внешнего класса, но только как часть реализации sendResponse() в подклассах, тогда у него нет причин существовать в базовом классе.sendResponse()
уже является абстрактным, и, таким образом, подкласс свободен реализовать его так, как он хочет. Таким образом, заставляя его также реализоватьexample()
метод, который нигде не используется, бесполезен.
Это приемлемый шаблон, хотя иногда он указывает на то, что вы смешиваете реализацию с интерфейсом.
Вместо этого может быть лучше иметь два или более классов / интерфейсов и класс "драйвера":
class DriverX {
RequestProcessor requestProcessor;
ResponseSender responseSender;
PermissionChecker permissionChecker;
public void process() {
if (permissionChecker.checkPermission()) {
requestProcessor.processRequest();
}
responseSender.sendResponse();
}
}
Где ссылочные типы являются интерфейсами.
Это обеспечивает четкое разделение обязанностей. Это облегчает модульное тестирование, упрощает документирование, делает его более гибким (если проверка разрешений может отличаться, но отправитель ответа может использоваться повторно).