4

I'm a bit confused by some object-oriented analysis and design (OOA&D) concepts.

In OOA&D, what recommendations should be followed in order to produce a viable conceptual Domain Model?

How should classes be identified in that process? I've read about a number of varying English language analysis and refining processes which indicate nouns in the use cases as candidate classes and verbs as operations/responsibilities. Apparently there are varying manners of applying that refining in order to figure out the classes.

From there it is possible, for instance, to use CRC cards to find out responsibilities and collaborations, as well as more class candidates. But I suspect CRC cards are not very popular, so I'd like to hear about other methods (but feel free to endorse CRC cards if you want).

And regarding the implementation details (the more concrete and technical classes, not the conceptual ones), is there a process in OOA&D to determine them? How is that accomplished?

Feel free to treat OOA and OOD separately and clarify the steps involved in them while answering. I believe this will help clarify things to me regarding how those classes are found.

Piovezan
  • 481

4 Answers4

5

In OOA&D, what recommendations should be followed in order to produce an accurate conceptual Domain Model?

I'd recommend grabbing a copy of Domain-Driven Design by Eric Evans, it's an excellent book that walks through the process of talking to domain experts and distilling ideas into a software model. One of the central ideas in the book is to develop a ubiquitous language for your system that both stakeholders and programmers can understand: if there is a "thing" that people talk about all the time, then it should probably be a class in your code.

And regarding the implementation details (the more concrete and technical classes, not the conceptual ones), is there a process in OOA&D to determine them?

Generally speaking, if you've got the right domain concepts and interfaces, the "technical" classes will fall into place fairly easily. Details such as databases, web services and IoC containers exist only to connect your domain model to the outside world, so just pick the simplest solution that makes the rest of your software work.

casablanca
  • 5,014
2

Fundamentally, we want to design abstractions that are useful to their consumers (often us, ourselves).

I generally advocate thinking more about how these abstractions are going to be used (rather than, say, about their implementation details).  Good abstractions are easy to use.

Let's also speak to the many different kinds of abstractions we can create in most OO languages:

  • functions
  • classes
  • interfaces + classes, and/or base classes + subclasses
  • namespaces

Each of these bundles more things together.  A function bundles a capability with inputs & outputs.  A class bundles multiple capabilities (aka methods) together with encapsulated state.  An interface (or base class) creates a capability over multiple varied implementations.  And a namespace defines a forest of classes that interact together or are otherwise related.

Good abstractions are complete.  If you can navigate from one to another then perhaps vice versa as well.  The consuming client should not have to manage two or more items when a single abstraction can do the job (e.g. separate x & y vs. vs. bundled together as a coordinate; an encode & decode pair of separate functions vs. bundled together as an interface).

Beyond thinking in terms of classes alone, we should more broadly model abstractions needed for a domain: to identify concepts and their relationships, to support navigation (traversal/search/query), to support behaviors for making changes (commands), all to make things easy for the consuming client programmer so they can work as much as possible directly in terms of the modeled domain.

Software is evolvable, so we don't need to get it perfect from the start.  We can start with a design and see how useful it is to consuming clients.  If, for example, the client has to manage multiple objects as a pair or set, that is indicative of a missing abstraction that perhaps should be modeled.

Erik Eidt
  • 34,819
2

Short answer: No. There is no unified mechanical process which produces a good object-model. Modelling is a creative and social process, it usually involves talking to-, and understanding other people, during which you come up with different ways to decompose a problem.

Just to be clear, it is not even close. Even judging the outcome is completely subjective, which is surprising considering most people believe software engineering is, well, some form of "engineering".

For example, I usually try to fulfill following constraints:

  • Any valid sentences in my model (i.e. any syntactically valid code using my objects) should be semantically valid too. So, if the code compiles it must have some "business" meaning.
  • All identifiers should come from the domain, or reference something from the problem domain. No technical classes.
  • No objects should ever publish their internal state.

A lot of people would disagree with the above. Most people are completely fine with "anemic" objects, i.e. records and structs, which the above isn't.

What I'm trying to say is, we didn't even agree how object-orientation should look like. Sure, there's lots of books and rules and best practices out there, but a lot of them are conflicting or depend on your personal interpretation. You have to make your own way basically.

1

From my POV there are two approaches which I would call analytical and synthetical (coming from 18th century philosophy) or perhaps more modern: top-down and bottom up. I find the former terms more describing because they indicate what you are doing: Analyzing things vs. putting things together.

I) The Analytical Way

When you enter your domain you have some understanding of what is going on. Say you are doing e-commerce you are dealing with Customers, Orders, Products etc.

what recommendations should be followed in order to produce an accurate conceptual Domain Model?

Coming down this road, the answer is

Getting to know your business domain

This is called analytical for just that reason of analyzing first and code second.

II) The Synthetical Way

If you have the luck I have and use a language which supports multiple paradigms (like Python) in my case, you could leverage that in order to avoid the question about objects (and modules etc.) at first. This way you build from the bottom up bit by bit - or as it is called you synthesize (group things together and group the groups) etc.

Generally speaking OOP is about data and behavior and grouping data and according behavior together (there are the three pillars which from my perspective come later).

But when starting the project most of the time you do not know how to group your data. Of course - as mentioned above - there are the "easy parts" of having an order.

Languages like Python allow you to postpone the question of what classes are needed and how they should look like to a later point. You start with the basic builtins and write some functions and group them later to modules which may become eventually classes. But sometimes you only see that you need a function.

The longer you work on the project, you realize which data "attracts" which behaviour so to say. If you have a bunch of functions every dealing with the same kind of data: Think of a class and clean up your code.

what recommendations should be followed in order to produce an accurate conceptual Domain Model?

The answer here is:

Start without any notion of objects at all and look for "attraction" of data and behaviour during the project.

I prefer the latter one. It let's me starting my work earlier.

But to do both ways in a reasonable way, you have to have (built up) experience.


Besides: I would substitute the term accurate with viable. You should model something which works. That may be inaccurate but accurate enough for the moment.

Thomas Junk
  • 9,623
  • 2
  • 26
  • 46