Übersetzung vorschlagen
 
Andere Vorschläge:

progress indicator
Keine anderen Vorschläge
MSDN Magazin > Home > Ausgaben > 2009 > MSDN Magazin August 2009 >  Cutting Edge: Für und Wider von Datentransferob...
Inhalt anzeigen:  Englisch mit deutscher ÜbersetzungInhalt anzeigen: Englisch mit deutscher Übersetzung
Dies sind maschinell übersetzte Inhalte, die von den Mitgliedern der Community bearbeitet werden können. Sie können die Übersetzung verbessern, indem Sie auf den jeweils zum Satz gehörenden Link "Bearbeiten" klicken.Mithilfe des Dropdown-Steuerelements "Inhalt anzeigen" links oben auf der Seite können Sie zudem bestimmen, ob nur der englische Originaltext, nur die deutsche Übersetzung oder beides nebeneinander angezeigt werden.
Cutting Edge
Pros and Cons of Data Transfer Objects
Dino Esposito
Nearly every developer and architect would agree on the following, though relatively loose, definition of the business logic layer (BLL) of a software application: The BLL is the part of the software application that deals with the performance of business-related tasks. Code in the BLL operates on data that attempts to model entities in the problem domain—invoices, customers, orders, and the like. Operations in the BLL attempt to model business processes.
Under the hood of this largely accepted definition lie a number of key details that are left undefined and unspecified. Design patterns exist to help architects and code designers transform loose definitions into blueprints. In general, BLL design patterns have a slightly different focus. They model operations and data and often serve as the starting point for designing the BLL.
In this article, after a brief refresher on procedural and object-based patterns for organizing the BLL, I'll focus on one side of the problem—data transfer objects—that if not effectively addressed at the architecture level, may have a deep impact on the development of the project.

Procedural Patterns for BLL
When it comes to designing the BLL, you can start from the use-cases that have emerged during the analysis phase. Typically, you end up coding one method for each required interaction between the user and the system. Each interaction forms a logical transaction that includes all due steps—from collecting input to performing the task, and from database access to refreshing the user interface. This approach is referred to as the Transaction Script (TS) pattern.
In TS, you focus on the required actions and don't really build a conceptual model of the domain as the gravitational center of the application.
To move data around, you can use any container objects that may suit you. In the Microsoft .NET space, this mostly means using ADO.NET data containers such as DataSets and DataTables. These objects are a type of super-array object, with some search, indexing, and filtering capabilities. In addition, DataSets and DataTables can be easily serialized across tiers and even persisted locally to enable offline scenarios.
The TS pattern doesn't mandate a particular model for data representation (and doesn't prevent any either). Typically, operations are grouped as static methods in one or more entry-point classes. Alternatively, operations can be implemented as commands in a Command pattern approach. Organization of data access is left to the developer and typically results in chunks of ADO.NET code.
The TS pattern is fairly simple to set up; at the same time, it obviously doesn't scale that well, as the complexity of the application grows. In the .NET space, another pattern has gained wide acceptance over the years: the Table Module pattern. In a nutshell, the Table Module pattern suggests a database-centric vision of the BLL. It requires you to create a business component for each database table. Known as the table module class, the business component packages the data and behavior together.
In the Table Module pattern, the BLL is broken into a set of coarse-grained components, each representing an entire database table. Being strictly table-oriented, the Table Module pattern lends itself to using recordset-like data structures for passing data around. ADO.NET data containers or, better yet, customized and typed version of ADO.NET containers are the natural choice.
As the need for a more conceptual view of the problem domain arises, the BLL patterns that have worked for years in the .NET space need to evolve some more. Architects tend to build an entity/relationship model that represents the problem domain and then look at technologies like LINQ-to-SQL and Entity Framework as concrete tools to help.

Object-Based Patterns for BLL
The Table Module pattern is based on objects, but it's not really an object-based pattern for modeling the business logic. It does have objects, but they are objects representing tables, not objects representing the domain of the problem.
In an object-oriented design, the business logic identifies entities and expresses all of the allowed and required interactions between entities. In the end, the application is viewed as a set of interrelated and interoperating objects. The set of objects mapping to entities, plus some special objects performing calculations form the domain model. (In the Entity Framework, you express the domain model using the Entity Data Model [EDM].)
There are various levels of complexity in a domain model that suggest different patterns—typically the Active Record pattern or the Domain Model pattern. A good measure of this complexity is the gap between the entity model you have in mind and the relational data model you intend to create to store data. A simple domain model is one in which your entities map closely to tables in the data model. A not-so-simple model requires mapping to load and save domain objects to a relational database.
The Active Record pattern is an ideal choice when you need a simple domain model; otherwise, when it is preferable to devise entities and relationships regardless of any database notion, the Domain Model pattern is the way to go.
The Active Record pattern is similar to what you get from a LINQ-to-SQL object model (and the defaultgenerated model with the Entity Designer in the Entity Framework Version 1.0). Starting from an existing database, you create objects that map a row in a database table. The object will have one property for each table column of the same type and with the same constraints. The original formulation of the Active Record pattern recommends that each object makes itself responsible for its own persistence. This means that each entity class should include methods such as Save and Load. Neither LINQ-to-SQL nor Entity Framework does this though, as both delegate persistence to an integrated O/RM infrastructure that acts as the real data access layer, as shown in Figure 1.
Figure 1 A Layered Architecture – the Domain Model Pattern Used for the BLL

