2

I am working on an open-source project which shows how to develop software iteratively using test-driven development and some ideas from domain-driven design. I know what I would do, however my formal skills (especially regarding UML) are a little bit rusty.

Below I am going to post my first steps with the diagrams and the explanations I would give to my readers.

I have the following questions:

  1. The last step ends with the question But what will stich together these components?. How to show the reader the way in UML terms, while not skipping anything in the train of thought? What I plan to do is to let each component provide an Environment class. For the purpose of testing, a TestingEnvironment will gather all those environments and inject the right callbacks into the World. But which types of UML diagrams to use for showing my train of thought, and in which order? My problem is, somehow, that I know what I want to do, but I can't rationalize it to myself why I want to do it that way - I guess it has gotten a part of me to the point I don't make such decisions consciously any more.
  2. What mistakes have I done so far, how to fix them, and most importantly: WHY?

Step 1

0001_user_commands_use_cases.pdf (0001_user_commands_use_cases.pdf)

0002_user_commands_use_cases.pdf (0002_user_commands_use_cases.pdf)

User Use Cases - Analysis

We are starting with an use case diagram (0001_user_commands_use_cases.pdf) as
part of the preliminary analysis stage. This diagram should only help us
understand what our client wants. These use cases may change over time, but
never the less, they help us understand the system we are going to develop.

Please follow the arrows while reading the following explanations.

The role the user plays when interacting first with our system will be Guest.
The Guest sends to the system some registration data, which we process.

In the diagram, we are describing what happens from a logistic point of view,
from the perspective of the client for which we write the application. We are
not referring yet to classes or objects, or the concrete workflow, which may
end up being quite different.

We are also not dealing with errors, because that would only add more
background noise to the idea - and because error handling does not add business
value to the system. Of course, a system has to be robust to errors, but keep
in mind that we're now just making the analysis - not the design of the system.

Logistically speaking, after the Guest has sent us the registration data, there
is a Registered User. A registered user can send us the login data, so that he
becomes an Authenticated User.

Following the diagram, we can see how only an Authenticated User can send to us
a request to log out of the system, thus becoming a Deauthenticated User.

Why a Deauthenticated User, and not a Guest back again? Basically, it comes
down to us not being able to foresee the future. We really have no idea how the
client will want us to extend the system - nor does he himself! Beside that,
the two roles, a Guest which we know nothing about, and a user which has just
deauthenticated, which we do know something about, are really different things.

Of course it may be that the Deauthenticated User will exist in our application
only for a very short period of time, or it may be that it's created for the
sole purpose of being destroyed back again, without being looked at by any
other subsystem of our ERP - but still I cannot stress it enough: logistically,
the role of a Deauthenticated User stands on its own.

The second diagram (0002_user_commands_use_cases.pdf) contains all the
information of the first diagram, with some added items. If you follow the
green arrows, you will see that the process is the same.

In the first diagram we notice how all three things done by the ERP system are
some kind of generalizations of a process. We have introduced this new generic
process in the second diagram as "Process Data".

Another element we have added in the second diagram is a generalization of the
three "Sending Data" elements. We are not sure how this will materialize in the
next stage (designing the system), but it looks like there's a generalization
there which may, in the end, make the system easier to maintain and extend.

We always seek new generalizations and abstractions because they have this nice
property of making the code maintainable and extendable.

Conclusion
----------

In our design, the ERP will do one central thing, "Process Data", data which
will come in in a standardized way, represented in our second diagram by the
"Send Data" use case.

We don't know how we will design these things yet, until now we have only
thought about the logistics, since we are doing just the analysis.

In the next commit, we are going to look closer at the application domain, in
order to better see the relations between all these notions and to enable us to
come up with a cohesive design.

Step 2

enter image description here

A rough overview of the components in the context of the application domain

Before looking at the diagram, let me first explain the thoughts I had prior to
coming up with this diagram.

We are going to design an ERP. What is this all about, and where lies the
business value in it?

We are supposedly making the product for a company which makes money by sending
products back and forth. This is the core domain of the application.

The basic idea is that a product P is moved from point A to point B, and in
this process, the company makes money.

The application will allow the company to make money by both being good at
organizing the workflow, and by making an existing workflow cheaper.

