Set of dynamic properties in domain-driven design - domain-driven-design

After through search i was unable to find any question which answers this, in my opinion fairly common design problem.
Given domain object:
public class Item {
private Long itemSN;
private String name;
methods, etc...
}
We need to store specific set of String properties which describes an item. It can be weight, color, sizes etc. System must be flexible and able to persist changeable list o properties. It needs to store allowed properties names, and preferably enforce some of them.
I tried several approaches, but concept of common constraints shared by all Item objects just don't fit in any standard domain model.
So i started to think about constraints as a form of configuration. Each Item has its's own properties (in simple String Map), constraints at the other hand are common configuration for all Items. So the next dilema emerged... how to express it without making big hole in domain model ?
It's easy to introduce additional application layer object to store constraints, but "allowed/required properites" are business affair, we need to allow domain user (manager of some sort) to change it, so its feels really horrible to draw this logic away from domain layer.
Any suggestions are welcome.
Edit 1.
After lot of brainstorming i managed to create valid object model for given situation. From first sight it was impossible to encapsulate properties with common constraints, but the latest out-of-domain implementation gave me an idea:
public class Item {
private Long itemSN;
private String name;
private List<Property> properties;
}
Core of the problem was solved here:
public class Property {
private Long propertyId;
private String propertyValue;
private Constraint constraint;
}
public class Constraint {
private String name;
private Boolean required;
private List<String> allowedValues;
}
So, each property have its value and constraint object which specifies name, allowed values and required status. This way constraint object can be shared by many properites, and any of this properties can have its own value.
It's adding some complexity to DB mapping and will hit performance but it's also keeping all domain logic in domain objects.
Any improvements, suggestions and opinions are welcome.

This problem can very reasonably be solved by the usage of annotations. Annotations allow you, the coder, to keep on using the language for the usage of properties by simply annotating your properties with constraints while still making it possible to apply the same constraints to user defined fields without the annotations.
JSR-349 is a Java standard for applying such constraints. Hibernate validator is a well known implementation.

Related

Usage of implementsInterface element on entities in guidewire

