У меня есть класс, который при построении загружает информацию из базы данных. Информация может быть изменена, и затем разработчик может вызвать Save() на ней, чтобы сделать ее Сохранить эту информацию обратно в базу данных.
Я также создаю класс, который будет загружаться из базы данных, но не будет допускать никаких обновлений. (версия для чтения). Мой вопрос: должен ли я создать отдельный класс и наследовать, или мне нужно просто обновить существующий объект, чтобы взять параметр readonly в конструкторе, или я должен сделать отдельный класс целиком?
Существующий класс уже используется во многих местах кода.
Спасибо.
Update:
Во-первых, здесь есть много замечательных ответов. Было бы трудно принять только одну. Спасибо всем.
Основные проблемы:
- Соответствие ожиданиям, основанным на именах классов и структурах наследования.
- Предотвращение ненужного дублирующего кода
Кажется, что существует большая разница между Readable и ReadOnly. Класс Readonly, вероятно, не должен быть унаследован. Но класс Readable предполагает, что он может также получить удобочитаемость в какой-то момент.
Итак, после долгих размышлений, вот что я думаю:
public class PersonTestClass
{
public static void Test()
{
ModifiablePerson mp = new ModifiablePerson();
mp.SetName("value");
ReadOnlyPerson rop = new ReadOnlyPerson();
rop.GetName();
//ReadOnlyPerson ropFmp = (ReadOnlyPerson)mp; // not allowed.
ReadOnlyPerson ropFmp = (ReadOnlyPerson)(ReadablePerson)mp;
// above is allowed at compile time (bad), not at runtime (good).
ReadablePerson rp = mp;
}
}
public class ReadablePerson
{
protected string name;
public string GetName()
{
return name;
}
}
public sealed class ReadOnlyPerson : ReadablePerson
{
}
public class ModifiablePerson : ReadablePerson
{
public void SetName(string value)
{
name = value;
}
}
К сожалению, я еще не знаю, как это сделать со свойствами (см. ответ StriplingWarrior для этого, выполненного со свойствами), но у меня есть ощущение, что оно будет включать защищенное ключевое слово и асимметричные модификаторы доступа к свойствам.
Кроме того, к счастью для меня, данные, загружаемые из базы данных, не обязательно должны быть превращены в ссылочные объекты, а простые типы. Это означает, что мне не нужно беспокоиться о том, что люди изменяют членов объекта ReadOnlyPerson
.
Обновление 2:
Обратите внимание, что, как предположил StriplingWarrior, downcasting может привести к проблемам, но это, как правило, верно, поскольку отбрасывание обезьяны и животных обратно на собаку может быть плохим. Однако кажется, что даже при том, что кастинг разрешен во время компиляции, на самом деле он не разрешен во время выполнения.
Класс обёртки также может сделать трюк, но мне это нравится лучше, потому что он позволяет избежать проблемы с глубокой копией переданного в объекте/разрешить изменение переданного объекта, модифицируя класс оболочки.