Let's say a product can be delivered to point C by taking the route A -> B ->
C, or the route A -> D -> C. The ERP must be capable of deciding which one is
better (in terms of money or time), and must manage the workflow it chooses.

So the whole point is supporting the movement of products around. Around what?
Around the world.

For this reason, let's first draw our first component: the World.

In a real project, I would continue by adding a Product component. I've chosen
not to yet, because this project is an educational one in nature, and I wanted
to get across new ideas about the architecture. If I had focused on the
products, I think there would be too much noise for the type of audience this
project is aimed at, a noise which would make the process of creating the
architecture and the architecture itself harder to understand.

We will introduce a Product component later, when the reader will feel at ease
with the architecture which, at that point, he will feel familiar with.

Instead of focusing on Products, we are going to focus on Users. This is,
incidentally, also the subject of the use cases we have drawn in the previous
commit. I think that any reader can relate to the concept of User.

So let's draw that component, the User.

Architecturally speaking, it's not that much of a difference between an User
and a Product. Instead of having Products moving around, we will have (for
now), users who live in the World and take different roles while interacting
with our system.

In the previous commit, we have concluded that there would be a standard way of
passing in data from the User to the system.

In terms of DDD (Domain-Driven Design), the data that gets into the system is
packed up as a Command. Since it looks like a good name, let's make a port of
the World component called Command Hub which will be used to receive and
process Commands from the outside.

Conceptually, the Command Hub will provide a Command Interface which any other
component can implement in order to send commands to the Hub, if it needs to.

We also want to make the components decoupled and thus reusable in different
types of applications, or to be able to combine them. This is achieved by
making an event-driven architecture.

For this reason, let's give the World component an Event Hub, which will
provide an Event interface.

But what will stich together these components?

This question is so pressing, because it's so central to our architecture, that
we will have to further investigate it.
Flavius
  • 13,566
  • 13
  • 80
  • 126

1 Answers1

1

This is not an asnwer, just a comment that would not fit into the comment box

(1) if you want to "teach your readers" something you can't do yourself, it is strange approach. Show your readers the way which works for you. Show the way "your train of thoughs runs", show the the mental images you saw in your mind, paper/pencil/photo in whatever visualization language you use

(2) you're skipping the uml-diagrams: UML 2.5 Behavior Diagrams as not useful? Even the uml-diagrams.org: UML Interaction Overview Diagrams not useful?

(3) this question looks like too broad(long) perhaps opinion-based and perhaps off-topic much more suitable for https://softwareengineering.stackexchange.com/help/on-topic

(4) for the recommended modeling workflow look at

In conclusion of this my long comment, I don't see any mistakes you did. If this is description of how Test-driven Development and Domain-driven design works for you so well that you even use it subconsciously then it is just fine and ok. Being a good teach is not an easy task, good luck

Community
  • 1
  • 1
xmojmr
  • 8,073
  • 5
  • 31
  • 54
  • 1
    Thanks, +1, especially for the multitude of links. I make a difference between test-driven development and test-driven design, though. I am obviously at the analysis step, before any design, though. – Flavius Nov 08 '14 at 19:41
  • 1
    @Flavius you are welcome, but especially providing a links, recommending a book, tool, tutorial or other off-site resource is an off-topic here. I don't know how your question should be handled gracefully, maybe on Code Review Stack Exchange? – xmojmr Nov 08 '14 at 19:47
  • 1
    I was thinking about some behavioral diagrams, but every time I tried to sketch something, I ended up with a giant leap in my train of thought, instead of baby steps, as I did in the first two steps. I wish to take the reader slowly, and the design to emerge naturally. – Flavius Nov 08 '14 at 21:10
  • I'm an old school in the sense that I started programming before [OOPSLA 95'](http://en.wikipedia.org/wiki/Unified_Modeling_Language#mediaviewer/File:OO_Modeling_languages_history.jpg) and before UML. What works for me for small to mid-size projects is getting the call sequences clarified (what UML sequence diagram captures) and then I write (few) mostly bottom-up code skeletons, the sooner it compiles the better. Up to 3 prototypes to throw-away. So I quite understand you "train" is different but for distributed or larger-scale projects it is not probably the best way to teach software design – xmojmr Nov 09 '14 at 20:10