As the point source of the full development process, requirements set the path, for the better or the worse, and well signaled crossroads along that path will clearly help.
Whatever the methodology, modeling processes can be mapped by a limited number of typical alternatives. Whereas some are fully set by technical contexts, critical ones are often rooted in requirements and subsequently govern the development course. The objective is therefore to identify archetypal crossroads and consistent signposts with rationale rooted at requirements.
Despite the attention given to the way requirements are expressed, few of the proposed solutions have taken into account an uncomfortable truth: requirements are not manna from heaven, in other words they do not come to the world as models.
As a prerequisite, it is necessary to distinguish business requirements from functional ones: the former deal with business concerns, the latter with the support provided by the system under consideration. The focus now is on functional requirements.
As they happen, neither words nor objects can be taken for granted: names may not be adequately fixed to objects, and objects may still waiting to be properly identified. Hence, requirements at their very beginning are just a flux of assertions, conditions and consequences, and the first aim of requirements analysis is to spin the threads and weave them into a fabric with clear and non ambiguous motifs, without making any prior assumption of what that may be.
Moreover, as the inception of a customer/provider transaction, requirements are by nature conflicting, informal, and subject to change. That doesn’t mean that requirements are necessarily captured as a lump of contradictory and ambiguous expectations; on the contrary, conflicting objectives must be clearly identified as well as options subject to reassessment. That is the second aim of requirements analysis.
Once dubious adornments and superfluous appendages have been cut off, core UML constructs are grounded on consistent and robust semantics. Hence the importance of a corresponding understanding of those constructs when archetypal crossroads call for direction:
- Functional or Non Functional ?
- Domain or Use Case ?
- Actual or Symbolic ?
- Power-type or Subtype ?
- Object, Aspect, or Attribute ?
- Attribute or Relation
- Aggregate or Composite ?
- Inheritance or Delegation ?
- Static or Dynamic Rule ?
- Milestone or Iterations ?
It must be noted that those signposts are not best practices but principled guidelines supporting clear-cut decision making.
Functional vs Non Functional
If the full model life cycle is to be traced back to requirements, and the spaghetti syndrome is to be avoided, a proper capture of requirements nature is clearly essential.
Whereas there is a broad consensus about functional requirements, namely how the system is expected to support business processes, opinions diverge regarding non functional ones, which range from standards to platforms and resources, with performances and security in between.
There is essentially three criteria to consider before setting a requirement apart as non functional:
- User experience: can the requirement under consideration be assessed by business users.
- Footprint: can the requirement be factored out and dealt with independently of any specific use case.
- Authority: is the requirement to be managed by a separate organizational unit.
The first two criteria can be decided in relation to established functional requirements, the third one is a matter of policy: defining some requirements as non functional put them under the authority of a separate organizational unit with its own agenda and decision making capacity.
Domain vs Use Case
Business domains (aka domains) describe the semantics and consistency rules of interrelated business objects whose persistency has to be managed as a whole independently of their use. Semantics and consistency rules must be set by a single authority.
Use cases (aka application domains) describe how a system is expected to support a business activity triggered by a single event and identified by a self contained objective.
Whereas initial requirements may present a mixed view of business and application domains, a cross analysis of business processes and objects may help to sort things out; taking advantage of CRUD matrices usually supported by requirements tools, two criteria should be used:
– Separation of concerns: domain perimeters are meant to be set by Create and Delete operations, use cases by Read and Update. Overlaps are to be reduced by the separation of concerns.
– Separation of responsibilities: domains and use cases perimeters should coincide with the access rights of actors.
That would translate into a two-staged procedure: a first stage for identification based upon primary entities or triggering events, a second stage for refinement based upon the singling out of responsibilities and rules enactment.
Those principles are enacted by DDD (Domain Driven Development) methodologies and the CQRS (Command and Query Responsibility Segregation) design pattern.
It must be noted that those principles put special relevance to the definition of agents and the roles they are entitled to play as actors. And since that is clearly an organizational matter, it can be set fully and precisely upfront with requirements.
Actual vs Symbolic
As illustrated by the emergence of 3D printing in manufacturing, the distinction between symbolic and actual artifacts is not as straightforward as it used to be. Moreover, that distinction may be critical for system modeling when architecture design is all about decisions between hardware and software.
To begin with, artifact semantics must be stated explicitly for actual or symbolic objects or activities. Yet, while symbolic artifacts will always be necessary (computers are meant to process symbolic data), that is not the case for actual ones whose description is only required when coupling constraints are to be supported, namely:
- When active objects interact with the system using non symbolic languages. In that case actual objects and their symbolic counterparts must be modelled simultaneously in order to specify functional boundaries and the associated coupling constraints.
- When the system must keep track of the state of actual activities. In that case activities and flows (data and control) will have to be associated with state machines describing actual execution and time synchronization.
While actual objects may or may not require state modeling (gates do, meters don’t), their explicit modeling must be justified by some actual interaction (capture of gates position or bell alarm).
Power-type vs Subtype
Power-types define partitions, each instance being associated with subsets of targeted populations to which they provide shared values for selected attributes. Subtypes describe additional features specific to subsets of targeted populations.
A sound procedure is therefore:
- Begin with partitions.
- Proceed with power-types if targeted objects are fully described by the same set of features.
- Introduce subtypes when some subsets make use of specific features.
Object, Aspect, or Attribute
The purpose of analysis models is to define the symbolic objects that will represent the actual business objects and activities. That calls for three levels of granularity:
- At the root one will need persistency and execution units whose identity is to be used to anchor symbolic representations to their actual counterparts, either persistently or until activity completion. For instance, repairs are actual processes ordered by actual customers.
- One level down, aspects are functional units meant to represent roles whose continuity and consistency can be described independently of the associated units. For instance, transactions regarding delivery or bills can be conducted by the owner or his representatives; and invoice can be computed independently.
- Finally, attributes are descriptions of formats and semantics used to describe the features of objects or aspects.
Whereas setting attributes apart should be straightforward considering they are meaningless on their own, that nonetheless must be checked against business concerns: addresses are usually seen as attributes when associated to customers, yet are definitively business objects for courier or real estate companies.
Distinguishing between objects and aspects is not always straightforward as it entails organizational considerations. Yet, those requirements can usually be expressed through identification and functional dependencies:
- Aspects or roles are not necessarily bound to actual objects or agents; e.g, one may manage a property’s insurer independently of actual incumbents, with the possibility of obligations being transferred between insurers.
- Functions are not necessarily bound to execution units; e.g, indemnities may be computed on a standalone basis, independently of specific contracts.
Attribute vs Relationship
Modeling objects and relations with graphical editors may blur the line between business requirements (aka CIMs) and system analysis (aka PIMs); yet the alternative between attributes and relationships must be decided on the basis of:
- Formal analysis of functional dependencies (normalization along relational theory).
- Business needs: attributes can be used on their own contrary to relationships which remain useless until the referenced object can be fetched (denormalization).
It must be noted that decision can (even should) be made upfront with business requirements, e.g a bank clerk who needs to fetch all the customer file or can do with his last year income. Yet, while it’s purely computation independent, it’s nonetheless critical for architecture design.
The same reasoning can be extended to other connectors, e.g when deciding if an activity is described as a local operation (as for an attribute) or delegated through a flow (as for a relationship).
Aggregate vs Composition
While modeling languages (e.g UML) or methods (e.g DDD) provide good notations and principles to describe how artifacts are connected, the focus is usually on design, with the risk of introducing some bias in requirements. Hence, before deciding if different aspects of objects are to be stored together or separately (design perspective), it is necessary to describe how they are connected (analysis perspective). And that can be achieved using standard connectors with functional stereotypes.
Taking Scrum for example, products, sprints, and releases share a common identity and can therefore be represented by a UML composite or DDD aggregates. While both descriptions are correct, the former may induce a poor design and the latter compels business analysts to consider implementation details.
Inheritance vs Delegation
Analysis is all about making distinctions out of differences. One step further, those variants will have to be represented by symbolic descriptions of structural and functional specializations:
- Structural specialization add extensions to base types, using inheritance of features and behaviors to describe instances. Inheritance may be introduced through two very different operations, namely specialization or generalization, and , as already mentioned, generalization should only be used when consolidation is necessary.
- Functional specialization deals with behaviors and therefore can be achieved through delegation, without taking into account object structures.
If requirements are to be neutral regarding their subsequent symbolic representation they must remain closely associated to actual business objects and processes. As a corollary, subtypes should be defined from subsets, as opposed to abstraction levels which are meant to be introduced at a later stage. Along the same reasoning, the nature of variants must be clearly established either as structural (different features of persistent objects) or functional (different operations of transient objects). Those can be achieved using roles:
- Both specialization can be uniformly described by subtypes of objects (structural) or roles (functional).
- Since inheritance of structural features is bound to identities, multiple structural inheritance is not possible.
- Role inheritance, simple or multiple, can be transformed into delegation without modifying requirements semantics.
Static vs Dynamic Rules
Rules are the flesh of requirements, pervading every corner as they span bridges across objects and processes. Their sheer ubiquity makes them difficult to capture and to fasten to specific targets. As already noted, rules can be analyzed along two criteria, target and enforcement:
- Structural rules and constraints target business objects, functional rules target business processes. While the former can be enforced both by persistency or execution units, the latter can only be supported by execution units.
- Rules, structural or functional, can be enforced as conditions (before objects are updated or actions executed) or as consequences (after objects are updated or actions executed).
Since the way business rules and constraints are implemented may significantly impact on system architecture, their expression must be kept neutral and strictly adhere to the necessary restrictions. Hence, as a complement to functional stereotypes and rule patterns, a number of generic principles should be applied:
- Rules and constraints on persistency units must be set apart from those on execution units (a).
- Rules and constraints on occurrences of persistency or execution units must be set apart from those dealing with their local consistency (b).
- Rules and constraints must be set at the lowest possible level: domain/use case, collection, persistency/execution unit, attribute/operation (c).
- Rules and constraints on connectors must be expressed using functional stereotypes (identification, exclusion, inclusion, etc) instead of numeric cardinalities (d).
As it happens, those principles deal with rules targeting symbolic objects representing persistency or execution units. While they do cover time constraints, they don’t take into account synchronization constraints associated with to objects representation or processes execution. For that purpose it will be necessary to introduce external eventsexplicitly and redefine rules accordingly.
It must be reminded that triggering rules tied to symbolic units (persistent or transient) can be defined independently of external events whatever their subsequent event-driven implementation.
Milestone vs Iterations
Behind the (often ineffectual) debate between waterfall and agile proponents, the problem it to set milestones when and where it is necessary to validate project deliverables or consolidate them with associated ones. If agile principles are to be heeded, such decisions should clearly be made on a case-by-case basis: sequencing is required when the footprint of a decision overlap the ones managed outside the project, otherwise iterative development is to be the organization of choice.
If development sequencing is to be based on requirements, functional and technical dependencies must be identified upfront in order to fence the areas within which iterations can be safely conducted.
Analysis, Patterns, Anti-Patterns
Requirements analysis (RA) goes in both directions, forward as projects use patterns to set their path, and backward as crossroads are checked for anti-patterns.
As a forward modeling process RA sieves through requirements looking for anchors identified by persistency or execution units. Those anchors will be refined along stereotyped structures, and serve as roots to primary threads weaved according to semantic patterns.
Requirements analysis can also proceed backward to review the outcome and check for completeness and consistency. The proportion of stereotyped artifacts provide a straightforward measure of completeness, with their consistency easily checked. Crossroads along primary threads can also be reviewed and checked for anti-patterns.