Chapter 12: Repositories

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

A ____________-oriented Repository interface defines save-based methods

Persistence

Every persistent ______________ type will have a Repository

Aggregate

For Repositories: When using the GemFire or Coherence caches, the MongoDB or Riak key-value stores, or some other mind of NoSQL persistence, you will probably want to use a fast and compact means to convert ________________ to their serialized/document form and then back again to their object form.

Aggregates

A common architectural approach to facilitating transactions on behalf of persistence aspects of the domain model is to manage them in the ___________ Layer.

Application

If your requirements demand a very high-performance domain with many, many objects in memory at any given time, designing a collection-oriented repository using a persistence mechanism that offers implicit copy-on read or implicit copy-on-write, such as ____________, is going to add gratuitous overhead, in both memory and execution. You will have to consider and decide carefully whether or not this works for you.

Hibernate

Generally, in the ___________ Layer, we create one Facade there for each major use case grouping addressed by the application/system. The Faced is designed with coarse-grained business methods, usually one for each use case flow (which may be limited to one for a given use case). Each such business method coordinates a task as required by the use case. When a Facade's business method is invoked by the User Interface Layer, whether on behalf of a human or another system, the business method begins a transaction and then acts as a client to the domain model. After all necessary interactions with the domain model is successfully completed, the Facade's business method commits the transaction it started. If an error/exception occurs that prevents completion of the use case task, the transaction is rolled back by the same managing business method.

Application

With any such persistence mechanism, you must find a way to provide the domain model access to the same Session, Unit of Work, and transaction that the ___________ Layer is managing. Dependency Injection works well for this if it is available. If it isn't available, there are other creative ways to facilitate the necessary wiring, event going as far as manually binding such objects to the current thread.

Application

Regarding designing collection-oriented Repositories: TopLink's Unit of Work provides a much more efficient use of memory and processing power since you must explicitly inform the Unit of Work that you intend to modify the object. It is not until that time that a clone, or editing copy, of you Aggregate is made. As you cause modifications on the object, TopLink is able to track the changes that occur. When method commit() on UnitOfWork is invoked, all modified objects are committed to the database. Further, the Repository needs to be put in edit mode so that the finder methods start registering all objects they query with the backing UnitOfWork and answers with the clones. This approach is called Explicit Copy-____________

Before-Write

If we add an Aggregate instance to the Aggregate's Repository designed with a _________ orientation, adding that instance a second time is benign. Each Aggregate has a globally unique identity that is associated with the Root Entity. It it this unique identity that allows the Set-like Repository to prevent adding the same Aggregate instances more than once.

Collection

The primary thing to keep in mind is that as much as possible you should try to design your Repositories with a ___________ orientation rather than a data access orientation. that will help keep you focused on the domain as a model rather than on data and any CRUD operations that may be used behind the scenes to manage its persistence.

Collection

When using a _________-oriented Repository, there is no need to do anything special to get it to recognize changes to the objects that it contains, other than to ask the Repository to hand you a reference to a specific object and then ask that object to do something to itself, which modifies its own state. The same object is still held by the Repository, and now the the state of that contained object is different from what it was prior to modification.

Collection

When using a ___________-oriented Repository style, Aggregate instance s are added only when they are created, since modifications are automatically tracked.

Collection

Using a persistence mechanism that offers implicit copy-on read or implicit copy-on-write, such as Hibernate, allows you to employ a traditional, ____________-oriented Repository, where changes to persistent objects are tracked implicitly, requiring no explicit client knowledge or intervention to make changes known to the persistence mechanism.

Colllection

If you find that you must create many finder methods supporting use case optimal queries on multiple Repositories, it's probably a code smell. First of all, this situation could be an indication that you've misjudged Aggregate boundaries and overlooked the opportunity to design one or more Aggregates of different types. The code smell here might be called Repository masks Aggregate mis-design. However, what if you encounter this situation and your analysis indicates that your Aggregate boundaries are well designed? This could point to the need to consider using ___________ (CQRS)

Command Query Responsibility Segregation.

Aggregates must defied carefully in order to ensure correct ___________ boundaries.

Consistency