The Service Layer
In Figure 1, you see a logical section of the BLL named as the "service layer" sitting in between the presentation layer and the layer that takes care of persistence. In a nutshell, the service layer defines an interface for the presentation layer to trigger predefined system actions. The service layer decouples presentation and business logic and represents the façade for the presentation logic to call into the BLL. The service layer does its own job, regardless of how the business logic is organized internally.
As a .NET developer, you are quite familiar with event handlers in Web or Windows forms. The canonical Button1_Click method belongs to the presentation layer and expresses the system's behavior after the user has clicked a given button. The system's behavior—more exactly, the use case you're implementing—may require some interaction with BLL components. Typically, you need to instantiate the BLL component and then script it. The code necessary to script the component may be as simple as calling the constructor and perhaps one method. More often, though, such code is fairly rich with branches, and may need to call into multiple objects or wait for a response. Most developers refer to this code as application logic. Therefore, the service layer is the place in the BLL where you store application logic, while keeping it distinct and separate from domain logic. The domain logic is any logic you fold into the classes that represent domain entities.
In Figure 1, the service layer and domain model blocks are distinct pieces of the BLL, although they likely belong to different assemblies. The service layer knows the domain model and references the corresponding assembly. The service layer assembly, instead, is referenced from the presentation layer and represents the only point of contact between any presentation layer (be it Windows, Web, Silverlight, or mobile) and the BLL. Figure 2 shows the graph of references that connect the various actors. The service layer is a sort of mediator between the presentation layer and the rest of the BLL. As such, it keeps them neatly separated but loosely coupled so that they are perfectly able to communicate. In Figure 2, the presentation layer doesn't hold any reference to the domain model assembly. This is a key design choice for most layered solutions.
Figure 2 Graph of References Between Participant Actors

Introducing Data Transfer Objects
When you have a domain-based vision of the application, you can't help but look seriously into data transfer objects. No multitier solution based on LINQ to SQL or Entity Framework is immune from this design issue. The question is, how would you move data to and from the presentation layer? Put another way, should the presentation layer hold a reference to the domain model assembly? (In an Entity Framework scenario, the domain model assembly is just the DLL created out of the EDMX file.)
Ideally, the design should look like Figure 3, where made-to-measure objects are used to pass data from the presentation layer to the service layer, and back. These ad hoc container objects take the name of Data Transfer Objects (DTOs).
Figure 3 Communication Between Presentation Layer and Service Layer
A DTO is nothing more than a container class that exposes properties but no methods. A DTO is helpful whenever you need to group values in ad hoc structures for passing data around.
From a pure design perspective, DTOs are a solution really close to perfection. DTOs help to further decouple presentation from the service layer and the domain model. When DTOs are used, the presentation layer and the service layer share data contracts rather than classes. A data contract is essentially a neutral representation of the data that interacting components exchange. The data contract describes the data a component receives, but it is not a system-specific class, like an entity. At the end of the day, a data contract is a class, but it is more like a helper class specifically created for a particular service method.
A layer of DTOs isolates the domain model from the presentation, resulting in both loose coupling and optimized data transfer.

