An aggregate (Article) has an entity (SmsContent) with a property (enabled) that only can change if a condition on the aggregate is met.
e.g.
<?php
//Aggregate
class Article {
/** #var User */
protected $user;
/** #var SmsOutput */
protected sms;
...
public function enableSms() {
if($this->user->hasPermission('sms')) {
throw new PermissionDeniedException('sms');
}
$this->sms->enable();
retutn $this;
}
public function getSms() {
return $this->sms;
}
...
}
//Entity
class SmsOutput {
/** #var boolean */
protected enabled = false;
...
public function enable() {
$this->enable = true;
}
...
}
How should you get the SmsContent entity from the Article without being able to change the enabled property from outside the aggregate?
For example:
$article->getSms()->enable();
How is this handled in DDD?
You have multiple options, depending on the architecture.
1. Use CQRS
In CQRS the Write is separated from the Read. This means that you don't interrogate the Aggregate, ever. You don't have any getters, only command handlers. If you can't interrogate the Aggregate you can't access any nested entity either. If you need to get data you do it only from a projection/read model that are read-only by default.
2. Use a different interface for returned entities
In this case you return the entity but it is type-hinted as being a sub-set of the actual entity. In your case you could have something like this:
<?php
interface SmsOutput
{
//...
public function isEnabled(): bool;
//...
}
//Entity
class SmsOutputWritable implements SmsOutput
{
/** #var boolean */
private $enabled = false;
//...
public function enable()
{
$this->enabled = true;
}
public function isEnabled(): bool
{
return $this->enabled;
}
//...
}
//Aggregate
class Article
{
/** #var User */
private $user;
/** #var SmsOutputWritable */
private $sms;
//...
public function enableSms(): void //no return values, see CQS
{
if ($this->user->hasPermission('sms')) {
throw new PermissionDeniedException('sms');
}
$this->sms->enable();
}
public function getSms(): SmsOutput
{
return $this->sms;
}
//...
}
Although the caller gets a SmsOutputWritable it does not know about this.
P.S. Anyway, even if the caller knows (or casts) that the returned value is SmsOutputWritable and call SmsOutputWritable::enable() nothing really happens because the caller can't persist the changes to the repository, only entire aggregates can be persisted not individual nested entities. This is because aggregates and/or nested entities don't persist themselves, only an Application service can do this, using a repository.
How should you get the SmsContent entity from the Article without being able to change the enabled property from outside the aggregate?
Short answer: You don't. You get an immutable representation (ie: a value type) of the SmsContent.State from the Aggregate Root.
That's the approach taken by Evans in Domain Driven Design. There have been a couple of innovations that have gained traction since then.
One is the idea that a single entity can serve in multiple roles. Rather than having a single repository that serves many different use cases, you might have many repositories that handle specific cases. Here, that might look like a repository that returns the Aggregate Root when you want to be able to change something, and a different repository that returns a view/projection for use cases that only inspect the data.
This separation goes really well with ideas like lazy loading; if you aren't going to need some data for a particular use case, you interact with a repository that doesn't load it.
Udi Dahan's essay Better Domain-Driven Design Implementation provides a high level overview.
This looks a lot like the CQRS suggestion of Constantin. I mean, when you start using different repositories for reads and writes, then you're already with one feet in CQRS
It does, but there are a few intermediate steps along the way; CQS, responsibility driven design.
Related
I am a .net developer, trying my hands on nodejs web api development.
I was wondering that whether we can create models in nodejs same as we create in asp.net web api.
For example
public class BaseResponse
{
public bool Success { get; set; }
public string ErrorMessage { get; set; }
}
public class MovieResponse : BaseResponse
{
public int MovieId { get; set; }
public string MovieName { get; set; }
}
This is how we do it in c#.
How can i create such models in nodejs.
Any npm package available?
There's good news and there's bad news. The bad news is the concept of classes and inheritance as you know it from other languages is not supported. The good news, JavaScript attempted to do something along that idea (although it did a miserable job implementing it). Below is an example of the code you provided using JavaScript:
function BaseResponse(success, errorMessage) {
this.success = success;
this.errorMessage = errorMessage;
}
function MovieResponse(success, errorMessage, movieId, movieName) {
BaseResponse.call(this, success, errorMessage); // Call the base class's constructor (if necessary)
this.movieId = movieId;
this.movieName = movieName;
}
MovieResponse.prototype = Object.create(BaseResponse);
MovieResponse.prototype.constructor = MovieResponse;
/**
* This is an example of an instance method.
*/
MovieResponse.prototype.instanceMethod = function(data) { /*...*/ };
/**
* This is an example of a static method. Notice the lack of prototype.
*/
MovieResponse.staticMethod = function(data) {/* ... */ };
// Instantiate a MovieResponse
var movieResInstance = new MovieResponse();
Mozilla has really good documentation on JavaScript and classes. In the code above, you are creating two functions BaseResponse and MovieResponse. Both of these functions act as constructors for an object with the appropriate "class" when you use the new keyword. You specify that MovieResponse inherits from BaseMovie with MovieResponse.prototype =Object.create(BaseResponse). This effectively sets MovieResponse's prototype chain equal to BaseResponse's prototype chain. You'll notice that immediately after setting MovieResponse's prototype chain I have to set its constructor to point to MovieResponse. If I didn't do this, every time you tried to initialize a MovieResponse, JavaScript would try to instead instantiate a BaseResponse (I told you they did a horrible job).
The rest of the code should be relatively straightforward. You can create instance methods on your brand new, shiny class by defining them on the prototype chain. If you define a function on BaseResponse that is not defined on MovieResponse but call the function on an instance of MovieResponse, JavaScript will "crawl" the prototype chain until it finds the function. Static methods are defined directly on the constructor itself (another weird feature).
Notice there is no concept of types or access modifiers (public/private). There are runtime tricks that you can implement to enforce types, but it's usually unnecessary in JavaScript and more prone to errors and inflexibility than adding such checks may justify.
You can implement the concept of private and protected members of a class in a more straightforward method than types. Using Node's require(), and assuming you wanted a private function called privateMethod you could implement it as:
function privateMethod() { /* privateMethod definition */ }
// Definition for MovieResponse's constructor
function MovieResponse() { /*...*/ }
module.exports = MovieResponse;
I will add a somewhat required commentary that I do not agree with: it is unnecessary to use inheritance in JavaScript. JavaScript uses a notion coined "duck typing" (if it looks like a duck and sounds like a duck, its a duck). Since JavaScript is weakly typed, it doesn't care if the object is a BaseResponse or MovieResponse, you can call any method or try to access any field you want on it. The result is usually an error or erroneous/error-prone code. I mention this here because you may come across the notion and its supporters. Know that such programming is dangerous and results in just bad programming practices.
Consider we have a BankCard Entity that is a part of Client Aggregate. Client may want to cancel her BankCard
class CancellBankCardCommandHandler
{
public function Execute(CancelBankCardCommand $command)
{
$client = $this->_repository->get($command->clienId);
$bankCard = $client->getBankCard($command->bankCardId);
$bankCard->clientCancelsBankCard();
$this->_repository->add($client);
}
}
class BankCard implements Entity
{
// constructor and some other methods ...
public function clientCancelsBankCard()
{
$this->apply(new BankCardWasCancelled($this->id);
}
}
class Client implements AggregateRoot
{
protected $_bankCards;
public function getBankCard($bankCardId)
{
if (!array_key_exists($bankCardId, $this->_bankCards) {
throw new DomainException('Bank card is not found!');
}
return $this->_bankCard[$bankCardId]);
}
}
Finally we have some domain repository instance which is reponsible for storing Aggregates.
class ClientRepository implements DomainRepository
{
// methods omitted
public function add($clientAggregate)
{
// here we somehow need to store BankCardWasCancelled event
// which is a part of BankCard Entity
}
}
My question is whether AggregateRoot responsible for tracking its Entities' events or not. Is it possible to get events of an Entity which is a part of an Aggregate from within its Aggregate or not?
How to actually persist the Client with all changes made to the bank card saving its consistency?
I would say the aggregate as a whole is responsible for tracking the changes that happened to it. Mechanically, that could be "distributed" among the aggregate root entity and any other entities within the aggregate or the aggregate root entity as the sole recorder or some external unit of work. Your choice, really. Don't get too hung up on the mechanics. Different languages/paradigms, different ways of implementing all this. If something happens to a child entity, just consider it a change part of the aggregate and record accordingly.
I have an aggregate that includes the entities A, AbstractElement, X, Y and Z. The root entity is A that also has a list of AbstractElement. Entities X,Y and Z inherit from AbstractElement. I need the possibility to add instances of X, Y and Z to an instance of A. One approach is to use one method for each type, i.e. addX, addY and addZ. These methods would take as arguments the values required to create instances of X, Y and Z. But, each time I add a new type that inherits from AbstractElement, I need to modify the entity A, so I think it's not the best solution.
Another approach is to use an abstract add method addAbstractElement for adding AbstractElement instances. But, in this case, the method would take as argument an instance of AbstractElement. Because this method would be called by entities located outside of the aggregate, following DDD rules/recommandations, are these external entities authorized to create instances of AbstractElement? I read in the Eric Evans book that external entities are not authorized to hold references of entities of an aggregate other than the root?
What is the best practice for this kind of problem?
Thanks
From Evan's book, page 139:
"if you needed to add elements inside a preexisting AGGREGATE, you might create a FACTORY METHOD on the root of the AGGREGATE"
Meaning, you should create a factory method on the root (A) which will get the AbstractElement's details. This method will create the AbstractElement (X/Y/Z) according to some decision parameter and will add it to its internal collection of AbstractElements. In the end this method return the id of the new element.
Best Regards,
Itzik Saban
A few comments. As the previous answerer said, it's a good practice to use a factory method. If you can avoid it, never create objects out of the blue. Usually, it's a pretty big smell and a missed chance to make more sense out of your domain.
I wrote a small example to illustrate this. Video is in this case the aggregate root. Inside the boundaries of the aggregate are the video object and its associated comments. Comments can be anonymous or can have been written by a known user (to simplify the example, I represented the user by a username but obviously, in a real application, you would have something like a UserId).
Here is the code:
public class Video {
private List<Comment> comments;
void addComment(final Comment.Builder builder) {
this.comments.add(builder.forVideo(this).build());
// ...
}
}
abstract public class Comment {
private String username;
private Video video;
public static public class Builder {
public Builder anonymous() {
this.username = null;
return this;
}
public Builder fromUser(final String username) {
this.username = username;
return this;
}
public Builder withMessage(final String message) {
this.message = message;
return this;
}
public Builder forVideo(final Video video) {
this.video = video;
return this;
}
public Comment build() {
if (username == null) {
return new AnonymousComment(message);
} else {
return new UserComment(username, message);
}
}
}
}
public class AnonymousComment extends Comment {
// ...
}
static public class UserComment extends Comment {
// ...
}
One thing to ponder on also is that aggregate boundaries contain objects and not classes. As such, it's highly possible that certain classes (mostly value objects but it can be the case of entities also) be represented in many aggregates.
If I have an entity Entity and a service EntityService and EntityServiceFacade with the following interfaces:
interface EntityService {
Entity getEntity(Long id);
}
interface EntityServiceFacade {
EntityDTO getEntity(Long id);
}
I can easily secure the read access to an entity by controlling access to the getEntity method at the service level. But once the facade has a reference to an entity, how can I control write access to it? If I have a saveEntity method and control access at the service (not facade) level like this (with Spring security annotations here):
class EntityServiceImpl implements EntityService {
...
#PreAuthorize("hasPermission(#entity, 'write')")
public void saveEntity(Entity entity) {
repository.store(entity);
}
}
class EntityServiceFacadeImpl implements EntityServiceFacade {
...
#Transactional
public void saveEntity(EntityDTO dto) {
Entity entity = service.getEntity(dto.id);
entity.setName(dto.name);
service.save(entity);
}
}
The problem here is that the access control check happens already after I have changed the name of the entity, so that does not suffice.
How do you guys do it? Do you secure the domain object methods instead?
Thanks
Edit:
If you secure your domain objects, for example with annotations like:
#PreAuthorize("hasPermission(this, 'write')")
public void setName(String name) { this.name = name; }
Am I then breaking the domain model (according to DDD?)
Edit2
I found a thesis on the subject. The conclusion of that thesis says that a good way IS to annotate the domain object methods to secure them. Any thoughts on this?
I wouldn't worry about securing individual entity methods or properties from being modified.
Preventing a user from changing an entity in memory is not always necessary if you can control persistence.
The big gotcha here is UX, you want to inform a user as early as possible that she will probably be unable to persist changes made to that entity. The decision you will need to make is whether it is acceptable to delay the security check until persistence time or if you need to inform a user before (e.g. by deactivating UI elements).
If Entity is an interface, can't you just membrane it?
So if Entity looks like this:
interface Entity {
int getFoo();
void setFoo(int newFoo);
}
create a membrane like
final class ReadOnlyEntity implements Entity {
private final Entity underlying;
ReadOnlyEntity(Entity underlying) { this.underlying = underlying; }
public int getFoo() { return underlying.getFoo(); } // Read methods work
// But deny mutators.
public void setFoo(int newFoo) { throw new UnsupportedOperationException(); }
}
If you annotate read methods, you can use Proxy classes to automatically create membranes that cross multiple classes (so that a get method on a readonly Entity that returns an EntityPart returns a readonly EntityPart).
See deep attenuation in http://en.wikipedia.org/wiki/Object-capability_model for more details on this approach.
I've been trying to come up with a way to write generic repositories that work against various data stores:
public interface IRepository
{
IQueryable<T> GetAll<T>();
void Save<T>(T item);
void Delete<T>(T item);
}
public class MemoryRepository : IRepository {...}
public class SqlRepository : IRepository {...}
I'd like to work against the same POCO domain classes in each. I'm also considering a similar approach, where each domain class has it's own repository:
public interface IRepository<T>
{
IQueryable<T> GetAll();
void Save(T item);
void Delete(T item);
}
public class MemoryCustomerRepository : IRepository {...}
public class SqlCustomerRepository : IRepository {...}
My questions: 1)Is the first approach even feasible? 2)Is there any advantage to the second approach.
The first approach is feasible, I have done something similar in the past when I wrote my own mapping framework that targeted RDBMS and XmlWriter/XmlReader. You can use this sort of approach to ease unit testing, though I think now we have superior OSS tools for doing just that.
The second approach is what I currently use now with IBATIS.NET mappers. Every mapper has an interface and every mapper [could] provide your basic CRUD operations. The advantage is each mapper for a domain class also has specific functions (such as SelectByLastName or DeleteFromParent) that are expressed by an interface and defined in the concrete mapper. Because of this there's no need for me to implement separate repositories as you're suggesting - our concrete mappers target the database. To perform unit tests I use StructureMap and Moq to create in-memory repositories that operate as your Memory*Repository does. Its less classes to implement and manage and less work overall for a very testable approach. For data shared across unit tests I use a builder pattern for each domain class which has WithXXX methods and AsSomeProfile methods (the AsSomeProfile just returns a builder instance with preconfigured test data).
Here's an example of what I usually end up with in my unit tests:
// Moq mocking the concrete PersonMapper through the IPersonMapper interface
var personMock = new Mock<IPersonMapper>(MockBehavior.Strict);
personMock.Expect(pm => pm.Select(It.IsAny<int>())).Returns(
new PersonBuilder().AsMike().Build()
);
// StructureMap's ObjectFactory
ObjectFactory.Inject(personMock.Object);
// now anywhere in my actual code where an IPersonMapper instance is requested from
// ObjectFactory, Moq will satisfy the requirement and return a Person instance
// set with the PersonBuilder's Mike profile unit test data
Actually there is a general consensus now that Domain repositories should not be generic. Your repository should express what you can do when persisting or retrieving your entities.
Some repositories are readonly, some are insert only (no update, no delete), some have only specific lookups...
Using a GetAll return IQueryable, your query logic will leak into your code, possibly to the application layer.
But it's still interesting to use the kind of interface you provide to encapsulate Linq Table<T> objects so that you can replace it with an in memory implementation for test purpose.
So I suggest, to call it ITable<T>, give it the same interface that the linq Table<T> object, and use it inside your specific domain repositories (not instead of).
You can then use you specific repositories in memory by using a in memory ITable<T> implementation.
The simplest way to implement ITable<T> in memory is to use a List<T> and get a IQueryable<T> interface using the .AsQueryable() extension method.
public class InMemoryTable<T> : ITable<T>
{
private List<T> list;
private IQueryable<T> queryable;
public InMemoryTable<T>(List<T> list)
{
this.list = list;
this.queryable = list.AsQueryable();
}
public void Add(T entity) { list.Add(entity); }
public void Remove(T entity) { list.Remove(entity); }
public IEnumerator<T> GetEnumerator() { return list.GetEnumerator(); }
public Type ElementType { get { return queryable.ElementType; } }
public IQueryProvider Provider { get { return queryable.Provider; } }
...
}
You can work in isolation of the database for testing, but with true specific repositories that give more domain insight.
This is a bit late... but take a look at the IRepository implementation at CommonLibrary.NET on codeplex. It's got a pretty good feature set.
Regarding your problem, I see a lot of people using methods like GetAllProducts(), GetAllEmployees()
in their repository implementation. This is redundant and doesn't allow your repository to be generic.
All you need is GetAll() or All(). The solution provided above does solve the naming problem though.
This is taken from CommonLibrary.NET documentation online:
0.9.4 Beta 2 has a powerful Repository implementation.
* Supports all CRUD methods ( Create, Retrieve, Update, Delete )
* Supports aggregate methods Min, Max, Sum, Avg, Count
* Supports Find methods using ICriteria<T>
* Supports Distinct, and GroupBy
* Supports interface IRepository<T> so you can use an In-Memory table for unit-testing
* Supports versioning of your entities
* Supports paging, eg. Get(page, pageSize)
* Supports audit fields ( CreateUser, CreatedDate, UpdateDate etc )
* Supports the use of Mapper<T> so you can map any table record to some entity
* Supports creating entities only if it isn't there already, by checking for field values.