A traditional collection-oriented Repository truly mimics a collection in that no parts of the persistence mechanisms are surfaced to the client by its public interface. This requires some specific capabilities of the backing persistence mechanism. The persistence mechanism must in some way support the ability to implicitly track changes made to each persistent object that it manages. This may be accomplished in various ways, including: Implicit _________: The persistence mechanism implicitly copies each persistent object on read when it is reconstituted from the data store and compares its private copy to the client's copy on commit. Stepping through this, when you ask the persistence mechanism to read an object from the data store, it does so and immediately makes a copy of the entire object (minus any lazy-loaded parts, which also may be loaded and copied later). When a transaction created through the persistence mechanism is committed, the persistence mechanism checks for modifications on the copied objects it has loaded (or reattached to) by comparing them. All objects with detected changes are flushed to the data store.

Copy-on-Read

A traditional collection-oriented Repository truly mimics a collection in that no parts of the persistence mechanisms are surfaced to the client by its public interface. This requires some specific capabilities of the backing persistence mechanism. The persistence mechanism must in some way support the ability to implicitly track changes made to each persistent object that it manages. This may be accomplished in various ways, including: Implicit _________: The persistence mechanism manages all loaded persistent objects through a proxy. As each object is loaded from the data store, a thin proxy is created and handed to the client. Clients unknowingly invoke behavior on the proxy object, which reflects the behavior onto the real object. When the proxy first receives a method invocation, it makes a copy of the managed object. The proxy tracks changes made to the state of the managed object and marks it dirty. When a transaction created through the persistence mechanism is committed, it checks for dirty objects and all such are flushed to the data store.

Copy-on-write

A ___________ (DAO) is expressed in terms of database tables, providing CRUD interfaces to them.

Data Access Object

Since you can use a ___________ (DAO) and related patterns to perform fine-grained CRUD operations on data that would otherwise be considered parts of an Aggregate, this would be a pattern to avoid with a domain model. Under normal conditions, you want the Aggregate itself to manage its business logic and other internals and keep everyone else out.

Data Access Object

Some like to locate all technical implementation classes of any Repository interface in the Infrastructure Layer (e.g., infrastructure.persistence). This uses the ____________, or DIP, for layering infrastructure concerns. The Infrastructure Layer is logically above all others, making references unidirectional and downward to the Domain Layer.

Dependency Inversion Principle

The domain model and its encompassing _________ Layer is never the correct place to manage transactions. The operations associated with a model are usually too fine grained to themselves manage transactions and shouldn't be aware that transactions play a part in their life cycle.

Domain

Sometimes, it is beneficial to provide additional behavior on a Repository interface. There may be other calculations that must be performed in the data store (database or grid included) in order to meet some stringent nonfunctional requirement. This can be the case if moving the data from its store to where the business logic executes is too slow. Instead you may have to move the code to the data. This can be accomplished using database stored procedures or data grid entry processors, such as are available with Coherence. However, such implementations are often best placed under the control of ____________, since those are used to house stateless, domain specific operations.

Domain Services

Strictly speaking, only Aggregates have Repositories. If you are not using Aggregates in a given Bounded Context, the Repository pattern may be less useful. If you are retrieving and using _________ directly in an ad hoc fashion rather than crafting Aggregate transactional boundaries, you may prefer to avoid Repositories.

Entities

In addition to the (command) methods for add, save, and remove Aggregate instances, another important part of the Repository interface is the definition of _________ (or query) methods

Finder

Some like to place the implementation class for a Repository in a Java Package directly under the Aggergate and Repository Module (e.g., com.{company}.{context}.domain.model.{module}.impl). Placing the class here allows you to manage the implementation in the Domain Layer, but in a special package for implementations. That way, you keep the domain concepts cleanly separated from those that directly deal with the persistence. This style of declaring interfaces in a richly name, and their implementations in a sub-package named ______ directly under it, is widely practiced in Java projects.

Impl

If it is very difficult to set up the full persistent implementation of a Repository for test, or too slow to use it, you can leverage another approach. You may also face undesirable conditions early on during domain modeling, perhaps when your persistence mechanisms, including the database schema, are not yet available. When you face any of these situations, it works best to implement an ___________ of Repositories, creating a HashMap to back your interface.

In-memory

There are two ways to look at testing Repositories. You have to test the Repositories themselves in order to prove that they work correctly. You also must test code that uses Repositories to store the Aggregates that they create and to find preexisting ones. For the first kind of test you must use the full production-quality implementation. Otherwise, you won't know if your production code will work. For the second kind of test, either you can use your production implementations, or you can use ___________ implementations instead.