Other Benefits of DTOs
The adoption of data contracts adds a good deal of flexibility to the service layer and subsequently to the design of the entire application. For example, if DTOs are used, a change in the requirements that forces a move to a different amount of data doesn't have any impact on the service layer or even the domain. You modify the DTO class involved by adding a new property, but leave the overall interface of the service layer intact.
It should be noted that a change in the presentation likely means a change in one of the use cases and therefore in the application logic. Because the service layer renders the application logic, in this context a change in the service layer interface is still acceptable. However, in my experience, repeated edits to the service layer interface may lead to the wrong conclusion that changes in the domain objects—the entities—may save you further edits in the service layer. This doesn't happen in well-disciplined teams or when developers have a deep understanding of the separation of roles that exists between the domain model, the service layer, and DTOs.
As Figure 4 shows, when DTOs are employed, you also need a DTO adapter layer to adapt one or more entity objects to a different interface as required by the use case. In doing so, you actually implement the "Adapter" pattern—one of the classic and most popular design patterns. The Adapter pattern essentially converts the interface of one class into another interface that a client expects.
Figure 4 DTO Adapters in the BLL
With reference to Figure 4, the adapter layer is responsible for reading an incoming instance of the OperationRequestDTO class and for creating and populating fresh instances of OperationResponseDTO.
When requirements change and force changes in a DTO-based service layer, all you need to do is update the public data contract of the DTO and adjust the corresponding DTO adapter.
The decoupling benefits of DTOs don't end here. In addition, to happily surviving changes in the presentation, you can enter changes to the entities in the domain model without impacting any clients you may have.
Any realistic domain model contains relationships, such as Customer-to-Orders and Order-to-Customer, that form a double link between Customer and Order entities. With DTOs, you also work around the problem of managing circular references during the serialization of entity objects. DTOs can be created to carry a flat stream of values that, if needed, serialize just fine across any boundaries. (I'll return to this point in a moment.)

Drawbacks of DTOs
From a pure design perspective, DTOs are a real benefit, but is this theoretical point confirmed by practice, too? As in many architecture open points, the answer is, it depends.
Having hundreds of entities in the domain model is definitely a good reason for considering alternatives to a pure DTO-based approach. In large projects with so many entities, DTOs add a remarkable level of (extra) complexity and work to do. In short, a pure, 100% DTO solution is often just a 100 percent painful solution.
While normally the complexity added to a solution by DTOs is measured with the cardinality of the domain model, the real number of needed DTOs can be more reliably determined looking at the use cases and the implementation of the service layer. A good formula for estimating how many DTOs you need is to look at the number of methods in the service layer. The real number can be smaller if you are able to reuse some DTOs across multiple service layer calls, or higher if your DTOs group some data using complex types.
In summary, the only argument against using DTOs is the additional work required to write and manage the number of resulting DTO classes. It is not, however, a simple matter of a programmer's laziness. In large projects, decoupling presentation from the service layer costs you hundreds of new classes.
It should also be noted that a DTO is not simply a lightweight copy of every entity you may have. Suppose that two distinct use cases require you to return a collection of orders—say, GetOrdersByCountry and GetOrdersByCustomer. Quite likely, the information to put in the "order" is different. You probably need more (or less) details in GetOrdersByCustomer than in GetOrdersByCountry. This means that distinct DTOs are necessary. For this reason, hundreds of entities are certainly a quick measure of complexity, but the real number of DTOs can be determined only by looking at use cases.
If DTOs are not always optimal, what would be a viable alternate approach?
The only alternative to using DTOs is to reference the domain model assembly from within the presentation layer. In this way though, you establish a tight coupling between layers. And tightly coupled layers may be an even worse problem.

Referencing Entities Directly
A first, not-so-obvious condition to enable the link of entities directly from the presentation layer is that it is acceptable for the presentation layer to receive data in the format of entity objects. Sometimes the presentation needs data formatted in a particular manner. A DTO adapter layer exists to just massage data as required by the client. If you don't use DTOs though, the burden of formatting data properly must be moved onto the presentation layer. In fact, the wrong place in which to format data for user interface purposes is the domain model itself.
Realistically, you can do without DTOs only if the presentation layer and the service layer are co-located in the same process. In this case, you can easily reference the entity assembly from within both layers without dealing with thorny issues such as remoting and data serialization. This consideration leads to another good question: Where should you fit the service layer?
If the client is a Web page, the service layer is preferably local to the Web server that hosts the page. In ASP.NET applications, the presentation layer is all in code-behind classes and lives side by side with the service layer in the same AppDomain. In such a scenario, every communication between the presentation layer and the service layer occurs in-process and objects can be shared with no further worries. ASP.NET applications are a good scenario where you can try a solution that doesn't use the additional layer of DTOs.
Technology-wise, you can implement the service layer via plain .NET objects or via local Windows Communication Foundation (WCF) services. If the application is successful, you can easily increase scalability by relocating the service layer to a separate application server.
If the client is a desktop application, then the service layer is typically deployed to a different tier and accessed remotely from the client. As long as both the client and remote server share the same .NET platform, you can use remoting techniques (or, better, WCF services) to implement communication and still use native entity objects on both ends. The WCF infrastructure will take care of marshaling data across tiers and pump it into copies of native entities. Also, in this case you can arrange an architecture that doesn't use DTOs. Things change significantly if the client and server platforms are incompatible. In this case, you have no chances to link the native objects and invoke them from the client; subsequently, you are in a pure service-oriented scenario and using DTOs is the only possibility.

The Middle Way
DTOs are the subject of an important design choice that affects the implementation of any communication between the presentation and the back end of the system.
If you employ DTOs, you keep the system loosely coupled and open toward a variety of clients. DTOs are the ideal choice, if you can afford it. DTOs add a significant programming overhead to any real-world system. This doesn't mean that DTOs should not be used, but they lead to a proliferation of classes that can really prefigure a maintenance nightmare in projects with a few hundred entity objects and even more use cases.
If you are at the same time a provider and consumer of the service layer, and if you have full control over the presentation, there might be benefits in referencing the entity model assembly from the presentation. In this way, all methods in the service layer are allowed to use entity classes as the data contracts of their signatures. The impact on design and coding is clearly quite softer.
Whether to use DTOs or not is not a point easy to generalize. To be effective, the final decision should always be made looking at the particulars of the project. In the end, a mixed approach is probably what you'll be doing most of the time. Personally, I tend to use entities as much as I can. This happens not because I'm against purity and clean design, but for a simpler matter of pragmatism. With an entity model that accounts for only 10 entities and a few use cases, using DTOs all the way through doesn't pose any significant problem. And you get neat design and low coupling. However, with hundreds of entities and use cases, the real number of classes to write, maintain, and test ominously approaches the order of thousands. Any possible reduction of complexity that fulfills requirements is more than welcome.
As an architect, however, you should always be on the alert to recognize signs indicating that the distance between the entity model and what the presentation expects is significant or impossible to cover. In this case, you should take the safer (and cleaner) route of DTOs.

Mixed Approach
Today's layered applications reserve a section of the BLL to the service layer. The service layer (also referred to as the application layer) contains the application logic; that is, the business rules and procedures that are specific to the application but not to the domain. A system with multiple front ends will expose a single piece of domain logic through entity classes, but then each front end will have an additional business layer specific to the use cases it supports. This is what is referred to as the service (or application) layer.
Triggered from the UI, the application logic scripts the entities and services in the business logic. In the service layer, you implement the use cases and expose each sequence of steps through a coarse-grained method for the presentation to call.
In the design of the service layer, you might want to apply a few best practices, embrace service-orientation, and share data contracts instead of entity classes. While this approach is ideal in theory, it often clashes with the real world, as it ends up adding too much overhead in projects with hundreds of entities and use cases.
It turns out that a mixed approach that uses data contracts only when using classes is not possible, is often the more acceptable solution. But as an architect, you must not make this decision lightly. Violating good design rules is allowed, as long as you know what you're doing.

Send your questions and comments for Dino to cutting@microsoft.com.

Dino Esposito is an architect at IDesign and co-author of Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008). Based in Italy, Dino is a frequent speaker at industry events worldwide. You can join his blog at weblogs.asp.net/despos.

