Wed Oct 8, 2003 5:48 am
Hi,
I am wondering if you can consider this problem and share your thoughts. I am
working on some software to track residues on crops for a argi-business company. I am working in a key area that deals with Analysis of the residues. In an area called Workbench, an A
nalysisRun is defined. This contains a list of Samples that will need to be analysed. The analysis takes place on an
Instrument. From the outset, the packaging was done for me, and was at the
application level - Workbench, Sample Management, Instrument Interfaces, etc. Instrument Interfaces requires a structure that is similar to the one in Workbench:
Instrument Interface:
+-----+ +-----------+ +--------+
| Run |-------->| Injection |Analyte |------->| Result |
+-----+ 0..*+-----------+ +--------+
Workbench:
+--------------+ +--------+ +--------+
| Analysis Set |-------->| Sample |Analyte |------->| Result |
+--------------+ 0..*+--------+ +--------+
But, in Workbench a Run is known as an Analysis Set, composed of Samples. There
is other information on a Sample object specific to Workbench. In Instruments, an Analysis Set is a Run and the Sample is an Injection. Structurally, an Analysis Set and a Run look the same, but there are differences - a Sample Name on a Sample is known as a VialID on an Injection.
While I was away, what has happened is that a new .NET Assembly has been
created, with the core of Workbench/Instrument Interface. I believe the idea was to extend the classes in the Workbench and Instrument domains. This is kinda like the Abstract Core. Trouble is there are two major reasons
for why these interfaces might change - requirements from Workbench or
Instrument Interfaces.
After sitting down and remodelling the problem, i started to think that maybe
while the concepts seem the same, they in fact arent. Workbench has its concept of a run, known as an Analysis Set. There are a whole number of other things (attributes and operations) that need to be added to the classes that make up the Analysis Set, that are irrelevant to Instrument Interfaces. So as a team
we have arrived at the following solution: accept that conceptually the two
distinct parts of the system have similar classes, but they are not the same. We will introduce a Mapper between Workbench and II that will convert an Workbench:
:AnalysisSet into a II:Run. The mapper is dependant on both areas, but we can ignore the II layer within Workbench now, which makes our
model much clearer.
When we started, the model was small and everything was in the same
assembly/component. As things have grown, the dependancies have become troublesome. On another note, we originally had class A--->B and it seemed like a correct domain association. Class A moved into its own DLL and B
moved into another. We didnt want to associate a class->class across component
boundaries, but the reality is that A--->B. What do yu do in this situation? The architect wanted to remove the link and use a facade. This is fine, but the model doesnt reflect reality.
Thanks for any comments.
`Nick Robinson`
> Hi,
>
> I am wondering if you can consider this problem and share your thoughts. I > am working on some
> software to track residues on crops for a argi-business company. I am > working in a key area that
> deals with Analysis of the residues.
Thanks for giving a specific description of the domain you are working in. Useful domain modeling requires understanding of the concrete situation and the application. Even so, I don't fully understand your domain, so take what I say with a grain of salt.
> In an area called Workbench, an AnalysisRun is defined.
> This contains a list of Samples that will need to be analysed. The analysis takes place on an
> Instrument. From the outset, the packaging was done for me, and was at the application level -
> Workbench, Sample Management, Instrument Interfaces, etc. Instrument Interfaces requires a
> structure that is similar to the one in Workbench:
> Instrument Interface:
+-----+ +-----------+ +--------+
| Run |-------->| Injection |Analyte |------->| Result |
+-----+ 0..*+-----------+ +--------+
> Workbench:
+--------------+ +--------+ +--------+
| Analysis Set |-------->| Sample |Analyte |------->| Result |
+--------------+ 0..*+--------+ +--------+
> But, in Workbench a Run is known as an Analysis Set, composed of Samples. There is other
> information on a Sample object specific to Workbench. In Instruments, an Analysis Set is a Run
> and the Sample is an Injection. Structurally, an Analysis Set and a Run look the same, but there
> are differences - a Sample Name on a Sample is known as a VialID on an Injection.
I would have a conversation with people who use the software to clarify these terms. Are these different words for the same thing or are they different things. Have them define the terms. Talk through different scenarios. In my opinion, spoken language is the most subtle tool we have for exploring models. The subtleties of models often come out in persistent conversation. (Warning, the conversation might be a little annoying to them if they don't understand why you are so particular about the meanings of minor phrases!) :-)
> While I was away, what has happened is that a new .NET Assembly has been created, with the core of
> Workbench/Instrument Interface. I believe the idea was to extend the classes in the Workbench and
> Instrument domains. This is kinda like the Abstract Core. Trouble is there are two major reasons
> for why these interfaces might change - requirements from Workbench or Instrument Interfaces.
> After sitting down and remodelling the problem, i started to think that maybe while the concepts
> seem the same, they in fact arent.
Aha. Probably not. The fun part of all this is looking for abstractions that more precisely describe each part. For example (and remember I don't know your domain, I'm just giving an example), although you think of a sample and an injection as the same thing, they aren't quite. The instrument sits there and gets injected with some stuff, which it analyzes in a particular way and returns a result. It presumably doesn't know the experiment it is a part of. In that experiment, sets of samples are collected and analyzed. Part of that analysis is injection of the material into an instrument and collecting the result. The "analysis" of the instrument is presumably narrower and only a part of the "analysis" of the experiment (the workbench?).
Or, maybe the machine is doing most of the work and the two really do map together, in that case, the workbench is just a sort of wrapper over an instrument run, where some extra tracking is done, or whatever. If that is the case, maybe you could find a way to get rid of the Sample and the workbench result and just use the instrument ones. Or maybe they are important wrappers too. Gosh, I just don't know enough.
> Workbench has its concept of a run, known as an Analysis Set.
> There are a whole number of other things (attributes and operations) that need to be added to the
> classes that make up the Analysis Set, that are irrelevant to Instrument Interfaces. So as a team
> we have arrived at the following solution: accept that conceptually the two distinct parts of the
> system have similar classes, but they are not the same.
Ok, so now you seem to be going a different direction. You've defined them as bounded contexts with their own models. They can model the same things in their own way and you will translate. This may be the right thing to do. It can side-step the need to work out the subtle differences between the models except at the specific points of contact, where you have your translation...
> We will introduce a Mapper between
> Workbench and II that will convert an Workbench: :AnalysisSet into a II:Run. The mapper is
> dependant on both areas, but we can ignore the II layer within Workbench now, which makes our
> model much clearer.
Well, if it makes your model much clearer, then probably you made the right decision.
> When we started, the model was small and everything was in the same assembly/component. As things
> have grown, the dependancies have become troublesome. On another note, we originally had class
> A--->B and it seemed like a correct domain association. Class A moved into its own DLL and B
> moved into another. We didnt want to associate a class->class across component boundaries, but
> the reality is that A--->B. What do yu do in this situation? The architect wanted to remove the
> link and use a facade. This is fine, but the model doesnt reflect reality.
This is hard to talk about in the abstract.
`Eric Evans`
> Hi,
>
> I am wondering if you can consider this problem and share your thoughts. I > am working on some
> software to track residues on crops for a argi-business company. I am > working in a key area that
> deals with Analysis of the residues.
Thanks for giving a specific description of the domain you are working in. Useful domain modeling requires understanding of the concrete situation and the application. Even so, I don't fully understand your domain, so take what I say with a grain of salt.
NR> Thats cool.
> In an area called Workbench, an AnalysisRun is defined.
> This contains a list of Samples that will need to be analysed. The analysis takes place on an
> Instrument. From the outset, the packaging was done for me, and was at the application level -
> Workbench, Sample Management, Instrument Interfaces, etc. Instrument Interfaces requires a
> structure that is similar to the one in Workbench:
> Instrument Interface:
+-----+ +-----------+ +--------+
| Run |-------->| Injection |Analyte |------->| Result |
+-----+ 0..*+-----------+ +--------+
> Workbench:
+--------------+ +--------+ +--------+
| Analysis Set |-------->| Sample |Analyte |------->| Result |
+--------------+ 0..*+--------+ +--------+
> But, in Workbench a Run is known as an Analysis Set, composed of Samples. There is other
> information on a Sample object specific to Workbench. In Instruments, an Analysis Set is a Run
> and the Sample is an Injection. Structurally, an Analysis Set and a Run look the same, but there
> are differences - a Sample Name on a Sample is known as a VialID on an Injection.
I would have a conversation with people who use the software to clarify these terms. Are these different words for the same thing or are they different things. Have them define the terms. Talk through different scenarios. In my opinion, spoken language is the most subtle tool we have for exploring models. The subtleties of models often come out in persistent conversation. (Warning, the conversation might be a little annoying to them if they don't understand why you are so particular about the meanings of minor phrases!) :-)
NR> A number of discussions did take place actually. From these discussions I realised something. Imagine a bunch of Vials sitting in a Rack on a desk. The Analyst would gather together his vials and place them into a rack while using Workbench. At some point he is happy with the Analysis Set, and hits a button titled Send To Instrument. This effectively sends a data file to a machine, but obviously this type of detail is irrelevant. More important is that the definition of a Run appears and is available to the Instrument.
The person who deals with actually running the Instrument (Instrument Manager) is typically different to the Analyst, though the Analyst is capable with the role of Instrument Manager. The IMs that we spoke to call the vials a Run, composed of Injections. An Injection is a single event/transaction - something is recorded by an Instrument. But the rack the vials arrived in becomes redundant till the end of the Analysis (the act of putting the Run through the Instrument). Runs are batched together if the IM wishes.
The way the vials are used by the IM is conceptually different to the Analyst. He talks about them differently....he reuses some too. For example we have this concept of a Standard. Lets say we are analysing for the presence of a chemical called Pixoxy in a whole Analysis Set. To help calibrate results, we put a number of Standards inside the Analysis Set, say every 3 samples. These Standards would be Pixoxy at a known Concentration. When we get our results back, if our first Injection is a Standard, and it was a 1.0 concentration, if the Result for this Injection was 0.9, then we have a 90% accuracy, and factor the actual samples we are analysing between this standard and the one that is 3 samples on. While its not essential for this discussion, that should help you visualize the world. Standards help to normalise the results to something more correct. Back to the IM - if a run requires a Standard of 1.0 in more than one place, the IM will configure his software at the instrument to keep using the same Standard....this is important. To the Analyst, each vial is used once but to the IM this restriction isnt necessarily true. Its also worth mentioning that from a Data Responsibility perspective, there are things required for injections that are irrelevant in LWB, and vice versa.
This is why I felt we were talking about different concepts, and recommended introducing this more explicitly into our domain.
> While I was away, what has happened is that a new .NET Assembly has been created, with the core of
> Workbench/Instrument Interface. I believe the idea was to extend the classes in the Workbench and
> Instrument domains. This is kinda like the Abstract Core. Trouble is there are two major reasons
> for why these interfaces might change - requirements from Workbench or Instrument Interfaces.
> After sitting down and remodelling the problem, i started to think that maybe while the concepts
> seem the same, they in fact arent.
Aha. Probably not. The fun part of all this is looking for abstractions that more precisely describe each part. For example (and remember I don't know your domain, I'm just giving an example), although you think of a sample and an injection as the same thing, they aren't quite. The instrument sits there and gets injected with some stuff, which it analyzes in a particular way and returns a result. It presumably doesn't know the experiment it is a part of. In that experiment, sets of samples are collected and analyzed. Part of that analysis is injection of the material into an instrument and collecting the result. The "analysis" of the instrument is presumably narrower and only a part of the "analysis" of the experiment (the workbench?).
Or, maybe the machine is doing most of the work and the two really do map together, in that case, the workbench is just a sort of wrapper over an instrument run, where some extra tracking is done, or whatever. If that is the case, maybe you could find a way to get rid of the Sample and the workbench result and just use the instrument ones. Or maybe they are important wrappers too. Gosh, I just don't know enough.
NR> I see how you are thinking. In fact this was how we were thinking about the domain too. We felt that it Workbench is so intimate with instruments, that we could introduce a Sample/Injection into Instruments and reuse them from Workbench. But I took a step back (and I could have stepped in poo...who knows!), and looked at the world slightly differently. Up until this point we had thought about the two domains as being intimately involved. But what I realised was that the Analyst isnt that intimately involed with instruments at all. She will call Send To Instrument from Workbench, and then simply wait for Results to appear. But a whole lot of stuff takes place after that. In the grand scheme of things the instrument bit is the tip of the ice berg. In Workbench linear curve aglorithms and correct algorithms are used to analyse the results we have for an experiment, and this is the core of Workbench, not Instruments. I started to feel that too much dependance on II was misleading. The real world is that II plays a very small part, albeit an important part....like I say, there could be a pong here, but while this chnage in perspective is subtle, it kinda helped us review the problem we were faced with.
> Workbench has its concept of a run, known as an Analysis Set.
> There are a whole number of other things (attributes and operations) that need to be added to the
> classes that make up the Analysis Set, that are irrelevant to Instrument Interfaces. So as a team
> we have arrived at the following solution: accept that conceptually the two distinct parts of the
> system have similar classes, but they are not the same.
Ok, so now you seem to be going a different direction. You've defined them as bounded contexts with their own models. They can model the same things in their own way and you will translate. This may be the right thing to do. It can side-step the need to work out the subtle differences between the models except at the specific points of contact, where you have your translation...
NR>We sat down and thought about the problem, and I proposed the concept of the Bounded Context (in different words). I explained that the classes in Workbench were too confusing as they were at the time implementing interfaces defined in II (as mentioned above). This meant that there were too many reasons for an Analysis Set in Workbench to change, and that alone concerned me - the concept wasnt concise enough and was doing too many things. So we decided to introduce and adapter/mapper layer to translate between the two and keep both sides clean and uninterested with the other.
> We will introduce a Mapper between
> Workbench and II that will convert an Workbench: :AnalysisSet into a II:Run. The mapper is
> dependant on both areas, but we can ignore the II layer within Workbench now, which makes our
> model much clearer.
Well, if it makes your model much clearer, then probably you made the right decision.
NR> It has done actually. But one concern was that of duplication. Team members still feel we have introduced duplication by going the way we have, but I am not convinced.
> When we started, the model was small and everything was in the same assembly/component. As things
> have grown, the dependancies have become troublesome. On another note, we originally had class
> A--->B and it seemed like a correct domain association. Class A moved into its own DLL and B
> moved into another. We didnt want to associate a class->class across component boundaries, but
> the reality is that A--->B. What do yu do in this situation? The architect wanted to remove the
> link and use a facade. This is fine, but the model doesnt reflect reality.
This is hard to talk about in the abstract.
NR> Yes, after I had written the above I felt it wasnt getting across what I wanted.
Thanks for your comments and your time Eric.
`Nick Robinson`
EvolvingStructureAndAmbiguousConcepts is mentioned on: ThreadView