I would like to know why do we use implementsInterface element in entities. I know one example where they use it to make it as assignable entity. But I could not understand what other purpose and how/why it is being used in entities.
Example: Injuryincident entity has claimantsupplier and coveragesupplier interface
I like to see it from this prespective, simplified and assuming that you have some java background:
As you probably already know it, having an entity means in the end of the day, having a Java class... Well, by using the implementsInterface element in your entity, is similar to implement an interface in you java class.
Here you have a quick example...
Consider the following:
MyEntiti.eti
<?xml version="1.0"?>
<entity
xmlns="http://guidewire.com/datamodel"
entity="MyEntity"
table="myentity"
type="retireable"/>
AnInterface.gs
package mypkg
interface AnInterface {
function doSomething()
}
AnInterfaceImpl.gs
package mypkg
class AnInterfaceImpl implements AnInterface {
override function doSomething() {
print("Hello!")
}
}
Image that you need MyEntity to have the ability of "doSomething", you just need to add the implementsInterface:
<?xml version="1.0"?>
<entity
xmlns="http://guidewire.com/datamodel"
entity="MyEntity"
table="myentity"
type="retireable">
<implementsInterface
iface="mypkg.AnInterface"
impl="mypkg.AnInterfaceImpl"/>
</entity>
By doing that, the following code must work:
var myEntity = new MyEntity()
myEntity.doSomething() //this will call the method defined in the interface-implementation
And even better, you migth let you implementation to recognize the related object of MyEntity and use it as per your needs:
package mypkg
class AnInterfaceImpl implements AnInterface {
private final var _relatedEntity : MyEntity
construct(relatedTo : MyEntity) {
_relatedEntity = relatedTo
}
override function doSomething() {
var createUser = _relatedEntity.CreateUser // you can accees to whatever you need
print("Hello!, this is the related instace of MyEntity: ${_relatedEntity}")
}
}
Hope it helps, regards!
I won't be repeating the other answer describing how it works, but I would like to mention how implementing an interface on an entity is different (and serves different purposes) compared to using enhancements.
On basic level both approaches let you add extra functionality to your entity classes. In most cases what you really want to do is just create/expand an enhancement - they are easier to write, more convenient to modify and just as effective when all you want is to just add a new function or calculated property.
When you implement an interface, you're bringing in some more serious guns. While this approach takes more work and requires creation of several files (not to mention modifying the entity itself), it gives you two important advantages over the enhancement mechanism:
The same interface can be implemented by several entities (typically each having its own implementation class) as well as non-entity classes. Objects of all such classes can then be used interchangeably in contexts expecting the interface (you can create an array of entity instances of several entities and even gosu-only wrappers/temporary objects and present it comfortably in the UI).
You can leverage polymorphism. While enhancement functions can't be overridden, the interface implementations allow you full flexibility of polymorphic OOP. You can, for example, set up a default "do nothing" implementation on high level entity that you intend to use and then add more meaningful implementations for specific subtypes meant to really make use of the new functionality.
It does have some overhead and complicates things, however. As mentioned - Enhancements are typically simpler. In practice you should ask yourself whether the extra effort of creating and implementing the interface is worth it - in many cases even situations seemingly calling for polymorphism can be handled well enough by a simple switch typeof this in the enhancement to provide all the necessary type-based logic.
In personal experience I've used interfaces in quite a few situations, but Enhancements are my first choice in overwhelming majority of cases.
As a final note I'd like to mention a delegate entity. If what you want to add to some unrelated entities is not functionality but Properties with underlying database fields, creating a delegate entity and "implement" it with the desired standalone entities. A delegate entity does work a bit like an interface (you can use entity objects implementing the delegate interchangeably in situations where the delegate is expected) and you can set-up both interface implementation and enhancements on delegate level as well.

How to model inheritance on DDD?

I am currently trying out DDD and reading Evans book. I have arrived at a model that has an aggregate whose root is Student. Now I need to have (or be able to distinguish) a RegisteredStudent and an EnrolledStudent (inherits RegisteredStudent). I don't know how to handle inheritance in DDD.
Should the 2 inherited classes be inside the aggregate? If so, are they also considered aggregate roots since their identity is the same as the root (there are only added properties to them)? If not, how do I give access to them from other entities?
Or should I not be using inheritance? Why?
And also, what if you have an entity in an aggregate that isn't a root, but you need it to inherit an entity outside? How should you go about it?
What you need to ask yourself here is whether a RegisteredStudent and an EnrolledStudent are different concepts. Are they not both students, but just in a different state?
In general, you should favor composition over inheritance.
Here's an example of what I would do. (Note that it's just my example, I don't know the domain, so it's not a definitive solution).
You could have a Student class, which is your aggregate root and then a few different state classes: Registered and Enrolled. That way you don't need to expose these state classes on the student but you could just expose methods on the Student. A small example in C#:
class Student
{
State _currentState;
void Enroll()
{
if(!_currentState is Registered)
throw new InvalidOperationException("Cannot enroll student who is not registered");
this._currentState = new Enrolled();
}
void Register(string name)
{
this._currentState = new Registered(name);
}
}
class StudentState{}
class Enrolled : StudentState
{}
class Registered : StudentState
{
public Registered(string name)
{
Name = name;
}
public string Name {get; private set;}
}
This is a simple application of the State design pattern, you could externalize more parts of it and build a complete state-machine, but I'll leave that up to you. (Also it's typed directly in to the SO-editor, so there could be syntax errors)
EDIT after comments
Whether you need to expose a State-property or not depends on the context. In general I would recommend not to do that, because you're exposing the internals of the Student. It would be better to expose a method called CanEnroll for example. That way you can change the internal implementation of your state pattern without affecting any clients.
As for question 3, it's hard to say without a use case. However, here are some guidelines:
Favor composition over inheritance (again, I know).
You can have a reference from inside an aggregate to the outer world, you shouldn't have a reference the other way around though.