Innovationen
Für und Wider von Datentransferobjekten
Dino Esposito
Fast alle Entwickler und Architekten würden die folgenden übereinstimmen. jedoch relativ verloren, die Geschäftslogikschicht (BLL) einer Softwareanwendung Definition: Die BLL ist der Teil der Softwareanwendung, die mit der Leistung von Business-Aufgaben umgeht. Code in die BLL bezieht sich auf Daten, die versucht Modell Entitäten in der Problemdomäne – Rechnungen, Kunden, Bestellungen und Ähnliches. Vorgänge in der BLL versucht, Geschäftsprozesse zu gestalten.
Hinter den Kulissen dieser weitgehend akzeptierte Definition liegen eine Reihe von Schlüssel Details, die nicht definiert und nicht angegeben. Entwurfsmuster vorhanden sein, Architekten und Code Designer lose Definitionen in Blaupausen zu transformieren. Im Allgemeinen haben BLL Entwurfsmuster ein etwas anderes Ziel. Diese Vorgänge und Daten modellieren und häufig als Ausgangspunkt für das Entwerfen der BLL dienen.
In diesem Artikel nach eine kurze Aktualisierungsprogramm auf Verfahrensweisen und objektbasierten Muster zum Organisieren der BLL ich konzentriere auf einer Seite der das Problem – Datenübertragung Objekte –, wenn nicht effektiv auf der Ebene Architektur behandelt möglicherweise tief Auswirkungen auf die Entwicklung des Projekts.

Verfahrensinformationen Mustern für BLL
Wenn es die BLL entwerfen geht, können Sie aus der Anwendungsfälle starten, die während der Analysephase entwickelt haben. In der Regel erhalten Sie codieren eine Methode für jede erforderliche Interaktion zwischen Benutzer und das System. Jede Interaktion eine logische Transaktion, die alle enthält Formulare fällig Schritte – von Eingaben für die Aufgabe sammeln und Datenbankzugriff auf die Benutzeroberfläche aktualisieren. Dieser Ansatz wird das Muster Transaktion Script (TS) genannt.
In TERMINALDIENSTE die erforderlichen Aktionen konzentrieren und nicht wirklich als gravitational Mittelpunkt der Anwendung erstellen Sie ein konzeptionelles Modell der Domäne.
Um Daten zu verschieben, können Sie keine Containerobjekte, die Sie anpassen können. Im Bereich Microsoft .NET bedeutet dies hauptsächlich mithilfe von ADO.NET Daten Containern wie DataSets und Datentabellen. Diese Objekte sind eine Art von Super-array-Objekt, mit einigen Suche, Indizierung und Filterfunktionen. Darüber hinaus werden lokal Offlineszenarios aktivieren DataSets und Datentabellen über Schichten hinweg leicht serialisiert und auch beibehalten.
Das TERMINALDIENSTE-Muster nicht vorschreiben ein bestimmtes Modells für die Darstellung der Daten (und keine entweder verhindern). Vorgänge werden in der Regel als statische Methoden in einem oder mehreren Entry-Point-Klassen gruppiert. Alternativ können Vorgänge wie Befehle in einem Befehl Muster Ansatz implementiert werden. Organisation der Zugriff auf Daten ist für den Entwickler links und führt normalerweise in Blöcken mit ADO.NET Code.
Das TERMINALDIENSTE-Muster ist relativ einfach einzurichten;zur gleichen Zeit es offensichtlich nicht skalieren, gut, wächst die Komplexität der Anwendung. Im Bereich .NET verfügt über ein weiteres Muster Breite Akzeptanz im Laufe der Jahre gewonnen: die Tabelle Module-Muster. Kurz gesagt, schlägt das Tabelle Module Muster eine Datenbank-zentrierte Vision der BLL. Es müssen Sie eine Geschäftskomponente für jede Datenbanktabelle zu erstellen. Die Tabellenklasse Modul genannt, Pakete die Geschäftskomponente die Daten und das Verhalten zusammen.
In der Tabelle Module-Muster wird die BLL in eine Reihe von grobe Komponenten jeweils eine gesamte Datenbanktabelle darstellen aufgeteilt. Tabelle Module Muster eignet sich zur Verwendung von Recordset-ähnliche Datenstrukturen zum Übergeben von Daten streng von der Tabelle ausgerichtet wird, ist. ADO.NET Datencontainer oder, besser noch, angepasste und typisierte Version von ADO.NET Container sind die natürliche Wahl.
Die Notwendigkeit einer mehr Konzeptansicht des Problemdomäne auftritt, müssen die BLL Muster, die für die Jahre im Bereich .NET gearbeitet haben einige mehr weiterentwickelt. Architekten meist ein Entität-Beziehung Modell, das die Problemdomäne darstellt, und betrachten Sie Technologien wie LINQ-SQL und Entity Framework als konkrete Tools zur Unterstützung.

