Відображення із наслідуванням (шаблон проєктування) — Вікіпедія
Відображення із наслідуванням (англ. Inheritance Mappers) — шаблон проєктування, який описую структуру класів відображення ієрархії наслідування.
Опис[ред. | ред. код]
При роботі із ієрархією об'єктів, які реалізують наслідування, необхідно зменшити об'єм коду, який використовується для запису і читання зі сховища, а також надати абстрактні та конкретні методи для роботи із даними.
Не зважаючи на те який спосіб наслідування реалізований зі сховищем (або образу декілька) опишемо структуру яка однакова для всіх.
Реалізація[ред. | ред. код]
Нехай дана ієрархія об'єктів.
public class Player { public string Name { get; set; } } class Footballer : Player { public string Club { get; set; } } class Cricketer : Player { public int BattingAverage { get; set; } }
Опишемо абстрактний клас для відображення зі структури в пам'яті до доменного об'єкта.
internal class AbstractMapper { public object Find(int id) { var row = FindRow(id); var domainObject = CreateDomainObject(); return PopulateDomainObject(row, domainOjbect); } public void Insert(object domainObject) { var dataObject = CreateDataObject(); var row = PopulateTableObject(domainObject, dataObject); db.Insert(row); } public void Update(object domainObject) { var id = GetId(domainObject); var dataObject = FindRow(); var row = PopulateTableObject(domainObject, dataObject); db.Update(row); } public void Delete(object domainObject) { var row = FindRow(id); db.Delete(row); } protected abstract object GetId(object domainObject); protected abstract object FindRow(int id); protected abstract object CreateDomainObject(); protected abstract object CreateDataObject(); protected abstract object PopulateDomainObject(object row, object domainObject); protected abstract object PopulateTableObject(object domainObject, object tableObject); }
Кожний клас ієрархії повинний реалізувати свою логіку відображення.
internal class PlayerMapper : AbstractMapper { protected object FindRow(int id) { return db.Find(id) as PlayerTable; } protected object CreateDomainObject(int id) { return new Player(); } protected object PopulateDomainObject(object row, object domainObject) { var playerDataRow = row as PlayerTable; var playerDomainObject = domainObject as Player; playerDomainObject.Name = playerDataRow.Name; return playerDomainObject; } . . . }
Класи відображення наслідують у тому ж порядку, що і оригінальна ієрархія та при потребі перевикористовують логіку.
internal class FootballerMapper : PlayerMapper { protected override object PopulateDomainObject(object row, object domainObject) { var footballerDataRow = base.PopulateDomainObject(row, domainObject) as FootballerMapper; footballerDataRow.Name = (row as FootballerTable).Club; return footballerDataRow; } . . . }
Заховаємо вищеописані класи за фасадом, який буде доступний користувачу.
class Mapper { private Dictionary<Type, AbstractMapper> mappers = new Dictionary<Type, AbstractMapper>(); // метод реєстрації класів відображення public void RegisterMapper(Type type, AbstractMapper mapper) { mappers[type] = mapper; } private AbstractMapper GetMapper(object domainObject) { return mappers[domainObject.GetType()]; } public object Find(int id) { foreach (var mapper in mappers.Values) { var domainObject = mapper.Find(id); if (domainObject != null) return domainObject; } } public void Insert(object domainObject) { // делегуємо роботу відповідним класам відображення GetMapper(domainObject).Insert(domainObject); } public void Update(object domainObject) { GetMapper(domainObject).Update(domainObject); } public void Delete(object domainObject) { GetMapper(domainObject).Delete(domainObject); } }
Див. також[ред. | ред. код]
- Успадкування (програмування)
- Наслідування з однією таблицею
- Наслідування з таблицею для кожного класу
- Наслідування з таблицею для кожного конкретного класу
Джерела[ред. | ред. код]
- Inheritance Mappers [Архівовано 9 серпня 2020 у Wayback Machine.]