Využíváte model driven architecture? rubrika: Programování: Jiné

6 kohven
položil/-a 30.6.2015

https://cs.wikipedia.org/wiki/Model_driven_architecture

Jde mi o přehled, na jakých technolgiích to savíte? Co se vám osvědčilo?

Já osobně pracoval na projektu, kde model byl uložen v xml. V modelu nebyl jen popis rozhraní objektů, ale zároveň funkčnost. Objekty neodpovídaly přímo třídám v kódu, ale šablonám, ze kterých se generovaly unikátní nové třídy s již vyplněnýmy metodami. S ručně psaným kódem se to skládalo dědičností nebo pomocí partial class v c#. Model se editoval v našem editoru. Ne jako xml, ale jako sada diagramů a formulářů.

Už ale dělám na jiných projektech a tohle mi přijde jako dost ultimativní řešení. Používáte nějaké již hotové nástroje nebo jednodužší a efektivnější metody MDA?

Edit: 30.6.2015
Ten projekt mi neříká pane a už na něm nepracuji, takže z něho rozhodně nic sdílet nemohu. Ale pro představu jsem načrtl, co se např. mohlo objevovat v modelu. Všechno má výchozí hodnoty/funkčnosti a definuje se jen to, co se nedá předpokládat. Takže např. pokud stačí vkládací formulář vygenerovat jen podle datových položek a nepotřebuji upravovat rozmístění ovl. prvků, tak ho vůbec nedeklaruji a vytvoří se automaticky.

  <screen>
    <name>fakturace</name>
    <master>
      <data-object>invoice</data-object>
    </master>
    <detail>
      <data-object>invoiceItem</data-object>
    </detail>
    <custom-menu>
      <menu-item>
        <name>pingBackground</name>
        <label>Tiskni růžově</label>
        <description>
          Vytiskne zobrazenou fakturu s růžovým pozadím a duhovým jednorožcem jako vodotisk.
        </description>
        <roles>
          <role>barbie</role>                                  
        </roles>
      </menu-item>
    </custom-menu>
  </screen>
 
  <data-object>
    <name>invoice</name>
    <label>Faktura</name>
    <data-item>
      <name>name</name>
      <label>Název</label>
      <data-type>string</data-type>
    </data-item>
    <data-item>
      <name>sumPrice</name>
      <label>Celková cena</label>
      <data-type>computed</data-type>
      <expression><![CDATA[sum(invoiceItem.sumPrice)]]></expression>
    </data-item>
  </data-object>
 
  <data-object>
    <name>invoiceItem</name>
    <label>Položka faktury</name>
    <data-item>
      <name>name</name>
      <label>Název</label>
      <data-type>string</data-type>
    </data-item>
    <data-item>
      <name>quantity</name>
      <label>Počet</label>
      <data-type>float</data-type>
    </data-item>
    <data-item>
      <name>price</name>
      <label>Cena</label>
      <data-type>float</data-type>
    </data-item>
    <data-item>
      <name>sumPrice</name>
      <label>Celková cena</label>
      <data-type>computed</data-type>
      <expression><![CDATA[quantity*price]]></expression>
    </data-item>
    <relation>invoice</relation>
  </data-object>
odkaz
9 Taco
odpověděl/-a 30.6.2015
 
upravil/-a 1.7.2015

Používám něco podobného, jak jsi použil v tom xmlku. Vypíchnul bych pár věcí:

Místo vypisování zkouším používat filtry:
Takže místo:

<domain name="Invoice">
  <entry name="InvoicePreview">
    <field ref="id"/>
    <field ref="price"/>
    <field ref="quantinty"/>
  </entry>
  <entry name="InvoiceFull">
    <field ref="id"/>
    <field ref="price"/>
    <field ref="quantinty"/>
    <field ref="sumPrice"/>
  </entry>
  <entry name="InvoiceNew">
    <field ref="price"/>
    <field ref="quantinty"/>
  </entry>
</domain>

napíšu:

<domain name="Invoice">
  <entry name="%{name}Preview">
    <field-filter type="exclude">sumPrice,created*,updated*</field-filter>
  </entry>
  <entry name="%{name}Full">
    <field-filter type="mask">*</field-filter>
  </entry>
  <entry name="%{name}New">
    <field-filter type="exclude">sumPrice,id,created*,updated*</field-filter>
  </entry>
</domain>

Snažím se rozdělovat definici jednotlivých fieldů, a pak jejich použití u formulářů jen odkazuji. Takže to celé bude vypadat nějak takto:

<domain name="Invoice" namespace="Taco/App">
  <abstract>
    <field name="id" type="%{name}Identification" />
    <field name="price" type="Money" mode="rw">
      <doc>Dokumentační komentář</doc>
    </field>
    <field name="quantinty" type="int" />
    <field name="sumPrice" type="int" />
    <field name="items" type="list:InvoiceItem" mode="rw" />
    <field name="created-by" type="User" />
    <field name="created-when" type="Date" />
    <field name="updated-by" type="User" />
    <field name="updated-when" type="Date" />
  </abstract>
 
  <entry name="%{name}Preview">
    <field-filter type="exclude">sumPrice,created*,updated*</field-filter>
    <field ref="price" mode="r" />
  </entry>
  <entry name="%{name}Full">
    <field-filter type="mask">*</field-filter>
  </entry>
  <entry name="%{name}New">
    <field-filter type="exclude">sumPrice,id,created*,updated*</field-filter>
    <field ref="price">
       <label>Cena</label>
    </field>
  </entry>
 