Objekt-basierten Mustern für BLL
Das Tabelle Module Muster basiert auf Objekte, aber ist nicht wirklich ein objektbasierte Muster für die Modellierung der Geschäftslogik. Verfügt über Objekte, aber Sie sind Objekten, die Tabellen, keine Objekte, die Domäne des Problems darstellt, darstellen.
Die Geschäftslogik in einem objektorientierten Entwurf Entitäten identifiziert und all die zugelassenen und erforderlichen Interaktionen zwischen Entitäten ausdrückt. Am Ende ist die Anwendung als eine Reihe von miteinander und interoperating Objekten angezeigt. Der Satz von Objekten, die Zuordnung zu Entitäten sowie einige besondere Objekte durchführen von Berechnungen Formular des Domänenmodells. (In der Entity Framework, bringen Sie das Domänenmodell mit dem Entitätsdatenmodell [EDM].)
Stehen verschiedene Stufen von Komplexität in einem Domänenmodell, die unterschiedliche Muster vorgeschlagen – normalerweise das Muster Active Datensatz oder das Domänenmodell Muster. Ein gutes Maß dieser Komplexität ist die Lücke zwischen Entitätsmodell, das Sie Bedenken haben und das relationale Datenmodell, das Sie zum Speichern von Daten erstellen möchten. Ein einfaches Domänenmodell ist eine in dem sich Ihre Entitäten zu Tabellen in das Datenmodell eng zuordnen. Ein Modell nicht so einfach ist erforderlich, zuordnen zu laden und Domänenobjekte in einer relationalen Datenbank speichern.
Das Muster Active Datensatz ist ideale Wahl, wenn Sie ein einfaches Domänenmodell;Wenn Entitäten und Beziehungen unabhängig von der alle Datenbank-Konzept entwickeln vorzuziehen ist, ist das Domänenmodell Muster andernfalls die Möglichkeit zum wechseln.
Das Muster Active Datensatz ähnelt der erhalten Sie von einer LINQ-SQL-Objektmodell (und das Defaultgenerated-Modell mit Entity-Designer in Entity Framework Version 1.0). Von einer vorhandenen Datenbank beginnen, erstellen Sie Objekte, die eine Zeile in einer Datenbanktabelle zugeordnet. Das Objekt wird eine Eigenschaft für jede Tabellenspalte des gleichen Typs und mit den gleichen Einschränkungen verfügen. Die ursprüngliche Formulierung des Musters Active Datensatz empfiehlt, dass jedes Objekt selbst für eigene Dauerhaftigkeit verantwortlich ist. Dies bedeutet, dass jede Entitätsklasse Methoden enthalten soll wie speichern und laden. Weder LINQ-SQL noch Entity Framework wird jedoch als beides delegieren Dauerhaftigkeit zu einer integrierten O-RM-Infrastruktur, die als der echte Datenzugriffsschicht fungiert, wie dargestellt im Abbildung 1.
Abbildung 1 A Layered Architektur – das Domänen Modell Muster für die der BLL

-Dienstschicht
In Abbildung 1 wird ein logischen Abschnitt die BLL Namens als "Dienstebene"sitzen zwischen der Präsentationsschicht und der Ebene, die Dauerhaftigkeit übernimmt. Kurz gesagt, definiert die Dienstschicht eine Schnittstelle für die Darstellungsschicht um vordefinierte Systemaktionen auszulösen. Die Dienstschicht entkoppelt die Darstellungs- und Geschäftslogik und der Fassade für die Darstellungslogik zum Aufrufen der BLL dar. Die Dienstschicht hat eigene Auftrag regardless of wie die Geschäftslogik intern organisiert ist.
Als Entwickler .NET sind Sie sehr vertraut mit Ereignishandlern in Web oder Windows-Formularen. Die kanonische Button1_Click-Methode gehört zu der Darstellungsschicht und das Systemverhalten ausdrückt, nachdem der Benutzer eine bestimmte Schaltfläche geklickt hat. Das Systemverhalten – genauer, den Sie implementieren, Anwendungsfall – einige Interaktion mit BLL Komponenten erfordern. In der Regel müssen Sie die BLL-Komponente zu instanziieren und Skript es. Der Code zum Skript für der Komponente kann so einfach wie beim Aufrufen des Konstruktors und vielleicht eine Methode sein. Je öfter jedoch solcher Code ist recht umfangreiche mit Verzweigungen und müssen möglicherweise in mehrere Objekte aufrufen oder eine Antwort warten. Die meisten Entwickler verweisen auf diesen Code als Anwendungslogik. Daher ist die Dienstschicht der Stelle in der BLL, in dem Sie eine Anwendungslogik, Speichern während Sie unterschiedliche und separate aus Domänenlogik. Die Domänenlogik ist keine Logik in die Klassen zu Falten, die Domäne Entitäten darstellen.
In Abbildung 1 sind die Blöcke Service Layer und Domäne Modell unterschiedliche Teile der BLL, obwohl Sie wahrscheinlich verschiedene Assemblys angehören. Die Dienstschicht weiß das Domänenmodell und die entsprechende Assembly verweist. Die Service Layer Assembly, stattdessen wird von der Darstellungsschicht verwiesen und der einzige Kontaktpunkt zwischen alle Darstellungsschicht darstellt (sein es Windows, Web, Silverlight oder Mobile) und der BLL. Abbildung 2 zeigt das Diagramm der Verweise, die die verschiedenen Akteure verbinden. Die Dienstschicht ist eine Art der Vermittler zwischen der Präsentationsschicht und der Rest der die BLL. Daher bleibt diese sauber getrennte aber lose gekoppelte damit Sie perfekt kommunizieren können, sind. Abbildung 2 nicht die Darstellungsschicht jeder Verweis auf die Domäne Modell Assembly enthalten. Dies ist eine wichtige Entwurf Wahl für die meisten geschichteten Lösungen.
Abbildung 2 Diagramm der Verweise zwischen Teilnehmer Schauspieler