How to access certain EStructuralFeatures of an EMF Model?

I know that there are ways to access an EAttribute of an Eclipse EMF model by its featureID or by its name via different indirect approaches. For that I found the following: Eclipse EMF: How to get access EAttribute by name?
But what if I don't know the name of the attribute I want to get? Let's say, based on the design, the model has some fixed attributes by the developer, along with the features that can be set dynamically by the user.
So, for the time being I use the getEAllStructuralFeatures() and use indexes via get() to reach to the by-the-user-created attributes, since I know that the list I get will have the fixed attributes of the model as its first elements beginning with the index 0. But I find this solution unclear and inefficient. Also in some cases, that I want to work, not suitable.
E.g: IEMFEditProperty prop = EMFEditProperties.list(editingDomain, EMFMODELPackage.Literals.EMFMODEL.getEAllStructuralFeatures().get(X));
Do you know a solution or a workaround for this problem? As far as I can see, there are no direct methods to get such dynamically created features of the model.
Every help will be appreciated.
I have been working on a similar case recently where I first tried to define an EStructuralFeature to access exactly the setting/attribute of the object that I needed.
But if you look at how things work internally in ECore, you will find out, that there is no way this will ever work, since the indices are bound to the object identity of the EStructuralFeature objects created at runtime for the specific context (i.e. EClass instance).
My approach was then to either inspect the features proposed by EClass.getEAllStructuralFeatures or to iterate over the features and inspect the object returned by EObject.eGet for this very feature (where EClass eClass = eObject.eClass()).
Example: In a UML profile I have defined a UML Stereotype called "Bean" with a property called FactoryEntity. The property shall reference a UML Class with the Stereotype "Entity" that is closest to this very bean and for which a static factory method will be generated.
In the model I would then have one UML Class typed as Bean and one as Entity.
And for the Class typed as "Bean" I would then set a value for the attribute/property factoryEntity defined in the profile.
The question was then how the property value would be accessible in ECore. I ended up iterating the List of available EStructuralFeature of the EClass of the EObject and checking the type of the object returned by eGet.
final EObject eObject = (EObject) holdingClass.getValue(stereotype, stereoTypePropertyName);
final EList<EStructuralFeature> allEStructFeats = eObject.eClass().getEAllStructuralFeatures();
for(EStructuralFeature esf : allEStructFeats)
{
final Object o = eobject.eGet(esf);
if(o instanceof org.eclipse.uml2.uml.Class)
{
return (org.eclipse.uml2.uml.Class) o;
}
}
Maybe that is not the most elegant way to access structural features but it is the only one I thought was robust enough to last.
Please let me know if you have any suggestions on how to improve this.

How to create a multilingual domain model

