Vra

Sê jy het'n aansoek verdeel in 3-vlakke:GUI, besigheid logika, en data toegang.In jou besigheid logika laag jy beskryf jou besigheid voorwerpe:getters, etters, accessors, en so aan...jy kry die idee.Die koppelvlak tot die besigheid logika laag waarborg veilige gebruik van die besigheid logika, so al die metodes en accessors jy noem sal die geldigheid van insette.

Hierdie groot wanneer jy die eerste keer skryf die UI-kode, want jy het'n netjies gedefinieer koppelvlak wat jy kan vertrou.

Maar hier kom die moeilike deel, wanneer jy begin met die skryf van die data toegang laag, die koppelvlak tot die besigheid logika nie jou behoeftes akkommodeer.Wat jy nodig het om meer accessors en getters te stel velde wat is/gebruik word om te weggesteek word.Nou is jy gedwing om te erodeer die koppelvlak van jou besigheid logika;nou is dit moontlik stel velde van die UI laag, wat die UI laag het geen besigheid omgewing.

As gevolg van die veranderinge wat nodig is vir die data toegang laag, die koppelvlak tot die besigheid logika het verweer tot die punt waar dit is moontlik om selfs te stel om die besigheid logika met ongeldige data.Dus, die koppelvlak nie waarborg veilige gebruik nie.

Ek hoop ek verduidelik die probleem duidelik genoeg.Hoe kan jy verhoed dat koppelvlak erodeer, in stand te hou die inligting wegkruip en inkapseling, en nog steeds akkommodeer verskillende koppelvlak behoeftes onder verskillende lae?

Was dit nuttig?

Oplossing

As ek die vraag reg verstaan, jy het 'n domein model geskep en jy wil graag 'n objekrelasionele kartograaf skryf na die kaart tussen rekords in die databasis en jou domein voorwerpe. Maar jy bekommerd is oor die besoedeling van jou domein model met die "loodgieter" kode wat nodig sou wees om te lees en skryf na velde jou voorwerp is.

Neem 'n stap terug, jy basies twee keuses van waar om jou data kartering kode sit - binne die domein klas self of in 'n eksterne kartering klas. Die eerste opsie is dikwels genoem die Active Record patroon en het die voordeel dat elke voorwerp weet hoe om self voortduur en het voldoende toegang tot sy interne struktuur om toelaat dat dit die kartering uit te voer sonder om nie-besigheid verwante velde blootstel.

Bv

public class User
{
    private string name;
    private AccountStatus status;