Einführung in Datenobjekte übertragen
Wenn Sie eine domänenbasierte Vision der Anwendung haben, können nicht Sie helfen jedoch suchen ernsthaft in Daten Transfer-Objekte. Keine mehrschichtige Lösung anhand von LINQ to SQL oder Entity Framework gegen Angriffe über dieses Entwurfsproblem ist. Ist die Frage, wie Sie Daten in und aus der Darstellungsschicht verschieben möchten? Halten Anders ausgedrückt, sollten die Darstellungsschicht einen Verweis auf die Domäne Modell Assembly? (In einem Szenario mit Entity Framework ist die Domäne Modell Assembly nur die aus der Datei EDMX erstellte DLL.)
Im Idealfall sollte der Entwurf Abbildung 3 aussehen, wobei sind maßgefertigten Objekte verwendet, um Daten von der Präsentationsschicht an die Dienstschicht übergeben und sichern. Diese ad-hoc-Containerobjekte werden der Name des Data-Objekte übertragen (DTOs).
Abbildung 3 Kommunikation zwischen der Präsentationsschicht und Service Layer
Ein DTO ist nichts anderes als ein Containerklasse, die Eigenschaften verfügbar macht, aber keine Methoden. Ein DTO ist hilfreich, wenn Sie Gruppe von Werten in ad-hoc-Strukturen zum Übergeben von Daten.
Eine Perspektive reine Entwurf sind DTOs eine Lösung tatsächlich fast perfekt. DTOs Hilfe zur Präsentation von der Dienstschicht und das Domänenmodell weiter zu entkoppeln. Wenn DTOs verwendet werden, die Präsentationsschicht und der Dienstschicht Datenverträge anstelle frei Klassen. Ein Datenvertrag ist im Wesentlichen eine neutrale Darstellung der Daten, die exchange-Komponenten, die interagierende. Der Datenvertrag beschreibt die Daten, die eine Komponente empfängt, aber es handelt sich nicht um eine Klasse systemspezifische wie eine Entität. Am Ende des Tages ein Datenvertrag ist eine Klasse, aber es ist eher eine Hilfsklasse, die speziell für einen bestimmten Webdienstmethode erstellt.
Eine Schicht von DTOs isoliert das Domänenmodell, aus der Präsentation, was zu einer losen Kopplung und optimiert die Datenübertragung.

Weitere Vorteile von DTOs
Die Übernahme von Datenverträgen Fügt ein gutes Maß an Flexibilität der Dienstschicht und anschließend für den Entwurf der gesamten Anwendung hinzu. Wenn DTOs verwendet werden, haben keine Änderung in die Anforderungen, die eine Verschiebung eine unterschiedliche Menge an Daten z. B. alle Auswirkungen auf die Dienstschicht oder sogar der Domäne. Sie ändern die beteiligten DTO-Klasse durch eine neue Eigenschaft hinzufügen, aber die allgemeine Schnittstelle von der Dienstschicht beizubehalten.
Es sollte, dass eine Änderung in der Präsentation wahrscheinlich eine Änderung in einem der Verwendungsfälle bedeutet beachtet werden und daher in der Anwendungslogik. Da die Dienstschicht die Anwendungslogik rendert, ist in diesem Kontext eine Änderung in der Dienstschnittstelle Ebene noch akzeptabel. Jedoch in meiner Erfahrung wiederholte Änderungen an der Dienstschnittstelle Schicht können führen zu falschen Schlussfolgerung, die in die Domänenobjekte ändert – die Entitäten – möglicherweise speichern Sie weitere Änderungen in der Dienstschicht. Ist nicht dies in well-disciplined Teams oder bei Entwicklern ein tiefes Verständnis der die Trennung von Rollen verfügen, die zwischen das Domänenmodell, die Dienstschicht und DTOs vorhanden ist.
Wie Abbildung 4 dargestellt, wenn DTOs beschäftigt sind, benötigen Sie außerdem eine Schicht DTO Adapter, ein oder mehrere Entität Objekte zu einer anderen Schnittstelle gemäß den Anwendungsfall anzupassen. Auf diese Weise implementieren Sie tatsächlich "Adapter"Muster – eines klassischen und beliebtesten Entwurfsmuster. Adapter-Muster konvertiert im Wesentlichen die Schnittstelle des eine Klasse in einer anderen Schnittstelle, die ein Client erwartet.
Abbildung 4 DTO-Adapter in der BLL
Mit Bezug Abbildung 4 ist die Adapter-Schicht für das Lesen einer eingehenden Instanz der OperationRequestDTO-Klasse und für das Erstellen und Auffüllen neue Instanzen von OperationResponseDTO zuständig.
Anforderungen ändern und Änderungen in einer Ebene DTO-basierten Dienst zu erzwingen, wird Sie müssen Update die öffentlichen Daten von der DTO Vertrag und passen Sie den entsprechenden DTO-Adapter.
Die Entkopplung Vorteile von DTOs Beenden nicht hier. Zusätzlich zu weiterhin bestehenden zum Glück Änderungen in der Präsentation können Sie die Änderungen auf die Entitäten im Domänenmodell eingeben, ohne Auswirkungen auf alle Clients möglicherweise.
Alle realistische Domänenmodell enthält Beziehungen-Kundenbestellungen sowie Order-Debitor, die eine doppelte Verknüpfung zwischen Customer- und Order-Entitäten zu bilden. Mit DTOs können Sie das Problem der Verwaltung von Zirkelverweise während der Serialisierung von Entitätsobjekten auch umgehen. DTOs können einen flachen Stream von Werten ausführen, die bei Bedarf über alle Grenzen hinweg einfach fein serialisieren erstellt werden. (Ich werde zu diesem Zeitpunkt in einen Moment zurückgeben.)

