We often use simple enumerations to represent a state on our entities. The problem comes when we introduce behaviour that largely depends on the state, or where state transitions must adhere to certain business rules.
Take the following example (that uses an enumeration to represent state):
public class Vacancy {
private VacancyState currentState;
public void Approve() {
if (CanBeApproved()) {
currentState.Approve();
}
}
public bool CanBeApproved() {
return currentState == VacancyState.Unapproved
|| currentState == VacancyState.Removed
}
private enum VacancyState {
Unapproved,
Approved,
Rejected,
Completed,
Removed
}
}
You can see that this class will soon become quite verbose as we add methods for Reject, Complete, Remove etc.
Instead we can introduce the State pattern, which allows us to encapsulate each state as an object:
public abstract class VacancyState {
protected Vacancy vacancy;
public VacancyState(Vacancy vacancy) {
this.vacancy = vacancy;
}
public abstract void Approve();
// public abstract void Unapprove();
// public abstract void Reject();
// etc.
public virtual bool CanApprove() {
return false;
}
}
public abstract class UnapprovedState : VacancyState {
public UnapprovedState(vacancy) : base(vacancy) { }
public override void Approve() {
vacancy.State = new ApprovedState(vacancy);
}
public override bool CanApprove() {
return true;
}
}
This makes it easy to transition between states, perform logic based on the current state or add new states if we need to:
// transition state
vacancy.State.Approve();
// conditional
model.ShowRejectButton = vacancy.State.CanReject();
This encapsulation seems cleaner but given enough states, these too can become very verbose. I read Greg Young's post on State Pattern Misuse which suggests using polymorphism instead (so I would have ApprovedVacancy, UnapprovedVacancy etc. classes), but can't see how this will help me.
Should I delegate such state transitions to a domain service or is my use of the State pattern in this situation correct?
To answer your question, you shouldn't delegate this to a domain service and your use of the State pattern is almost correct.
To elaborate, the responsibility for maintaining the state of an object belongs with that object, so relegating this to a domain service leads to anemic models. That isn't to say that the responsibility of state modification can't be delegated through the use of other patterns, but this should be transparent to the consumer of the object.
This leads me to your use of the State pattern. For the most part, you are using the pattern correctly. The one portion where you stray a bit is in your Law of Demeter violations. The consumer of your object shouldn't reach into your object and call methods on it's state (e.g. vacancy.State.CanReject()), but rather your object should be delegating this call to the State object (e.g. vacancy.CanReject() -> bool CanReject() { return _state.CanReject(); }). The consumer of your object shouldn't have to know that you are even using the State pattern.
To comment on the article you've referenced, the State pattern relies upon polymorphism as it's facilitating mechanism. The object encapsulating a State implementation is able to delegate a call to whichever implementation is currently assigned whether that be something that does nothing, throws an exception, or performs some action. Also, while it's certainly possible to cause a Liskov Substitution Principle violation by using the State pattern (or any other pattern), this isn't determined by the fact that the object may throw an exception or not, but by whether modifications to an object can be made in light of existing code (read this for further discussion).
Related
I can specify a contract for an automatic property like this (example taken from the CC documentation):
public int MyProperty { get; set ; }
[ContractInvariantMethod]
private void ObjectInvariant () {
Contract. Invariant ( this .MyProperty >= 0 );
...
}
When runtime-checking is turned on, and an attempt is made to assign an invalid value to MyProperty, the setter throws System.Diagnostics.Contracts.__ContractsRuntime+ContractException.
Is there a way to make it throw a specific type of exception - typically, ArgumentNullException, ArgumentOutOfRangeException, or similar, without having to go back and implement the property manually using a backing field and Requires<> ?
No, there isn't.
But as long as your property setter is private, you don't have to worry about that. Any ArgumentException that would be thrown from your setter indicates a bug in the code calling that setter, and should be fixed there. The only code that can call your setter is your own.
If your property setter is protected or public, then you do need to specify which ArgumentException gets thrown for which values.
From the Code Contracts manual:
Object invariants are conditions that should hold true on each instance of a class whenever that object is visible to a client. They express conditions under which the object is in a "good" state.
There's a peculiar couple of sentences in the manual at the top of page 10:
Invariants are conditionally defined on the full-contract symbol [CONTRACT_FULL]. During runtime checking, invariants are checked at the end of each public method. If an invariant mentions a public method in the same class, then the invariant check that would normally happen at the end of that public method is disabled and checked only at the end of the outermost method call to that class. This also happens if the class is re-entered because of a call to a method on another class.
— text in brackets is mine; this is the compile time symbol the manual is referencing which is defined.
Since properties are really just syntactic sugar for T get_MyPropertyName() and void set_MyPropertyName(T), these sentences would seem to apply to properties, too. Looking in the manual, when they show an example of defining object invariants, thy show using private fields in the invariant contract conditions.
Also, invariants don't really communicate to consumers of your library what the pre-conditions or post-conditions for any particular property or method are. Invariants, again, only state to consumers of the library what conditions "hold true on each instance of a class whenever that object is visible to a client." That's all they do. In order to state that if an invalid value will result in throwing an exception, you must specify a pre-condition, which is demonstrated below.
Therefore, it would appear that in order to best achieve what you're looking for, it's as hvd says: it's best to have a private backing field and place the invariant on the backing field. Then you would also provide the contracts on the property getter/setter so that consumers of your library know what the pre-conditions and guaranteed post-conditions (if any) are.
int _myPropertyField = 0;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_myPropertyField >= 0);
}
public int MyProperty
{
get
{
Contract.Ensures(Contract.Result<int>() >= 0);
return _myPropertyField;
}
set
{
Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
_myPropertyField = value;
}
}
Now, there is another way to throw a specific exception using "legacy" code contracts (e.g. if-then-throw contracts). You would use this method if you're trying to retrofit contracts into an existing codebase that was originally written without contracts. Here's how you can do this without using Contract.Requires<TException>(bool cond):
Basically, in Section 5: Usage Guidelines of the manual, you'll be referencing Usage Scenario 3, legacy contract checking (see page 20). This means you need to set the following options in the Code Contracts project properties dialog:
Ensure that the Assembly Mode is set to Custom Parameter Validation.
Use "if-then-throw" guard blocks and perform manual inheritance.private
Ensure Contract.EndContractBlock() follows these guard blocks.
Check Perform Runtime Contract Checking and select the level of checking you want, but only on Debug builds—not on Release builds.
Feel free to use Contract.Requires(bool cond) (non-generic form) on private API methods (e.g. methods not directly callable by a library consumer).
Then, you could write the following code:
private int _myPropertyField = 0;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_myPropertyField >= 0);
}
public int MyProperty
{
get
{
Contract.Ensures(Contract.Result<int>() >= 0);
return _myPropertyField;
}
set
{
if (value < 0)
{
throw new ArgumentOutOfRangeException("value");
}
Contract.EndContractBlock();
_myPropertyField = value;
}
}
Now, you specifically stated that you didn't want to have to go back and create private backing fields for all of your properties. Unfortunately, if this is a public property than can be mutated, then there really is no way to good avoid this. One possible way to avoid this, though, is to make your setter private:
public int MyProperty { get; private set; }
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(MyProperty >= 0);
}
public SetMyProperty(int value)
{
// Using Code Contracts with Release and Debug contract checking semantics:
Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
// Or, using Code Contracts with Debug-only contract checking semantics:
Contract.Requires(value >= 0);
// Using Legacy contracts for release contract checking without throwing
// a ContractException, but still throwing a ContractException for
// debug builds
if (value < 0)
{
throw new ArgumentOutOfRangeException(nameof(value));
}
Contract.EndContractBlock();
MyProperty = value;
}
However, I must admit, I'm not really sure what you're gaining at this point by implementing invariants in this manner. You might as well just bite the bullet and use one of the first two examples I demonstrated above.
Addendum, 2016-02-22
The OP notes in their comment that Section 2.3.1 of the manual mentions that defining object invariants on auto-properties results in the invariant essentially becoming a precondition on the setter and a postcondition on the getter. That's correct. However, the preconditions that are created use the non-generic Contract.Requires(bool condition) form. Why? So that when invariants are used by those who don't want runtime contract checking turned on for their Release builds, they can still use invariants. Therefore, even if you use invariants on properties, if you want a specific exception thrown on contract violations, you must use full properties with backing fields and the generic form of Requires, which also implies that you want to perform runtime contract checking on all builds, including Release builds.
Let's say we have a template method that looks like this
abstract class Worker
{
public void DoJob()
{
BeforJob()
DoRealJob();
AfterJob();
}
abstract void DoRealJob();
}
subclasses that inherit from the Wroker classe should implemente the DoRealJob() method,
when the implementation is running under the same thread everything is fine, the three part of the DoJob() method get executed in this order
BeforJob()
DoRealJob()
AfterJob()
but when DoRealJob() runs under another thread, AfterJob() may get executed before DoRealJob() is completed
my actual solution is to let the subclasses call AfterJob() but this doesn't prevent a subclass from forgetting to call it, and we loose the benefit of a template method.
are there other ways to get consistent call order despite the fact the DoRealJob() is blocking or not?
You can't get both the simple inheritance(signature and hooking) and support asynchronous operations in your code.
These two goals are mutually exclusive.
The inheritors must be aware about callback mechanisms in either direct (Tasks, async) or indirect (events, callback functions, Auto(Manual)ResetEvents or other synchronization constructs). Some of them new, some old. And it is difficult to say which one will be better for the concrete case of use.
Well, it may look like there is a simple way with multithreaded code, but what if your DoRealJob will actually run in another process or use some remote job queuing, so the real job will be executed even outside your app?
So:
If you really consider that your class will be used as the basis for some
async worker, then you should design it accordingly.
If not - do not overengineer. You can't consider any possible
scenario. Just document your class well enough and I doubt that
anyone will try to implement the DoRealJob asynchronously,
especially if you name it DoRealJobSynchronously. If someone tries to
do it then in that case your conscience can be pristinely clean.
EDIT:
Do you think it would be correct if I provide both versions, sync and
async, of DoRealJob and a flag IsAsynchronous so I can decide which
one to call
As I have already said I don't know your actual usage scenarios. And it is unrealistic to consider that the design will be able to effectively handle all of them.
Also there are two very important questions to consider that pertain to your overall Worker class and its DoJob method:
1) You have to determine whether you want the DoJob method to be synchronous or asynchronous, or do you want to have both the synchronous and asynchronous versions? It is not directly related to your question, but it is still very important design decision, because it will have great impact on your object model. This question could be rephrased as:
Do you want the DoJob method to block any actions after it is called until it does its job or do you want to call it as some StartJob method, that will just launch the real processing but it is up to other mechanisms to notify you when the job has ended(or to stop it manually):
//----------------Sync worker--------------------------
SyncWorker syncWorker = CreateSyncStringWriter("The job is done");
Console.WriteLine("SyncWorker will be called now");
syncWorker.DoJob(); // "The job is done" is written here
Console.WriteLine("SyncWorker call ended");
//----------------Async worker--------------------------
Int32 delay = 1000;
AsyncWorker asyncWorker = CreateAsyncStringWriter("The job is done", delay);
Console.WriteLine("AsyncWorker will be called now");
asyncWorker.StartDoJob(); // "The job is done" won't probably be written here
Console.WriteLine("AsyncWorker call ended");
// "The job is done" could be written somewhere here.
2) If you want DoJob to be async(or to have async version) you should consider whether you want to have some mechanisms that will notify when DoJob finishes the processing - Async Programming Patterns , or it is absolutely irrelevant for you when or whether at all it ends.
SO:
Do you have the answers to these two questions?
If yes - that is good.
If not - refine and consider your requirements.
If you are still unsure - stick with simple sync methods.
If you, however, think that you need some async based infrastructure, then, taking into account that it is C# 3.0, you should use Asynchronouse Programming Model.
Why this one and not the event based? Because IAsyncResult interface despite its cumbersomeness is quite generic and can be easily used in Task-based model, simplifying future transition to higher .NET versions.
It will be something like:
/// <summary>
/// Interface for both the sync and async job.
/// </summary>
public interface IWorker
{
void DoJob();
IAsyncResult BeginDoJob(AsyncCallback callback);
public void EndDoJob(IAsyncResult asyncResult);
}
/// <summary>
/// Base class that provides DoBefore and DoAfter methods
/// </summary>
public abstract class Worker : IWorker
{
protected abstract void DoBefore();
protected abstract void DoAfter();
public IAsyncResult BeginDoJob(AsyncCallback callback)
{
return new Action(((IWorker)this).DoJob)
.BeginInvoke(callback, null);
}
//...
}
public abstract class SyncWorker : Worker
{
abstract protected void DoRealJobSync();
public void DoJob()
{
DoBefore();
DoRealJobSync();
DoAfter();
}
}
public abstract class AsyncWorker : Worker
{
abstract protected IAsyncResult BeginDoRealJob(AsyncCallback callback);
abstract protected void EndDoRealJob(IAsyncResult asyncResult);
public void DoJob()
{
DoBefore();
IAsyncResult asyncResult = this.BeginDoRealJob(null);
this.EndDoRealJob(asyncResult);
DoAfter();
}
}
P.S.: This example is incomplete and not tested.
P.P.S: You may also consider to use delegates in place of abstract(virtual) methods to express your jobs:
public class ActionWorker : Worker
{
private Action doRealJob;
//...
public ActionWorker(Action doRealJob)
{
if (doRealJob == null)
throw new ArgumentNullException();
this.doRealJob = doRealJob;
}
public void DoJob()
{
this.DoBefore();
this.doRealJob();
this.DoAfter();
}
}
DoBefore and DoAfter can be expressed in a similar way.
P.P.P.S: Action delegate is a 3.5 construct, so you will probably have to define your own delegate that accepts zero parameters and returns void.
public delegate void MyAction()
Consider change the DoRealJob to DoRealJobAsync and give it a Task return value. So you can await the eventual asynchronous result.
So your code would look like
abstract class Worker
{
public void DoJob()
{
BeforJob()
await DoRealJobAsync();
AfterJob();
}
abstract Task DoRealJob();
}
If you don't have .net 4.0 and don't want to us the old 3.0 CTP of async you could use the normale task base style:
abstract class Worker
{
public void DoJob()
{
BeforJob()
var task = DoRealJobAsync();
.ContinueWith((prevTask) =>
{
AfterJob()
});
}
abstract Task DoRealJob();
}
I found the following code on MSDN:
public class DisposeExample
{
public class MyResource: IDisposable
{
private IntPtr handle;
private Component component = new Component();
private bool disposed = false;
public MyResource(IntPtr handle)
{
this.handle = handle;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
CloseHandle(handle);
handle = IntPtr.Zero;
disposed = true;
}
}
~MyResource()
{
Dispose(false);
}
}
public static void Main()
{
MyResource obj = new MyResource()
//obj.dispose()
}
}
Now the confusion I have here is that, if I call obj.dispose, it disposes the objects created in the class MyResources i.e. handle, component etc. But does the obj also gets removed off the heap?? Same applies with the destructor. If I don't call dispose, the destructor will be called sometime. The code inside destructor removes the contained objects. But what about the obj?
Secondly, if I don't have a destructor defined inside the class and I dont even call dispose, does the GC never come into picture here?
IDisposable exists to remove unmanaged items from your managed objects. The runtime automatically provides a destructor, this destructor here has the sole purpose of releasing unmanaged items. As soon as your object goes out of scope or is set to null and has no more references to it will eventually be cleared by the GC.
The fundamental rule I'd recommend with with IDisposable is that at any given moment in time, for every object that implements IDisposable, there should be exactly one entity which has the clearly-defined responsibility of ensuring that it will get cleaned up (almost always by calling Dispose) before it is abandoned. Such responsibility will initially belong to whatever entity calls the IDidposable object's constructor, but that entity may hand the responsibility off to some other entity (which may hand it off again, etc.).
In general, I'd guess that most programmers would be best served if they pretended finalizers and destructors did not exist. They are generally only needed as a consequence of poorly-written code, and in most cases the effort one would have to spend writing a 100%-correct finalizer/destructor and working through all the tricky issues related to threading context, accidental resurrection, etc. could be better spent ensuring that the primary rule given above is always followed. Because of some unfortunate design decisions in the Framework and its languages, there are a few situations which can't very well be handled without finalizers/destructors, but for the most part they serve to turn code which would fail relatively quickly into code which will mostly work but may sometimes fail in ways that are almost impossible to debug.
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.
I know that the Specification pattern describes how to use a hierarchy of classes implementing ISpecification<T> to evaluate if a candidate object of type T matches a certain specification (= satisfies a business rule).
My problem : the business rule I want to implement needs to evaluate several objects (for example, a Customer and a Contract).
My double question :
Are there typical adaptations of the Specification patterns to achieve this ? I can only think of removing the implementation of ISpecification<T> by my specification class, and taking as many parameters as I want in the isSatisfiedBy() method. But by doing this, I lose the ability to combine this specification with others.
Does this problem reveal a flaw in my design ? (i.e. what I need to evaluate using a Customer and a Contract should be evaluated on another object, like a Subscription, which could contain all the necessary info) ?
In that case (depending on what the specification precisely should do, I would use one of the objects as specification subject and the other(s) as parameter.
Example:
public class ShouldCreateEmailAccountSpecification : ISpecification<Customer>
{
public ShouldCreateEmailAccountSpecification(Contract selectedContract)
{
SelectedContract = selectedContract;
}
public Contract SelectedContract { get; private set; }
public bool IsSatisfiedBy(Customer subject)
{
return false;
}
}
Your problem is that your specification interface is using a generic type parameter, which prevents it from being used for combining evaluation logic across different specializations (Customer,Contract) because ISpecification<Customer> is in fact a different interface than ISpecification<Contract>. You could use Jeff's approach above, which gets rid of the type parameter and passes everything in as a base type (Object). Depending on what language you are using, you may also be able to pull things up a level and combine specifications with boolean logic using delegates. C# Example (not particularly useful as written, but might give you some ideas for a framework):
ISpecification<Customer> cust_spec = /*...*/
ISpecification<Contract> contract_spec = /*... */
bool result = EvalWithAnd( () => cust_spec.IsSatisfiedBy(customer), () => contract_spec.IsSatisfiedBy( contract ) );
public void EvalWithAnd( params Func<bool>[] specs )
{
foreach( var spec in specs )
{
if ( !spec() )
return false; /* If any return false, we can short-circuit */
}
return true; /* all delegates returned true */
}
Paco's solution of treating one object as the subject and one as a parameter using constructor injection can work sometimes but if both objects are constructed after the specification object, it makes things quite difficult.
One solution to this problem is to use a parameter object as in this refactoring suggestion: http://sourcemaking.com/refactoring/introduce-parameter-object.
The basic idea is that if you feel that both Customer and Contract are parameters that represent a related concept, then you just create another parameter object that contains both of them.
public class ParameterObject
{
public Customer Customer { get; set; }
public Contract Contract { get; set; }
}
Then your generic specification becomes for that type:
public class SomeSpecification : ISpecification<ParameterObject>
{
public bool IsSatisfiedBy(ParameterObject candidate)
{
return false;
}
}
I don't know if I understood your question.
If you are using the same specification for both Customer and Contract, this means that you can send the same messages to both of them. This could be solved by making them both to implement an interface, and use this interface as the T type. I don't know if this makes sense in your domain.
Sorry if this is not an answer to your question.