</domain>

Používám to na vygenerování doménových objektů/entit, ale jak říkám, zatím je to jen taková hračka.

Komentáře

  • kohven : To filtrování vypadá zajímavě. To moje XML vychází z toho, že je editováno vlastním editorem, kde se XML vůbec nezobrazuje. Bylo to tak navrženo, aby to mohli používat analytici, kteří pak za nás dělali půl práce. Takže tam by to filtrování asi úplně neprošlo. Ale dobrý nápad. Jinak fieldy se samozřejmě deklarují jen jednou. Položky formuláře, databázová tabulka a business třída se už nikde znovu nedeklarují. Dá se deklarovat formulář (kvůli rozmístění ovl. prvků), ale jeho položky jsou jen odkazy a rozhodně už se tam nepíše label nebo typ ovládacího prvku. Když se pak položka odkáže v jiném formuláři, tak se pak nemůže stát, že jedna položka je v různých formulářích popsána různými popiskami (pokud si to explicitně nevyžádám). 30.6.2015
  • Kit : @kohven: Je obvyklé, že se taková schémata editují vlastním editorem a XML je jen serializačním formátem. 30.6.2015
  • Kit : @Taco: Podle mne šetříš na nesprávném místě. Raději vyjmenuji platné sloupce než neplatné. Jak definuješ pohledy s JOIN a integritní omezení? 30.6.2015
  • Taco : @kohven: Tak to máme podobné. Labely a další věci se dají přirozeně překrýt novým zněním. Moje vize je taková, že mám nějakou entitu, která má max fieldů (plus různé varianty), ale pak mám něco jako pohledy. Takže třeba vytvoření nového záznamu má jiné položky (nemá updated ani created ani id) než detail záznamu, a aktualizace záznamu má také jiné položky (má id, ale nemá created). A tak jsem se to snažil logicky popsat, tím spíše, že jsem občas pracoval s objektem který měl dvacet záznamů. To už se mi nechtělo vypisovat. 30.6.2015
  • Taco : @Kit: Jo, jenže když se přidržím deklarativního popisu, místo tupého vyjmenování, tak pak při změně báze (přidání, odebrání prvku) bych nemusel upravovat pohledy. Ale samozřejmě je to teorie, a praxe ukáže. 30.6.2015
  • Taco : @Kit: omezení řeším na úrovni typu, plus příznak bound=".+*?". JOINy nedělám, protože ten můj popis je na jiné úrovni. JOIN je imho relační operátor čistě vázanej na rel. databáze, což zatím nepotřebuji (dost si vystačím s algebrou). 30.6.2015
  • kohven : To, že se nemusím starat o views, když odeberu položku z datového objektu, může být dvousečné. Někdy je možná dobré být nucen zrevidovat vše, co mi odebrání položky ovlivní. Záleží případ od případu, ale někdy by to mohlo být nevýhodou. Určitě bych doporučoval přidat možnost psát to i výčtem 1.7.2015
  • Kit : @kohven: Myslím, že to vidím v tom třetím entry, i když místo exclude mělo být asi něco jiného. 1.7.2015
  • Taco : @kohven: Ta možnost _není_ buď a nebo. Klidně to tam můžu vypsat. Já věřím na sémantiku ;-) ale máš pravdu, že se uvidím časem, zda je to ku prospěchu, nebo ku škodě. 1.7.2015
  • Taco : @Kit: Zrovna v tom třetím případě je to "správně", opravdu jsem to myslel jako "všechno krom". Ale otevírají se tam jiné možnost: Zda se ty filtry dají kombinovat a tak. Můžu to navíc zkombinovat, že filtrama si tam vyřadím, nebo zaříadím nějaké elementy (na to stačí jméno), ale pak jim ještě pomocí [field ref="foo"/] doupravím další atributy. 1.7.2015
  • Kit : @Taco: price a quantity v prvním příkladu ve třetím entry máš. Nevylučuješ je. 1.7.2015
  • Taco : @Kit: No, moc ti nerozumím. Ale trošku jsem ten příklad upravil, Třeba to bude jasnější. A chybu jsem tam skutečně měl. V případě nového záznamu tam chci price a nechci priceSum. 1.7.2015
  • Kit : @Taco: InvoiceNew se přece skládá z price a quantity. Tak to máš v prvním příkladu, který už nepoužíváš. < entry name="InvoiceNew"> 1.7.2015
  • Taco : @Kit: ano, to by odpovídalo, takže? 1.7.2015
  • Kit : @Taco: entry name="InvoiceNew" není exclude, ale list, ve kterém jsou položky price a quantity. Úplně na začátku. Ve druhém příkladu máš exclude. Evidentně to není ekvivalentní úprava. 1.7.2015
  • Taco : @Kit: Á druhý příklad. Lepší? 1.7.2015
  • Kit : @Taco: Myslel jsem to sice trochu jinak, ale teď už to sedí a je to tedy OK. 1.7.2015

Pro zobrazení všech 2 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.