Nachteile von DTOs
Im Hinblick auf reine Entwurf DTOs sind echte Vorteil, aber ist diesem theoretischen Punkt bestätigt von praktischen zu? Als viele Punkte der Architektur-öffnen, lautet die Antwort, es abhängt.
Hunderte von Entitäten ist im Domänenmodell definitiv einen guten Grund berücksichtigt Alternativen zu einem reinen DTO-basierten Ansatz. Fügen Sie in großen Projekten mit so vielen Entitäten DTOs ein bemerkenswert Maß an Komplexität (zusätzlichen) und zu tun. In Short, eine reine 100 % DTO Lösung ist häufig nur eine 100 % mühsam Projektmappe.
Während normalerweise die Komplexität von DTOs einer Projektmappe hinzugefügt mit die Kardinalität des Domänenmodells gemessen wird, können die Real-Anzahl der erforderlichen DTOs mehr zuverlässig bestimmt die Anwendungsfälle und die Implementierung der Dienstschicht ansehen sein. Darin, dass eine gute Formel für die Schätzung wie viele DTOs Sie müssen die Anzahl der Methoden in der Dienstschicht betrachten. Die reelle Zahl kann sein, kleiner, wenn Sie über mehrere Webdienstaufrufe Layer einige DTOs wiederverwenden können, oder höher, wenn Ihre DTOs einige Daten mithilfe von komplexe Typen gruppieren.
Zusammenfassend ist das einzige Argument gegen mithilfe von DTOs die zusätzliche Arbeit, die zum Schreiben und verwalten die Anzahl der resultierenden DTO-Klassen erforderlich. Es ist nicht, jedoch eine einfache von einem Programmierer Bequemlichkeit und unerheblich. In großen Projekten Kosten Präsentation von der Dienstschicht entkoppeln Sie Hunderte von neuen Klassen.
Es sollte auch beachtet werden, dass ein DTO nicht einfach eine lightweight Kopie jede Entität ist möglicherweise. Angenommen, zwei verschiedene Anwendungsfällen müssen Sie eine Auflistung von Bestellungen zurückzugeben – sagen, GetOrdersByCountry und GetOrdersByCustomer. Sehr wahrscheinlich die Informationen in "Order" Einfügenunterscheidet. Wahrscheinlich benötigen Sie weitere (oder weniger) Details in GetOrdersByCustomer als in GetOrdersByCountry. Dies bedeutet, dass unterschiedliche DTOs erforderlich sind. Aus diesem Grund Hunderte von Entitäten sind sicherlich eine schnelle Messung der Komplexität, aber die reelle Zahl von DTOs können nur durch Betrachten Anwendungsfälle bestimmt werden.
Wenn DTOs nicht immer optimal sind, wäre was eine sinnvolle Alternative Methode?
Die einzige alternative zur Verwendung von DTOs besteht darin, die Domäne Modell Assembly aus in der Darstellungsschicht verweisen. Auf diese Weise richten Sie jedoch eine enge Kopplung zwischen den Ebenen. Und eng gekoppelte Ebenen möglicherweise ein Problem schlimmer.

Entitäten direkt verweisen
Eine erste, nicht so offensichtliche Bedingung So aktivieren Sie die Verknüpfung von Entitäten direkt aus der Darstellungsschicht ist, dass es die Darstellungsschicht Daten im Format der Entitätsobjekte empfangen akzeptabel ist. Die Präsentation benötigt manchmal Daten in einer bestimmten Weise formatiert. Ein DTO Adapter Layer zu nur Massage Daten gemäß dem Client vorhanden ist. Wenn Sie jedoch nicht DTOs verwenden, muss die Last richtig Formatieren von Daten auf der Präsentationsebene verschoben werden. Tatsächlich ist die falsche Stelle in der Format-Daten für Benutzer Schnittstelle Zwecke das Domänenmodell selbst.
Realistisch, können Sie ohne DTOs tun, nur, wenn die Präsentationsschicht und der Dienstschicht in demselben Prozess Zusammenlegung sind. In diesem Fall können Sie problemlos die Entität-Assembly in beide Ebenen ohne Umgang mit thorny Problemen wie z. B. Remoting und Daten Serialisierung verweisen. Diese Überlegung führt zu einem anderen gute Frage: Wo sollten Sie die Dienstschicht anpassen?
Wenn der Client einer Seite ist, ist die Dienstschicht vorzugsweise lokal auf dem Webserver, der die Seite hostet. In ASP.NET Anwendungen die Darstellungsschicht ist, alle im Code - behind-Klassen und befinden sich nebeneinander mit Dienstschicht in derselben Anwendungsdomäne. In einem solchen Szenario jede Kommunikation zwischen der Präsentationsschicht und der Dienstschicht erfolgt in-Process und Objekte können mit keine weiteren Sorge freigegeben werden. ASP.NET Anwendungen sind ein guter Szenario können Sie eine Lösung versuchen, die die zusätzliche Schicht von DTOs nicht verwendet.
Technology-Wise, können Sie die Dienstschicht über einfache .NET Objekte oder über lokale Windows Communication Foundation (WCF) Dienste implementieren. Wenn die Anwendung erfolgreich ist, können Sie problemlos Skalierbarkeit erhöhen, indem die Dienstschicht auf einem Server separate Anwendung verschieben.
Ist der Client eine Desktopanwendung ist dann die Dienstschicht i. d. r. in einer anderen Ebene bereitgestellt und Remote über den Client zugegriffen. Sofern der Client und dem Remoteserver die gleiche .NET Plattform verwenden, können Sie Remoting Techniken (oder besser, WCF-Dienste) zum Implementieren von Kommunikation und systemeigene Entitätsobjekte weiterhin an beiden Enden verwenden. Die WCF-Infrastruktur wird kümmern Marshallen von Daten über Schichten hinweg und in Kopien des systemeigenen Entitäten Pumpe. In diesem Fall können Sie auch eine Architektur anordnen, die nicht DTOs verwendet. Dinge ändern erheblich, wenn die Client und Server-Plattformen nicht kompatibel sind. In diesem Fall müssen Sie keine Wahrscheinlichkeit die systemeigenen Objekte verknüpfen und diese vom Client; aufrufenNachfolgend, Sie sind in einem reinen dienstorientierte Szenario und mithilfe von DTOs ist die einzige Möglichkeit.