I am using domain-driven design and I have a pretty clear picture of my domain model. It contains over 120 classes and it is quite stable. We will implement it in .NET 4 and C#. The thing is, we need the model to be multilingual; some of the attributes need to be stored in multiple languages. For example, the Person class has a Position property of type string which should store a value in English (e.g. "Librarian") and Spanish (e.g. "Bibliotecario"). The getter for this property should return the English or Spanish version depending on some language parameter.
And here begin my questions. I am not sure how to parameterize this. I have exlpored two major ways to do it:
Use property collections. Position would not be a string but rather a Dictionary<Language, string>, which would let clients retrieve the person's position by language.
Keep simple, scalar properties, but make them return (or set) the value for one language or another depending on a globally known "current language" setting. The client code would set the working language, and then all objects would set and get values in that language.
Option 1 avoids global state, but it messes up the interface of almost every class in my model. On the other hand, option 2 is less expressive, since you can't tell what language you're going to get without looking at the global setting. Also, it introduces a dependency into every class on the global setting.
Please note that I am not interested in database or ORM implementations; I am working at the domain model level only.
I have two specific questions then:
Which is the best option (1 or 2) to achieve my goal of a multilingual domain model?
Are there other options that I haven't considered, and which are they?
Thank you.
Edit. Some have suggested that this is a user interface related issue, and thus can be tackled through globalisation/localisation support in .NET. I disagree. UI localisation works only if you know the localised literals that must be shown to the user at compile time, but this is not our case. My question involves multilingual data that is unknown at compile time, because it will be provided as user data at run-time. This is not a UI-related issue.
Edit 2. Please bear in mind that the Person.Position is just a toy example to illustrate the question. It's not part of the real model. Don't try to criticise it or improve upon it; there is no point in doing that. Our business requirements involve a lot of attributes that cannot be encoded as enum types or similar, and must stay as free text. Hence the difficulty.
Given the following:
Some use case involve setting the values for an object in all the
supported languages; others involve looking at the values in one given
language.
I would suggest going for both options. That means that the Person and all classes that hold multilingual content should keep that content in their state and:
The Position property should set/get the person's position in the
current user's language.
There should be a corresponding property or method for all
language setting/getting.
There should be a method for setting (or even switching if needed)
the user language. I would create an abstract class (e.g.
BaseMultilingualEntity) with an abstract SetLanguage(Language
lang) method and a CurrentLanguage getter. You need to keep
track of all the objects that derive from BaseMultilingualEntity
in some sort of registry that would expose language setting.
EDIT WITH SOME CODE
public enum Language {
English,
German
}
// all multilingual entity classes should derive from this one; this is practically a partly implemented observer
public abstract class BaseMultilingualEntity
{
public Language CurrentLanguage { get; private set; }
public void SetCurrentLanguage(Language lang)
{
this.CurrentLanguage = lang;
}
}
// this is practically an observable and perhaps SRP is not fully respected here but you got the point i think
public class UserSettings
{
private List<BaseMultilingualEntity> _multilingualEntities;
public void SetCurrentLanguage(Language lang)
{
if (_multilingualEntities == null)
return;
foreach (BaseMultilingualEntity multiLingualEntity in _multilingualEntities)
multiLingualEntity.SetCurrentLanguage(lang);
}
public void TrackMultilingualEntity(BaseMultilingualEntity multiLingualEntity)
{
if (_multilingualEntities == null)
_multilingualEntities = new List<BaseMultilingualEntity>();
_multilingualEntities.Add(multiLingualEntity);
}
}
// the Person entity class is a multilingual entity; the intention is to keep the XXXX with the XXXXInAllLanguages property in sync
public class Person : BaseMultilingualEntity
{
public string Position
{
set
{
_PositionInAllLanguages[this.CurrentLanguage] = value;
}
get
{
return _PositionInAllLanguages[this.CurrentLanguage];
}
}
private Dictionary<Language, string> _PositionInAllLanguages;
public Dictionary<Language, string> PositionInAllLanguages {
get
{
return _PositionInAllLanguages;
}
set
{
_PositionInAllLanguages = value;
}
}
}
public class Program
{
public static void Main()
{
UserSettings us = new UserSettings();
us.SetCurrentLanguage(Language.English);
Person person1 = new Person();
us.TrackMultilingualEntity(person1);
// use case: set position in all languages
person1.PositionInAllLanguages = new Dictionary<Language, string> {
{ Language.English, "Software Developer" },
{ Language.German, "Software Entwikcler" }
};
// use case: display a person's position in the user language
Console.WriteLine(person1.Position);
// use case: switch language
us.SetCurrentLanguage(Language.German);
Console.WriteLine(person1.Position);
// use case: set position in the current user's language
person1.Position = "Software Entwickler";
// use case: display a person's position in all languages
foreach (Language lang in person1.PositionInAllLanguages.Keys)
Console.WriteLine(person1.PositionInAllLanguages[lang]);
Console.ReadKey();
}
}
A domain model is an abstraction - it models a specific part of the world, it captures the concepts of a domain.
The model exists so developers can communicate in code the way domain experts communicate - using the same names for the same concepts.
Now, a Spanish expert and an English expert may use different words for the same concept, but the concept itself would be the same (one hopes, though language can be ambiguous and people do not always understand the same concept in the same way, but I digress).
The code should pick one human language for these concepts and stick to it. There is absolutely no reason for the model to consist of different languages in order to represent a single concept.
Now, you may need to show users of the application data and meta data in their language, but the concept does not change.
In this regard, you second option is the thing you should be doing - with .NET, this is normally done by looking at the CurrentThread.CurrentCulture and/or CurrentThread.CurrentUICulture and by using satellite assemblies that will contain localized resources.
My question involves multilingual data
[...]
Please note that I am not interested in database or ORM
implementations;
I can see a bit of contradiction in these 2 statements. Whatever the final solution, you'll have multilingual-specific structures in your database anyway as well as a mechanism that queries them to do the translation, right ?
The thing is, unless your domain really is about translation, I would try to keep it away from multilingual concerns as much as possible, for the same reason that you would try to make your domain persistence ignorant or UI ignorant.
Thus I would at the very least place the multilingual resolution logic in the Infrastructure layer. You could then for instance use aspects to only attach multilingual behavior to some properties, if you really need a trace of multi-language in your entities and don't want your persistence layer to handle all that transparently :
public class Person
{
[Multilingual]
public string Position { get; set; }
}
It contains over 120 classes and it is quite stable.
Not directly related to question, but you might want to consider the existence of multiple bounded contexts in your domain.
I agree with Oded that it seems in your scenario, language is a UI concern. Sure, the domain may be declared via combination of C# and English, what it represents is abstract. The UI would handle language with CultureInfo.CurrentCulture - effectively option #2.
A Person entity having a Position property doesn't govern the natural language used to represent the position. You may have a use case where you'd want to display a position in one language while it is originally stored in another. In this case, you can have a translator as part of the UI. This is similar to representing money as a pair of an amount and currency and then converting between currencies.
EDIT
The getter for this property should return the English or Spanish
version depending on some language parameter.
What determines this language parameter? What is responsible for ensuring that, say Position, is stored in multiple languages? Or is translation to be performed on the fly? Who is the client of the property? If the client determines the language parameter, why can't the client perform the translation without involving the domain? Are there any behaviors associated with multiple languages or is this only a concern for reading purposes? The point of DDD is to distill your core behavioral domain and shifts aspects related to querying data into other areas of responsibility. For example, you can use the read-model pattern to access the Position property of an aggregate with a specific language.
Make the User explicit!
I already encountered domains where the user's culture is a first class citizen in the domain but, in such situations, I model a proper value object (in your example I would use a Position class properly implementing IEquatable<Position>) and the User that is able to express such values.
Sticking to your example, something like:
public sealed class VATIN : IEquatable<VATIN> { // implementation here... }
public sealed class Position : IEquatable<Position> { // implementation here... }
public sealed class Person
{
// a few constructors here...
// a Person's identifier from the domain expert, since it's an entity
public VATIN Identifier { get { // implementation here } }
// some more properties if you need them...
public Position CurrentPosition { get { // implementation here } }
// some commands
public void PromoteTo(Position newPosition) { // implementation here }
}
public sealed class User
{
// <summary>Express the position provided according to the culture of the user.</summary>
// <param name="position">Position to express.</param>
// <exception cref="ArgumentNullException"><paramref name="position"/> is null.</exception>
// <exception cref="UnknownPositionException"><paramref name="position"/> is unknown.</exception>
public string Express(Position position) { // implementation here }
// <summary>Returns the <see cref="Position"/> expressed from the user.</summary>
// <param name="positionName">Name of the position in the culture of the user.</param>
// <exception cref="ArgumentNullException"><paramref name="positionName"/> is null or empty.</exception>
// <exception cref="UnknownPositionNameException"><paramref name="positionName"/> is unknown.</exception>
public Position ParsePosition(string positionName) { // implementation here }
}
And don't forget documentation and properly designed exceptions!
WARNING
There are at least two huge design smells in the sample model that you provided:
a public setter (the Position property)
a System.String holding business value
A public setter means either that your entity exposes its own state to clients regardless of its own invariants, or that such a property has no business value for the entity and thus should not be part of the entity at all. Indeed, mutable entities should always separate commands (that can change the state) and queries (that cannot).
A System.String with business semantic always smells of a domain concept left implicit, typically a value-object with equality operations (that implements IEquatable, I mean).
Be aware that a reusable domain model is quite challenging to obtain, since it requires more than two domain experts and a strong experience in ddd modeling. The worst "domain model" that I faced in my carreer was designed by a senior programmer with huge OOP skills but no previous modeling experience: it was a mix of GoF patterns and data structures that, in the hope to be really flexible, proved to be useless. After 200k €, spent in that effort, we had to throw it away and restart from scratch.
May be that you just need a good data model directly mapped to a set of simple data structures in C#: you'll never have any ROI from an upfront investment in a domain model, if you don't really need it!
It might be worth mentioning Apache's MultiViews feature and the way it delivers different content based on the browser's Accept-Language header.
So if a user requests 'content.xml', for example, Apache will deliver content.en.xml or content.sp.xl or content.fr.xml or whatever is available based on some prioritization rules.
Given the requirements I would probably try to model the position as an entity/value on its own. This object would not be a dictionary of translations but rather just be usable as a key into a domainDictionary.
// IDomainDictionary would be resolved based on CurrentThread.CurrentUICulture
var domainDict = container.Resolve<IDomainDictionary<Position>>();
var position = person.Position;
Debug.Writeline(domainDict.NameFor(position, pluralForm: 1));
Now assuming you need to dynamically create new positions when a suitable synonym doesn't exist you could probably keep the data somewhat tidy by using the IDomainDictionary as an source for auto complete suggestions in the UI.

Domain driven design - How to check uniqueness of one property in domain object

I'm developing an application using domain driven design. One of the patterns I've been using is Repository pattern. For the sake of simplicity, let's say I have following classes and interfaces.
Car - domain class representing car domain concept.
public class Car {
public int Id {get;private set;}
public string SomeUniqueCode {get;private set;}
}
ICarRepository - interface for adding, deleting or saving changes to Car objects.
public interface ICarRepository{
Car AddCar(Car c);
void DeleteCar(Car c);
}
My problem is, how to check uniqueness of SomeUniqueCode property among all Car objects in the database? That property is changed by user (not auto-generated) at any time during the object life-cycle. Of course, one solution would be to put the unique key in the database, but that is not the principle of DDD. I've seen Specification pattern used to validate single objects. How would that pattern be applied to a set of Car objects?
Is it legitimate that Specification class (let's call it CheckUniqueCarSpecification) accesses ICarRepository?
A repository mimics an in-memory collection. What I have used before is a Contains method as opposed to a Find method, I guess you could have either. A query layer could also be used for this. Just as you have a CarRepository you could have a CarQuery. Trying to check for uniqueness in the domain is somewhat pesky. I would do a check for the sake of convenience but still rely on the DB to raise the exception since you should also handle that case. Using the specification pattern for this may be more effort than it is worth.
Since repository is a 'collection' I wouldn't have Commit and Rollback on there.
Use DomainService ICarCodesLibrary.
public class Car {
ctor(string someUniqueCode, ICarCodesLibrary codes)
{
// the check
codes.IsValidCode(someUniqueCode)
}
public int Id {get;private set;}
public string SomeUniqueCode {get;private set;}
}
Implement the interface in the place where u create the Car object and inject it. Also get rid of the properties and use fields. The ID is OK to be a prop.

Resources