Programování

Návrhové vzory, kterým se často vyhýbám: Vzor úložiště

Návrhové vzory poskytují ověřená řešení problémů reálného světa, kterým čelí softwarové návrhy. Vzor úložiště se používá k oddělení obchodní logiky a vrstev přístupu k datům ve vaší aplikaci.

Vrstva pro přístup k datům obvykle obsahuje kód specifický pro úložiště a metody pro práci s daty do az datového úložiště. Vrstva přístupu k datům, kterou úložiště abstraktu může být ORM (tj. Entity Framework nebo NHibernate), soubor XML, webová služba atd. Může to být dokonce kolekce příkazů SQL.

Při použití návrhového vzoru úložiště nemusí vrstva obchodní logiky vaší aplikace mít žádné znalosti o tom, jak se pod datem setrvává. Úložiště v zásadě zprostředkovává mezi doménou a vrstvami mapování dat vaší aplikace. Má vám poskytnout zapouzdření ve způsobu, jakým jsou data ve vrstvě pro ukládání dat skutečně přetrvávána.

Vzor úložiště může být prospěšný, pokud máte mnoho entit a máte mnoho složitých dotazů pro práci s těmito entitami. Extra vrstva abstrakce vám v tomto případě pomůže eliminovat duplikaci logiky dotazu.

Generické úložiště

Obecné úložiště je typ, který se skládá ze sady obecných metod pro provádění operací CRUD. Je to však jen další anti vzor a často se s Entity Framework používá k abstraktnímu volání vrstvy přístupu k datům. Podle mého názoru je použití obecného úložiště příliš generalizace. Je to špatný nápad abstraktní volání Entity Framework pomocí obecného úložiště.

Vysvětlím to na příkladu.

Následující seznam kódů ilustruje obecné úložiště - obsahuje obecné metody pro provádění základních operací CRUD.

veřejné rozhraní IRepository

   {

IEnumerable GetAll ();

T GetByID (int id);

void Přidat (položka T);

void Update (položka T);

void Delete (položka T);

   }

Chcete-li vytvořit konkrétní úložiště, budete muset implementovat obecné rozhraní, jak je uvedeno v seznamu kódů níže.

veřejná třída AuthorRepository: IRepository

   {

// Implementované metody rozhraní IRepository

   }

Jak vidíte, pro vytvoření jakékoli konkrétní třídy úložiště byste museli implementovat každou z metod obecného rozhraní úložiště. Hlavní nevýhodou tohoto přístupu je, že byste museli vytvořit nové úložiště pro každou entitu.

Zde je další nevýhoda tohoto přístupu: Základním záměrem vzoru úložiště je oddělení vaší doménové vrstvy od toho, jak jsou data ve skutečnosti zachována vrstvou pro přístup k datům. Zde je aktualizovaná verze třídy úložiště, kterou jsme právě vytvořili.

veřejná třída AuthorRepository: IRepository

   {

soukromý AuthorContext dbContext;

// Metody rozhraní IRepository

   }

Jak vidíte ve výše uvedeném seznamu kódů, AuthorRepository potřebuje instanci AuthorContext k provádění operací CRUD, pro které je určena. Kde je tedy oddělení? V ideálním případě by doménová vrstva neměla mít žádné znalosti logiky vytrvalosti.

Další vrstva abstrakce

Model domény a model vytrvalosti v aplikaci mají zřetelně odlišné odpovědnosti. Zatímco první modely chování, tj. Modely problémů v reálném životě a řešení těchto problémů, druhé se používá k modelování toho, jak jsou data aplikace ve skutečnosti uložena v úložišti dat.

Záměrem vzoru úložiště by mělo být abstrahování logiky perzistence a skrytí interních implementací toho, jak jsou data zachována. Operace úložiště by měly být dostatečně expresivní a neměly by být obecné. Nemůžete mít úložiště, které je obecné a které může obsahovat operace, které se vejdou do jakéhokoli scénáře. To se stává zbytečnou abstrakcí, a proto se generický vzor úložiště stává anti-vzorem. Všechny své doménové objekty můžete modelovat stejným způsobem. Obecné úložiště nedefinuje smysluplnou smlouvu a znovu byste potřebovali konkrétní úložiště, které rozšiřuje vaše obecné úložiště a poskytuje konkrétní sadu operací, které mají smysl pro konkrétní entitu.

Nyní, když máte kolem sebe několik vyspělých technologií pro persistenci dat (NHibernate, Entity Framework atd.), Proč vlastně potřebujete tuto další vrstvu abstrakce? Většina vyspělých technologií ORM, které jsou dnes k dispozici, mají stejné schopnosti. Při pokusu o použití úložiště stačí bez dalšího důvodu přidat další vrstvu abstrakce. Jako příklad možná budete potřebovat metody, jako je následující, pro váš AuthorRepository.

FindAuthorById ()

FindAuthorByCountry ()

To se zhoršuje, protože máte stále více metod a složitých vyhledávání - skončili byste tím, že budete mít úložiště, které by úzce mapovalo s trvalou vrstvou úložiště, která se používá pod ní.