I'm new to Agile. I'm currently writing a software that basically does a simulation using real-life objects – for simplicity's sake here's an example:
I have a GUI where I can add two Human Object(s) onto a plane, a Ball Object, and one Human Object. Then I can press a PLAY button to simulate a situation where Human Object A can throw the Ball Object by specifying parameters I can use physics based on Force/Velocity/Direction, and then the Human Object B can catch the ball based on its own position and time while he is walking (where its movement is specified by reading in an input file).
It's a two step phase where I do parameter specification, then pressing play to simulate how those events unfold.
My difficulties reside only for the backend part where I know I need an a) Event Handler, b) Coordinate system infrastructure. But I'm having trouble determining where in my User Stories they should belong?
Right now they sit on its own User Story just written as tasks as "Event Handling." and "XYZ Coordinate System", which I feel is not very well placed.
What I'm trying to understand: If I have the User story:
As a user, I want to be able to be able to add a Human Object to my simulation so that I can have the object interact with the ball
Would my Task List (for specifically back-end stuff) include:
Implement xyz-coordinate system
Implement having an Event Handler and adding the Human Object to being an Event Handling object?
Or should I stick those tasks into a User Story like
As a user, I want to be able to see my objects interact with each other when I press a play button so that I can determine what the status of the objects are after it is done playing
to handle the task of implementing infrastructure of the coordinate system and event handling?
(And to note, in reality outside of the example, I have a lot more objects and back-end processing.)
The direct answer to your question is that the user story you put at the end is probably your best bet for a user story. Implementation tasks are just how your team is going to make that happen. Where it gets messy in complex work like what you are describing is if that user story takes a month to build and you have to break it down.
You want to deliver functionality, even if it isn't the whole package. This may be abusing your example, but where I'd probably start in the case you give is first limit the scope of the user story to simulating those exact objects and interactions: 2 humans and one ball. This takes out a lot of the variability. Now, from a programming standpoint, there is a huge trap here. When you implement it, make sure to do it in a way that those areas can be expanded later without throwing the implementation out and starting over if you can.
Next, if that is too big, I'd probably split the throw and the catch simulation. This is implementing the code in a way that is aligned with the purpose of Agile. If I make Human A throw a ball, I can show that to a user and potentially learn. Maybe we are simulating football and we throw a "prolate spheroid" (the term for the shape of an American football) in a perfect spiral. I show it to the user and he says "No no, we're from Spain, we are simulating an overhead 2-handed throw of a round ball." Now you've learned something critical about the work you've done and the work to be done (the receiver can't catch with their hands).
The specific tool of user stories may or may not be helpful. I could write this last one as "As a sports coach, I would like to simulate a throw-in so I can experiment with different techniques." That contains a lot of convenient information for me. In particular, user stories are most valuable in places where you are trying to understand your user's needs better. However, if you feel you understand them well enough, "Simulate throw" is a perfectly adequate backlog item.
Related
I have a task to make a simple information system for the functioning of a guest house. I need to make a USE CASE diagram, but I don't know if what I've done is correct, or if I need to add something, I don't know where to include the maid.
As users of the system I have put - client, receptionist, manager
As objects of the system I have put client, room, occupied rooms, employees (maids, receptionist, manager), tour agency, payment
Can you give me a hand?
Well, you are at the verge of functional decomposition. And that's not what UCs are about. They are about added value. So the bubbles contain headers describing those added values. For a hotel the basic UC would be Reserve room. (A real hotel would of course offer more added values, but for your example that's it.)
Now, the reservation is usually going along with payment. But would you consider that added value? I would not. So rather than making these UCs they are constraints (from requirements defined elsewhere). There's a lot one could talk about representing requirements and business rules, but that is far too much for a discussion here. I recommend reading Bittner/Spence about UC sythesis. It takes that book and a lot of experience to get familiar with this area.
Note that UCs are described with subject/predicate(/object) to be meaningful. Room is no UC. If you intend to show an object, use a rectangle (with object notation). That however, is in most times more confusing than helpful. Stay with actors and (real!) use cases.
Another note: the downward association from Hotel manager should rather be a generalization (open triangle instead of an arrow). And the actors usually are also shown with arms ;-)
I guess this question could be related to any evented system like Event sourcing / DDD / Lambda architecture, ESB, Actors... I tagged the question so that people experienced with these systems could answer.
I'm currently experimenting with my startup an original way to build user interfaces, by using concepts often used in DDD / Event sourcing world but applied to a javascript single page application. What I want is a purely functional UI, where I can replay the in-memory event log to restore the UI state (the event log is not persisted on browser close, it is just to make things easy to reason about and potentially enable cool features like UI undo/redo for free, time travelling debugger like in ELM...)
I just wonder sometimes how to choose the right level of abstraction for events as it seems to me there may be multiple "interpretations" of something that just happened.
Basically, in a JS SPA, many events are triggered after an user has clicked on a button, on a link or something like that. So I could add an entry to my event log being this low-level event (after managing to make it serializable). But this event can also be interpreted as a representation of what the user really has done in a high level abstraction.
To give an exemple, let's say I have on my UI a popup that is displayed at some point.
When the user clicks anywhere outside of the popup, it should be closed.
Let's imagine now the user clicks to a div outside of the popup to close it. What event abstraction level am I supposed to add to the event log?
User has clicked on div ?
User has clicked outside of the popup ?
User has closed the popup ?
These 3 event abstractions seems correct to me: they describe in the past something that happened, but at different abstraction levels. So I'm asking myself some questions like:
Do I have to choose one of the 3 abstraction level? If so how to choose?
Can or should I fire all 3 events? If so, wouldn't the event log becomes a bit messy?
Should I use concepts like DDD Saga, so that when receiving a "user clicked div" event, the Saga could fire a "close popup" command or something?
In an example described, I would suggest to not generate any events at all, because you are not performing any command (action which changes application state). You may want to have such event only in situation when there is actually a practical value of saving it, or you can think of it becoming valuable in the nearest future, so you can use all this information to generate some kind of report which will become valuable for your business.
There is no hard and fast rule behind that, it's just a matter of common sense. What kind of problem are you trying to solve? If it's implementing redo/undo, event sourcing is not the first thing that you should look for, "command" pattern would probably be a better choice. You will not get undo/redo "for free" with just event sourcing. Consider splitting your answer into multiple ones and be more specific about practical goal.
Also, my advice would be to stay away from SAGAs as long as you can. It's always better to perform things synchronously where possible, otherwise your code will quickly become a mess (less readable, growing semantic distance). If you have to make it async, the better alternative would be utilizing "continuation passing style","promises". Sagas should be considered as a last resort and used when all other approaches failed to work ... but such scenarios are more likely to crop up on a server side, when your lovely noSql thing does not support ACID transactions, for example :p.
Correct me if I'm wrong, but looks like you just want to play with a "new trendy approach" and try it without any practical reason. It's fine, as long as you are ok with making your application more complex than it should be. (more expensive to develop and support)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
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:
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.
What mistakes have I done so far, how to fix them, and most importantly: WHY?
Step 1
(0001_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
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.
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
(4.1) Cangnus's sequence diagramming comment in Stack Overflow: sequence diagram for books exchange
(4.2) BobRodes's use case scenario comment in Stack Overflow: Formal language for UML sequence diagrams
(4.3) Scott W. Ambler's Agile Modeling: Where Do I Start? for what when how and why Agile Modeling Best Practices
to name just a few
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
A group diary and time management system is intended to support the timetabling of
meetings and appointments across a group of coworkers. When an appointment is to be
made that involves a number of people, the system finds a common slot in each of their
diaries and arranges the appointment for that time. If no common slots are available, it
interacts with the user to rearrange his or her personal diary to make room for the
appointment.
First step is to think about what objects you have in the system. Make a list of candidates.
Now think about how does this scenario get initiated. Where does the message come from? Draw that incoming message.
The next step is to think about which object is going to receive that message. Now in order to do the work that object will probably need to talk to other objects. Sketch out the other object with an arrow and a message name.
Keep thinking about the sequence of messages and the objects to which the messages go - and try sketching them out one at a time.
Don't expect to get it right first time. Try sketching out several approaches.
A sequence diagram describes interactions between objects that achieve some goal.
So your first step needs to be to identify some objects (and actors). If you start with that step, show us your attempt, then we have something to discuss further.
"You should identify possible objects in the following systems and develop an object-oriented design for them. You may make any reasonable assumptions about the systems when deriving the design."
From Chapter 14 Exercise 14.7
DDD teaches us to build our classes like their real-world prototypes.
So instead of using setters
job = new Job
job.person = person
job.since = time.Now()
job.title = title
we define well-named methods in our aggregation root
job = person.promote(title, /** since=time.Now() **/)
Now the tricky part
Assume we have an UI for an HR where he/she enters a new title via the HTML form and makes a typo like "prgrammer" (Of course in real application there'd be a select list, but here we have a text input), or selects a wrong date (like default today)
Now we have a problem. There are no typos in real world. Our John Doe is definitely a "programmer" and never a "prgrammer"
How do we fix this typo in our domain model?
Our Person has just promote, demote, fire, etc. methods, which reflect the HR domain model.
We could cheat a little bit and change the Job record directly, but now we have a Job.setTitle method, that doesn't reflect our domain model and also, setters are evil, you know.
That may look a little "academic", but that really bugs me when I try to build a good domain model for a complex application
Another side of DDD is invariants - "always valid" entity. And when you try to break this invariant (some rule) you must stop execution and say "loudly" adout this (throw exception). So, you need to have a list of valid titles and when you try to change title (does not matter how) to invalid state, you must throw some usefull exception.
To "fix" typo situations you must separate operations in your domain promote is one operation (it may check something, sent contratulation email :) and so on). And edit operation - just to edit some properties. So, the differenece is in logic of operations. You can't call promote without some preconditions (for example, required experience of worker), but you can call edit and fix worker's name because of type.
And usually this operations are separated between different users: only HR's can promote but a worker can edit his name, if it's wrong.
This solution is very complicated for such example, but it's always with DDD.
The main concept - separate operations. Each one with their own conditions, permissions, rules.
A question about invariants (rules).
If a client is purely entering data, then the underlying domain in this (bounded) context is not very deep. In these cases, it's fine to use a CRUD style application and allow titles to be changed (setTitle()).
Just make sure dependent BCs (e.g., billing, vacation planning, ...) where no such thing as "invalid data" exists, can react to changes in your CRUD context appropriately.
The application should enforce input correctness before it reaches the domain layer, no garbage input. If that means using a dropdown for the job titles then so be it. You can validate the title against existing titles.
In my company of 18 thousand employees, typo happens all the time. You are going to have to be pragmatic about this and accept that there will be setters in your code (one way or another)
Pragmatic thinking is very much at the core of the domain driven design, and is what keep things simple.
"Purity is good in theory, but in practice it can be very difficult to achieve, and sometimes you must choose the pragmatic approach" - Patterns, Principles, and Practices of Domain-Driven Design (2015)
"There are no typos in real world", I get what you mean, but that's not true, there are human mistakes in real world scenarios and they should be accounted for in your domain if they are frequent.
If data entry errors aren't frequent it may not be worth the extra modeling efforts and those could perhaps just get fixed directly in the DB. It also depends if the business wishes to learn something about those mistakes or not.
However, if data entry errors are frequent, it might be an indicator that the system is perhaps not offering enough guidance and the business may wish to learn more about those errors in order to make processes more efficient and less error-prone.
You may wish to implement an operation such as job.correctTitle(...), perhaps in a BC dedicated to data corrections? Also, it's probably very rare that each and every piece of information will be erroneous so corrective operations can be segregated. That means you probably do not need a job.correctAllInformation(...) kind of operation.
This whole scenario is very fictive since job titles would usually be managed in a separate BC from where they are used and they would probably get picked from a list, therefore typos would be less frequent, but you will always have to deal with data entry errors. Choosing the appropriate solution is not always easy and will vary from case to case, but try to stay pragmatic and not strive for the perfect model in every sphere of your domain.