'FAQ - What is a Software Factory?' described what a 'product line' is, and discussed how the variants of the product line are basically defined. In this article, we want to dig a little deeper into what is variability, and how you define your product variants.
What is Variability?
So, each product that your factory creates will have certain aspects of it that can be variable, by changing these aspects you get a different 'product variant'. Maybe, these aspects are behavioural, maybe they are architectural. Either way, the factory needs to offer a means to specialise the product instance to suit certain end-requirements. Each aspect of the product that varies defines a point of variability of the product. So, if you configure this point of variability you end up with a different 'product variant' by definition.
So, you wouldn't go ahead and create two factories that created almost the same thing, if those two things if those two factories could define the same variability point for the same solution domain. Instead your factory would identify that its product instances share some common logical architecture and maybe only vary in appearance, behaviour, or even in physical architecture. Your factory would then define a shared logicalmodel of the product and offer a means to configure the variable aspects of it.
Now, a certain number of the variants will share the same set of configuration for a given set of variability points. You start to define the common product types your factory creates. You no longer require your factory user to define every single variable point, you can simply provide them a 'template' (a type) that fixes some of the variability points to known values, leaving the other variability points for specialisation.
I need to emphaise that at this point, we are not talking about the variance of the physical instance of the product (source code etc.), we are talking about the variance in the logical model of the product. The degree to how much the physical representation differs from the logical model will depend on the abstractions offered by the factory. It is feasible that there are many physical representations for the same logical model that differ by the configuration of the model.
Your factory's 'solution domain' is bounded by the product variants your factory makes. Although not precisely accurate, (depends on your factory) your logical product model defines your solution domain too.
How to Identify variability?
So, how do you identify the points of variability in your product?
There is plenty of information on the web about the practice of Commonality and Variability Analysis (CVA) which is basically how you identify what varies in your product and to what extend it varies.
The key pieces of variability to identify are logical architectural variance and variance in the components of logical architecture.
Interestingly enough, if you are building a factory from an existing framework, this practice has already been employed to a certain extent, as this is one of the steps taken to get from implementation to class library and then to framework.
How to Represent Variability
Once you have your points of variability, the next question is how to represent them in your product model.
In the simplest case, a point of variability could be represented in your model as a configuration setting: such as an integer for the number of cyclinders of the engine, or perhaps as a set of configuration settings, which may be defined for one or more elements in the model.
In more complex case you may need a slighly enhanced logical architectural model, to represent a different product type: such as, one model for the petrol engine, one for the diesel engine.
The art of defining the product model is identifying what is the minimal set of variability points, and hence their configurations or architectural representations, you need to define the types of the product variants in your solution domain.
How to Use/Abuse Variability
We said before that the best factories will be those with a highly specialised domain, and those with the best implementations for that domain. The question is how to define that domain and still create a successful factory?
I know - you just can't wait to break down your solutions into a product and types, and the possibilities are endless on the variability you can model - right?!?
Now here is the problem. Given any solution it is conceivable, in most cases, to decompose the solution, identify the product variants of ever finer granularity of variability, and define extensive configuration or models to address that variability. After a time, your model has so much variability it starts to look like a programming language. After all, high level programming languages are essentially a low level form of configuration – aren't they? Using this approach would yield a factory with a huge number of variability points, which results in potentially large product line, and therefore - a very generic factory!!!
You might initially think this is ideal? Well as it turns out - yes, it may appear to be ideal - except when you realise that this approach is not far from where we are today with a generic solution authoring tools like programming languages and class libraries.
The problem is that as the number of variability points increases, so do the number of possible variants, and therefore, so do the number of paths you can take to configure any given variant, and since its highly configurable how do you keep control of which variant you are working towards at any given time? And with all that configuration, it's very hard to validate and control the values of interdependent configuration. Not to mention, the amount of time it takes and the complexity to configure this model for the factory users.
It's exactly the same issue that we have with generic frameworks/libraries today – 'they create everything useful and nothing useful - all at the same time' and everyone has their own way to do it and much of it is unverifiable due to the large number of possibilities.
The other side-effect of this approach, on the solution side, is that it's very hard, if not impossible, for your factory to provide specific optimised solutions for you products if you have to cater for so many variants of them. (No single factory author nor tool can possess that many domain specific skills, experience, knowledge to create the most optimal solution to such a large set of variants).
Another way to look at this: - your factory is doing little to provide known specialised solutions to known specific problems, so why would anyone want to use it?
You want to beware of those factories that claim to create *anything* you want, or where the product line is very large.
It's all about being a specific and as highly specialised as you can, which means you are creating a small set of very high quality products. To be successful, your factory needs to provide highly specialised, proven solutions to known specific problems that accommodate some variability for customization.
The most successful, and hence most attractive factories, will be the ones that have a narrow well-defined domain (i.e. a small number of product variants). The physical solutions will be built by the best people, most experienced and skilled that solution domain.
I dislike to over-use automobile industry analogies, but they can be useful sometimes.
Have you ever wondered why the highest quality car manufacturers in the world only create a small number of high precision models tailored for certain markets?
The car manufacturers that make 'normal' cars, (for folks like you and me ), create the 'baseline' products (like the chassis with wheels and engines). Then other factories that tailor them to a given market, which only really add the bodywork, paint and interior, and ornament, depending on the size of your pay-check.