    private User()
    {
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public AccountStatus Status
    {
        get { return status; }
    }

    public void Activate()
    {
        status = AccountStatus.Active;
    }

    public void Suspend()
    {
        status = AccountStatus.Suspended;
    }

    public static User GetById(int id)
    {
        User fetchedUser = new User();

        // Lots of database and error-checking code
        // omitted for clarity
        // ...

        fetchedUser.name = (string) reader["Name"];
        fetchedUser.status = (int)reader["statusCode"] == 0 ? AccountStatus.Suspended : AccountStatus.Active;

        return fetchedUser;
    }

    public static void Save(User user)
    {
        // Code to save User's internal structure to database
        // ...
    }
}

In hierdie voorbeeld het ons 'n voorwerp wat 'n gebruiker met 'n Naam en 'n AccountStatus verteenwoordig. Ons wil nie toelaat dat die Status direk om in te lê, miskien omdat ons wil om te kyk wat die verandering is 'n geldige status oorgang, so ons het nie 'n setter. Gelukkig het die kartering kode in die GetById en Save statiese metodes het volle toegang tot die naam en status velde die voorwerp se.

Die tweede opsie is om 'n tweede klas wat verantwoordelik is vir die kartering het. Dit het die voordeel van verskil tussen Dobby uit die verskillende belange van besigheid logika en volharding wat kan toelaat dat jou ontwerp om meer toetsbaar en buigsaam wees. Die uitdaging met hierdie metode is hoe om die naam en status velde bloot te stel aan die eksterne klas. Sommige opsies is:   1. Gebruik weerspieëling (wat geen probleem het oor die grawe diep in private dele van jou voorwerp)   2. Verskaf spesiaal genoem, openbare etters (bv voorvoegsel hulle met die woord 'Private ") en hoop niemand gebruik dit per ongeluk   3. As jou taal suports dit, maak die opstellers interne maar jou data kartograaf toegang module toestaan. Bv gebruik die InternalsVisibleToAttribute in NET 2.0 en verder of vriend funksies in C ++

Vir meer inligting, sou ek aanbeveel Martin Fowler se klassieke boek 'Patrone van Enterprise Architecture'

Maar as 'n woord van waarskuwing, voordat hulle op die pad van die skryf van jou eie mappers Ek sal sterk aanbeveel op soek na die gebruik van 'n 3de party beswaar relasionele kartograaf (ORM) instrument soos nHibernate of Microsoft se Entity Framework. Ek het op vier verskillende projekte waar, om verskeie redes, ons het ons eie kartograaf gewerk en dit is baie maklik om 'n klomp van die tyd die handhawing en uitbreiding van die kartograaf in plaas van die skryf kode wat eindgebruiker waarde bied mors. Ek het gebruik nHibernate op een projek tot dusver en hoewel dit nogal 'n steil leerkurwe aanvanklik, die belegging wat jy sit in vroeg betaal aansienlik af.

Ander wenke

Dit is 'n klassieke probleem - skeiding jou domein model van jou databasis model. Daar is verskeie maniere om dit aan te val, dit hang af van die grootte van jou projek in my opinie. Jy kan die bron patroon gebruik as ander reeds gesê het. As jy met behulp NET of java kan jy gebruik NHibernate of Hibernate .

Wat ek doen, is gebruik Toets Driven Ontwikkeling so ek my UI en Model skryf lae eerste en die Data laag is gespot, sodat die UI en model is gebou rondom domein spesifieke voorwerpe, dan later het ek karteer hierdie voorwerp wat ooit tegnologie Ek gebruik die die Data Layer. Is 'n baie slegte idee om jou te laat die databasis te bepaal die ontwerp van jou jeug, skryf eers die jeug en dink oor die data later.

ps die titel van die vraag is 'n bietjie mis-lei

@ Ice ^^ Heat:

  

Wat is jou bedoeling met die data vlak nie bewus van die besigheid logika toegeroep moet wees? Hoe sou jy 'n besigheid voorwerp vul met data?

Die UI vra die ServiceClass in die besigheid vlak vir 'n diens, naamlik om 'n lys van voorwerpe gefiltreer deur 'n voorwerp met die nodige parameter data.
Dan skep die ServiceClass 'n geval van een van die repository klasse in die data vlak, en doen 'n beroep die GetList (ParameterType filters).
Dan toegang tot die data toegeroep die databasis, trek die data, en kaarte aan die algemene formaat gedefinieer in die "domein" vergadering.
Die BL het geen werk meer te doen met hierdie inligting, so dit uitset dit aan die UI.

Toe wil die UI om Item X. Dit stuur die item (of besigheid voorwerp) wysig om die diens in die Business Tier. Die maatskappy se vlak bekragtig die voorwerp, en indien dit OK, dit stuur dit na die data vlak vir stoor.

Die UI weet die diens in die besigheid vlak wat weer weet oor die data vlak.

Die UI is verantwoordelik vir die kartering van die gebruikers data insette na en van die voorwerpe, en die data vlak is verantwoordelik vir die kartering van die data in die db na en van die voorwerpe. Die Business vlak bly suiwer besigheid. :)

Dit kan 'n oplossing wees, as dit die koppelvlak nie sou erodeer. Ek dink jy kan 'n klas soos volg:

public class BusinessObjectRecord : BusinessObject
{
}

Ek skep altyd 'n aparte vergadering wat bevat:

  • 'n baie klein Interfaces (dink ICreateRepository, IReadRepository, IReadListRepsitory .. die lys gaan aan en die meeste van hulle afhanklik is van generiese)
  • 'n baie konkrete Interfaces, soos 'n IPersonRepository, wat erf vanaf IReadRepository, kry jy die punt ..
    Enigiets wat jy kan nie beskryf met net die kleiner koppelvlakke, jy sit in die beton koppelvlak.
    Solank as wat jy die IPersonRepository gebruik om jou doel te verklaar, kry jy 'n skoon, konsekwent koppelvlak om te werk met. Maar die skopper is, jy kan ook 'n klas wat f.x. neem 'n ICreateRepository in sy konstruktor, so die kode sal uiteindelik 'n baie maklik om 'n paar regtig funky stuff doen met. Daar is ook koppelvlakke vir die dienste in die besigheid toegeroep hier.
  • Uiteindelik i hou al die domein voorwerpe in die ekstra vergadering, net om die kode basis self 'n bietjie skoner te maak en meer losweg gekoppel. Hierdie voorwerpe hoef nie enige logika, hulle is net 'n algemene manier om die data te beskryf vir al 3+ lae.