Die Mitte-Methode
DTOs sind den Betreff der eine wichtige Entwurfsentscheidung, die die Implementierung der Kommunikation zwischen der Präsentation und dem Back-End des Systems auswirkt.
Wenn Sie DTOs einsetzen, behalten Sie das System, lose gekoppelten und gegen eine Vielzahl von Clients geöffnet. DTOs sind die ideale Wahl, wenn Sie sich leisten können. DTOs hinzufügen eine erhebliche Programmierung Aufwand an realen System. Dies bedeutet nicht, dass DTOs nicht verwendet werden sollte, aber Sie führen zu einer Verbreitung von Klassen, die eigentlich ein Albtraum Wartung in Projekten mit ein paar Hundert Entitätsobjekte und sogar noch mehr Anwendungsfälle prefigure können.
Wenn Sie auf die gleiche Zeit einen Anbieter und Consumer von der Dienstschicht, und vollständige Kontrolle über die Präsentation haben Sie möglicherweise Vorteile in verweisen auf die Entität Modell Assembly aus der Präsentation. Auf diese Weise werden alle Methoden in der Dienstschicht mit Entitäten als die Datenverträge deren Signaturen zulässig. Die Auswirkungen auf Entwurf und Codierung sind klar ziemlich weichere.
Ob Sie DTOs oder nicht zu verwenden ist kein leicht zu verallgemeinern. Um effektiv zu sein, sollten die endgültige Entscheidung immer vorgenommen werden die Besonderheiten des Projekts betrachten. Am Ende ist ein gemischter Ansatz wahrscheinlich, was Sie in den meisten Fällen durchführen müssen. Neigen dazu ich persönlich zu Entitäten wie möglich verwenden. Dies geschieht nicht, weil ich gegen Reinheit und sauberen Entwurf, jedoch für eine einfachere Frage des Pragmatism. Mit ein Entitätsmodell, die Konten für nur 10 Entitäten und ein paar Anwendungsfälle, verwenden Sie DTOs ganz über keine bedeutendes Problem darstellen. Und Sie erhalten praktische Entwurf und Niedrig Kopplung. Jedoch mit Hunderten von Entitäten und verwenden Fällen die reelle Zahl von Klassen zu schreiben, Verwalten und Test ominously die Reihenfolge der Tausende nähert. Alle möglichen Reduzierung der Komplexität, die Anforderungen erfüllt ist mehr als Willkommen.
Als Architekt sollten Sie jedoch immer sein auf die Warnung zum Erkennen der Anzeichen, dass der Abstand zwischen das Entitätsmodell und was die Präsentation erwartet bedeutende oder zur Deckung unmöglich ist. In diesem Fall sollten Sie die Route sicherere (und Bereinigung) DTOs ergreifen.

Gemischte Ansatz
Überlappende heutigen Anwendungen reservieren einen Abschnitt der BLL dem Dienst-Layer. Die Dienstschicht (auch als der Anwendungsebene bezeichnet) enthält die Anwendungslogik;d. h., die Geschäftsregeln und Prozeduren, die bestimmte auf die Anwendung jedoch nicht auf die Domäne. Ein System mit mehreren front-Ends ein einzelnes Teils Domänenlogik über Entitätsklassen macht, aber dann müssen jedes front-End eine zusätzliche Geschäftsschicht spezifisch für die Anwendungsfälle unterstützt wird. Dies ist, was als Layer Service (oder Anwendung) bezeichnet wird.
Ausgelöst von der Benutzeroberfläche, Skripts die Anwendungslogik, die Entitäten und Dienste in der Geschäftslogik. In der Dienstschicht Sie implementieren die Anwendungsfälle und offen legen jede Abfolge der Schritte über eine grobe Methode für die Präsentation aufrufen.
Im Entwurf der Dienstschicht sollten Sie einige best Practices anwenden, Dienstorientierung nutzen und Freigeben von Datenverträgen anstelle von Entitäten. Dieser Ansatz in der Theorie ideal ist, Konflikt oft mit der realen Welt, wie es zu viel Aufwand in Projekten mit Hunderten von Entitäten und Anwendungsfälle hinzufügen endet.
Wie sich herausstellt, dass ein gemischter Ansatz, der Daten verwendet Verträge nur bei Verwendung von Klassen nicht möglich ist, ist oft mehr akzeptable Lösung. Aber als Architekt, Sie müssen nicht diese Entscheidung leicht. Ein guter Entwurfsregeln verletzen ist zulässig, solange Sie wissen, was Sie tun.

Senden Sie Ihre Fragen und Kommentare für Dino in cutting@microsoft.com.

Dino Esposito ist Architekt bei IDesign und Mitautor von Microsoft.NET: Entwickeln Anwendungen für die Enterprise- (Microsoft Press, 2008). Dino arbeitet in Italien und ist ein weltweit gefragter Referent bei Branchenveranstaltungen. Sie können seinen Blog unter weblogs.asp.net/despos beitreten.

Page view tracker