In-memory

When designing a Repository, the first step is to create an _____________, which should be placed in the same Module as the aggregate type that it store.

Interface

When using an object-oriented language to develop a domain model, it can be tempting to leverage inheritance to create type hierarchies. We might think of this as an opportunity to place default state and behavior in a base class and then extend that using subclasses. I am referencing to creating a relatively small number of Aggregate types that extend a common domain-specific superclass. These are designed in order to form a hierarchy of closely related types that have interchangeable, polymorphic characteristics. These kinds of hierarchies use a single Repository to store and retrieve instances of the separate types, because the client should use the instances interchangeably, and the clients rarely if ever have to be aware of the specific subclass that they are dealing with at any given time, which reflects the ___________ (LSP) In the case where only two or a few such concrete subclasses are necessary, it may be best to create separate Repositories. When the number of concrete subclasses grows to several or many, most of which can be used completely interchangeably (LSP), it is worthwhile for them to share a common Repository.

Liskov Substitution Principle

It is possible that instances of some Aggregate types must never be removed through normal application use cases. It may be necessary to retrain the instance long after it is no longer usable in the application, possibly for referential and/or historical purposes. From a business perspective, it may be unwise, ill advised, or even illegal to remove some objects. In those cases, you may decide to simply mark the Aggregate instance disabled, unusable, or in some other specific way, ____________ removed. If so, you may determine not to include any removal methods on the Repository public interface, or you may decide to implement the removal methods to set the unusable state of the Aggergate instance.

Logically

Using a persistence mechanism that offers implicit copy-on read or implicit copy-on-write, such as Hibernate, allows you to employ a traditional, collection-oriented Repository. But this approach may have unnecessary memory and execution overhead for your use case. Oracle's TopLink and its nearest relative, EclipseLink, provide a more optimally performing object-relational mapping tool that supports a collection-oriented Repository. TopLink provides a Unit of Work, which is not entirely unlike Hibernate's session. However, TopLink's component does not make an implicit copy-on-read. Instead it makes an Explicit Copy-before-Write. Here the term explicit means that the client must inform the Unit of Work that changes are about to take place. This gives the Unit of Work the opportunity to clone the given domain object in preparation for modifications. The key point is that TopLink consumes ____________ only when it must.

Memory

Sometimes, it is beneficial to provide additional behavior on a Repository interface. It may at ties be advantageous to query Aggregate parts out of the Repository without directly accessing the Root itself. This might be so if an Aggregate holds a large collection of some Entity type, and you need to get access only to the instance that match a certain criterion. This should be used primarily to address ___________ concerns under conditions where navigation through the Root would cause an unacceptable bottleneck. The methods that address such optimal access would have the same basic characteristics as other finders, but would answer instances of the contained parts rather than Root Entities.

Performance

Another advantage to implementing in-memory editions of your Repositories is when you need to test for proper uses of save() with a ___________-oriented interface. You can implement the save() methods to count invocations. After each test is run, you can assert that the invocation count matches the number required by the client of the specific Repository. Generally, you could use this approach when testing Application Services that must explicitly save() changes to an Aggergate.

Persistence

Another consideration for choosing a ____________-oriented approach for Repository over a collection-oriented one, in cases where it is a very realistic possibility that your persistence mechanism will shift in the future, it might be best to design with the more flexible interface in mind. The downside is that your current object-relational mapper may cause you to leave out necessary uses of save() that you may catch only later when there is no longer a backing Unit of Work. The upside is that the Repository pattern will allow you to completely replace your persistence mechanism with potentially little impact to you application.

Persistence

For times when a collection-oriented style doesn't work, you will need to employ a ____________-oriented, save-based Repository. This will be the case when your persistence mechanism doesn't implicitly or explicitly detect and track object changes. This happens to be the case when using an in-memory Data Fabric, or by any other name a NoSQL key-value data store. Every time you create a new Aggregate instance or change a preexisting one, you will have to put it into the data store by using save() or a save-like Repository method.

Persistence

When designing Repositories with a ____________ orientation, we must explicitly put() both new and changed objects into the store, effectively replacing any value previously associated with the given key. Using these kinds of data stores greatly simplifies the basic writes and reads of Aggregates. For this reason, they are sometimes called Aggregate Stores or Aggregate-Oriented Databases.

