У меня есть абстрактный класс в библиотеке. Я пытаюсь максимально упростить правильную реализацию производной от этого класса. Проблема в том, что мне нужно инициализировать объект в три этапа: взять файл, сделать несколько промежуточных шагов, а затем работать с файлом. Первый и последний шаг относятся к производному классу. Вот урезанный пример.
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()
; просто ужасная производительность в определенных ситуациях.
Я чувствую, что в любом случае есть серьезная и неочевидная "ошибка", с которой будущим пользователям библиотеки придется обходиться. Есть ли какой-то другой дизайн, который я должен использовать для достижения такой инициализации?
Я могу предоставить более подробную информацию, если это необходимо; Я просто пытался привести самый простой пример, который выразил проблему.