Btw. Hoekom sou jy definieer metodes in die besigheid logika toegeroep om die data vlak te akkommodeer?
Die data toegeroep moet geen rede om eens weet daar is 'n besigheid toegeroep het ..

Wat is jou bedoeling met die data vlak nie bewus van die besigheid logika toegeroep moet wees? Hoe sou jy 'n besigheid voorwerp vul met data?

Ek doen dit dikwels:

namespace Data
{
    public class BusinessObjectDataManager
    {
         public void SaveObject(BusinessObject object)
         {
                // Exec stored procedure
         {
    }
}

So die probleem is dat die besigheid laag moet meer funksies bloot te stel aan die data laag, en die toevoeging van hierdie funksies beteken te veel bloot te stel aan die UI laag? As ek jou probleem korrek is verstaan, dit klink soos jy probeer om te veel te bevredig met 'n enkele koppelvlak, en dit is net veroorsaak dat dit te deurmekaar raak. Hoekom nie twee koppelvlakke in die besigheid laag te hê? 'N Mens sou 'n eenvoudige, veilige koppelvlak vir die UI laag wees. Die ander sal 'n laer-koppelvlak vir die data laag wees.

Jy kan hierdie twee-koppelvlak benadering van toepassing op enige voorwerpe wat moet geslaag word om beide die UI en die data lae, ook.

public class BusinessLayer : ISimpleBusiness
{}

public class Some3LayerObject : ISimpleSome3LayerObject
{}

Wil jy dalk jou poorte verdeel in twee tipes, naamlik:

  • View koppelvlakke - wat koppelvlakke wat jou interaksie spesifiseer met jou UI, en is
  • Data koppelvlakke - wat koppelvlakke wat jou sal toelaat om interaksies spesifiseer met jou data is

Dit is moontlik om te erf en te implementeer beide stel koppelvlakke sodanig dat:

public class BusinessObject : IView, IData

Op hierdie manier, in jou data laag hoef jy net die koppelvlak implementering van IData sien, terwyl dit in jou UI jy net nodig het om die koppelvlak implementering van iView sien.

Nog 'n strategie wat jy dalk wil om te gebruik is om jou voorwerpe komponeer in die UI of Data lae sodanig dat hulle bloot vergaan deur hierdie lae, Bv.,

public class BusinessObject : DomainObject

public class ViewManager<T> where T : DomainObject

public class DataManager<T> where T : DomainObject

Dit op sy beurt kan jou besigheid voorwerp onkundig van beide die UI / View laag en die data laag bly.

Ek gaan om voort te gaan my gewoonte om te gaan teen die grein en sê dat jy moet die vraag waarom jy die bou van al hierdie verskriklik komplekse voorwerp lae.

Ek dink baie ontwikkelaars dink van die databasis as'n eenvoudige volharding laag vir hul voorwerpe, en is slegs gemoeid met die CRUD bedrywighede wat die voorwerpe nodig het.Te veel moeite is om te sit in die "impedence mismatch" tussen die voorwerp en die relasionele modelle.Hier is'n idee:ophou probeer.

Skryf gestoor prosedures te omsluit jou data.Gebruik die resultate stelle, DataSet, DataTable, SqlCommand (of die java/php/wat ook al ekwivalent) as wat nodig is van die kode om met die databasis.Jy hoef nie die voorwerpe.'n uitstekende voorbeeld is die inbedding van'n SqlDataSource in'n .ASPX bladsy.

Jy moet nie probeer om weg te steek van jou data van iemand.Ontwikkelaars nodig het om te verstaan presies hoe en wanneer hulle interaksie met die fisiese data stoor.

Voorwerp-relasionele mappers is die duiwel.Ophou met behulp van hulle.

Gebou onderneming aansoeke is dikwels'n oefening in die bestuur kompleksiteit.Jy het om dinge te hou so eenvoudig as moontlik, of sal jy het'n absoluut vn-stelsel te onderhou.As jy bereid is om te laat'n paar koppeling (wat inherent in enige aansoek in elk geval), jy kan weg te doen met beide van jou besigheid logika laag en jou data toegang laag (vervang hulle met gestoor prosedures), en jy sal nie nodig het om enige van diegene koppelvlakke.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top