Persistence

When using a __________-oriented Repository style, Aggregate instances must be save both when they are created and when they are modified.

Persistence

A major strength of Data Fabrics such as GemFire and Coherence is ___________ and high availability.

Redundancy

For each type of object that needs global access, create an object that can provide the illusion of an in-memory collection of all objects of that type. Set up access through a well-known global interface. Provide methods to add and remove objects. Provide methods that select objects based on some criteria and return fully instantiated objects or collections of objects whose attribute values meet the criteria. Provide these _______________ only for aggregates

Repositories

Regarding removing objects from a collection-oriented Repository that uses Hibernate, there is one additional detail regarding the removal of Aggregates that use one-to-one mappings (i.e., there is a nested Entity under the Aggregate Root) Because you cannot cascade changes on such relationships, you will need to explicitly delete objects on both sides of the associations. The inner Entity instance must first be deleted, and then the Aggregate Root. If you do not delete the inner Entity instance, it will be orphaned in its corresponding database table. In general, this is a good reason to avoid one-to-one associations and instead use a constrained singular many-to-one unidirectional association. Nota that there are different preferred approaches for dealing with such situations. Some may choose to depend on ORM life cycle events to cause part object cascading deletes. I have purposely avoiding such approaches because I am a strong opponent of Aggregate-managed persistence, and I strongly advocate ____________-only persistence. Understand that DDD experts avoid Aggregate-managed persistence as a rule of thumb.

Repository

Sometimes, when two or more Aggregate types share an object hierarchy, the types may share a single ____________.

Repository

There are two kinds of _________ design, a collection-oriented design and a persistence-oriented design.

Repository

Unlike a DAO, which tends to serve as a wrapper around a database table, _____________ and Data Mapper, having object affinity, are typically the patterns that would be used with a domain model.

Repository

A collection-oriented Repository should mimic a _________ collection. Whatever the backing implementation with a specific persistence mechanism, you must not allow instances of the same object to be added twice. Also, when retrieving objects from a Repository and modifying them, you don't need to "re-save" them to the Repository. You'd just retrieve from the collection the reference to the object you desire to modify, and then ask the object to execute some state-transitioning behavior by invoking a command method.

Set

Sometimes, it is beneficial to provide additional behavior on a Repository interface. One behavior that comes in handy is to answer the count of all instances in a collection of Aggregates. You may think of this behavior as having the name count. However, since the Repository should mimic a collection as closely as possible, you might consider instead using the method name: _________()

Size

To enlist changes to the domain model in a transaction, ensure that Repository implementations have access to the same Session or Unit of Work for the transaction that the Application Layer started. That way the modifications made in the Domain Layer will be properly committed to the underlying database or rolled back. Enterprise Java containers and inversion of control containers, such as _________, provide the means to do this.

Spring

Most of the time, instead of creating a type hierarchy of aggregates that may or may not be persisted using the same Repository, this kind of situation can be completely avoided by designing type descriptive information as a property of the Aggregate. This way a single Aggregate type could internally implement different behavior based on an explicitly determined ___________ (e.g., Enum).

Standard Type

(T/F) Generally speaking, there is a one-to-one relationship between an Aggregate type and a Repository

T

DAO and related pattern tend to serve as wrappers around database ___________.

Tables

Be careful not to overuse the ability to commit modification to multiple Aggregates in a single transaction just because it works in a unit test environment. If you aren't careful, what works well in development and test can fail severely in production because of concurrency issues. Precisely define consistency boundaries in order to ensure ___________ success.

Transactional

Certain use cases of your system may cut across Aggregate types, possibly composing just certain parts of one or more Aggregates. In situations like this, you might choose to use what is called a ____________. This is where you specify a complex query against the persistence mechanism, dynamically placing the results into a Value Object specifically designed to address the needs of the use case. This query can go on a Repository.

Use Case Optimal Query

In regarding to the design a Repository, we can consider a _________-oriented design a traditional approach because it adheres to the basic ideas presented in the original DDD pattern. These very closely mimic a collection, simulating at least some of its standard interface. Here you design a Repository interface that does not hint in any way that there is an underlying persistence mechanism, avoiding any notion of saving or persisting data to a store.

collection


Ensembles d'études connexes

Network Troubleshooting at the Command Line

View Set

Chapter 13: Labor and Birth Process

View Set