У меня есть абстрактный класс в библиотеке. Я пытаюсь сделать это как можно проще, чтобы правильно реализовать вывод этого класса. Проблема в том, что мне нужно инициализировать объект в трехэтапном процессе: захватить файл, сделать несколько промежуточных шагов и затем работать с файлом. Первый и последний шаги относятся к производному классу. Вот урезанный пример.Как избежать вызова духовных методов из базового конструктора
abstract class Base
{
// grabs a resource file specified by the implementing class
protected abstract void InitilaizationStep1();
// performs some simple-but-subtle boilerplate stuff
private void InitilaizationStep2() { return; }
// works with the resource file
protected abstract void InitilaizationStep3();
protected Base()
{
InitilaizationStep1();
InitilaizationStep2();
InitilaizationStep3();
}
}
Проблема, конечно же, в вызове виртуального метода в конструкторе. Я боюсь, что потребитель библиотеки окажется ограниченным при использовании класса, если они не могут рассчитывать на полностью инициализированный производный класс.
я мог вытащить логику из конструктора в защищенный Initialize()
метод, но реализатор можно назвать Step1()
и Step3()
непосредственно вместо вызова Initialize()
. Суть проблемы заключается в том, что не было бы очевидной ошибки, если пропускается Step2()
; просто ужасное исполнение в определенных ситуациях.
Я чувствую, что в любом случае существует серьезная и неочевидная «гочка», которую будущие пользователи библиотеки будут работать. Есть ли какой-то другой дизайн, который я должен использовать для достижения такой инициализации?
При необходимости я могу предоставить более подробную информацию; Я просто пытался предоставить простейший пример, который выразил проблему.
Согласен. Другим подходом было бы обслуживание зависимостей, которые этот объект имеет при создании. –
Мне нравится ваше решение, но другой возможностью рассмотреть может быть разбиение кода на шагах 1 и 3 на пару интерфейсов, которые передаются конструктору. Конструктор может позвонить им в нужный момент, чтобы выполнить свою роль. Короче говоря, это вполне может быть одним из тех мест, где композиция превосходит наследование. –
Это не касается его опасений по поводу вызова шагов из последовательности и способа упрощения создания производных классов. – eschneider