--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
The two things have nothing to do with each other. A repository loads your aggregate root (by whatever means). A specification is useful for business rules. I find them to be a really clean method of ensuring invariants in a system. say a command comes into your aggregate and you need to check if something exists. pseudo ` void Handle(Deposit deposit){ if(Try(Specifications.AccountExists(accountId).And(Specifications.AccountInGoodStanding(acountId))) RaiseEvent(new DepositAccepted(…) else Reject(deposit); } ` of course, you can maintain those specifications in other files to keep your aggregates cleaner. /end ramble. |
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
How are specifications in this sense different from validation?
I guess when I read about specifications in the past I took them to be primarily used to filter down an existing list, such as to find a suitable type of plant for partial shade that has red flowers (and..)
I should note that I don't use any in my application so I'm talking mostly from a theoretical stance.
You're right. Those in pseudo code were just static. In my system, the objects behind those static methods are indeed specifications. That and this was not real ;) |
yes sorry autocorrected.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
--Studying for the Turing test
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
Again, that was pseudo code and, admittedly, a bad example. Yes. My code looks like that. But behind the static assertions are real specifications. Maybe I should shut my trap around these parts ;) |
> I use specification pattern to validate business logic> Assert<ProjectIsSubmitted>()Are you sure that you need to call it "specification" in that meaning as Evans did? Looks like simple static assertion.
On Saturday, December 12, 2015 at 9:51:55 AM UTC+3, Kirill Chilingarashvili wrote:I use specification pattern to validate business logic in command methods in my aggregate.I have set of reusable specs like IsNew, IsNotNew, then next level of reusable specs within domain like ProjectIsSubmitted, AccountRegistrationCompleted etc.Then I was writing spec per aggregate operation, but then I realized that spec per operation does not make sense if you dont reuse it, so I write business specs inline for that cases.so the code is like:Assert<IsNotNew>();Assert<ProjectIsSubmitted>();I reuse specs in testsI found interesting way of reusing same specs in UI.For example there is a command named "SubmitProject"I can move command validation into separate spec "CanSubmitProject"I then can reuse it- as command guard- for probing condition in tests- for probing whether the function is available to interested parties (UI)I just not feel comfortable with last because to probe it I need to fetch aggregate, so I think the spec should be written to test some interface containing state needed for spec, and then implement it on aggregate/read model
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
so yes, I think it does implement what was meant in blue book
class Person
{
private int Age
public void BuyWine(int amount)
{
Assertion.greatOrEqual(Age, 18); // or even Assertion.true(Age.isAdult());
// ...
}
}
public class AccountInGoodStandingSpec implements Specification<int> {
@Value("${accounts.healthythreshold}")
BigDecimal accountHealthyThreshold;
@Inject AccountRepository repository;
public boolean isSatisifed(int accountId) {
// etc etc
}
}
public class AccountDepositRules {
@Bean Specification<int> canDepositAccountSpec(AccountExistsSpec accountExistsSpec, AccountInGoodStandingSpec accountInGoodStandingSpec) {
return and(accountExistsSpec, accountInGoodStandingSpec);
}
}public class DepositHandler {
@Inject Specification<int> canDepositAccountSpec;
public void handle(Deposit deposit) {
if(canDepositAccountSpec.isSatisfied(accountId)){
// etc etc
}
}
}DepositHandler is decoupled (not just abstracted) from the exact business rules required to determine whether a deposit can be made. These two responsibilities often even belong to different components (or even services).Suffice to say, this is not a very common pattern for day-to-day if-else situation. Only in complex business rules that require a degree of decoupling and flexibility, commonly used in frameworks such Business Rule Engine or ESB, e.g. Message Router (http://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageRouter.html) in Mule or Camel could be implemented using specification pattern.
So again, adopting this pattern is mostly relevant only when you're writing a framework like Linq, rx, BRE, or ESB, where you need to externalise rules from the executions. But if you just need to execute a direct if-else, I don't see a point of implementing specification pattern that's only executed directly (i.e. you're not decoupling anything).