Search code examples
design-patternsdomain-driven-designsmalltalkspecification-pattern

How to implement isGeneralizationOf with the composite specification pattern?


I am trying to implement the composite specification pattern, as per the Specifications Document by Fowler and Evans.

At first impression, I thought the implementation of isGeneralizationOf would be different for conjunction and disjunction.

In particular, I thought the logic for conjunction would be

(1) Let specX be the conjunction of specA and specB. Then, specX is a generalization of specC only if both specA and specB are a generalization of specC.

And I thought the logic for disjunction would be

(2) Let specY be the disjunction of specA and specB. Then, specY is a generalization of specC if either specA or specB is a generalization of specC.

However, on page 16 of the document , they show this method:

CompositeSpecification >> isGeneralizationOf: aSpecification
"True if each component is subsumed. False if any component is not subsumed."
^ (self components contains:
        [:each |(each isGeneralizationOf: aSpecification) not ]) not

Is my reasoning in (1) and (2) correct? If it's wrong, why is that? If it's correct, then why did the authors define a single method to be inherited by both conjunction and disjunction specifications? What is their intent here?


Solution

  • Examples:

    The following models: the spec "a AND b" is specialization of "a OR b"
    
    ({a,b} isSpecializationOf: {a}) & ({a,b} isSpecializationOf: {b})
    -> true
    
    This following models: the spec "a OR b" is specialization of "a AND b"
    
    ({a} isSpecializationOf: {a,b}) | ({b} isSpecializationOf: {a,b})
    -> false
    

    You can get the syntax this nice in Squeak if you first define the objects a and b, since {} is a special syntax for dynamic array literals (define isSpecializationOf: in class Array).