There are 3 different fields for User Stories for a related parent, and we have run into some confusion about them.
As I understand it:
The Parent field is for a direct parent that is another User Story
The PortfolioItem field is for a direct parent that is Feature
The Feature field is for a parent (direct or via one or more US parents) that is a
Feature
If you have the Parent and Feature fields, couldn't you compare the two of them to see if the direct parent is a US or a PI (thus rendering the PortfolioItem field unnecessary)? It seems to me the one explanation for this is that originally there were only 2 fields, "Parent" and "PortfolioItem", but that restricted the ability to see an associated feature unless you traversed the hierarchy of User Stories up to one with a Feature set as the parent.
So, my questions are:
Did I define the three fields and their uses correctly? If so,
Why are there 3 when 2 (Parent and Feature) would suffice?
Are there other cases I am not considering?
Thanks
The portfolio item field predate the feature field. When we added it to the API we had not yet created the technology to "Roll down" information in our hierarchy. Cases one and two are mainly used to show the direct parent (if any) that is shown in grids and boards.
We will probably keep the portfolioitem field around for backwards compatibility.
Related
I'm working on a hobby project which is a nested todo list app.
I started with the tree view example in the Redux repository (Javascript project), which uses a data structure which stores an array of child ids on each node. At first I found this strange, but having played with the structure for some time, IMO its easy to maintain and reason about.
Now I'm researching the best method to persist my todos using PostgreSQL. I've extensively read through the pros and cons of each solution here (What are the options for storing hierarchical data in a relational database?), and am about to settle on recursive WITH CTE's, as writes and updates take priority over reads in my app, but I thought I should ask.. is there a reason why storing child ids on the parent is not a popular solution for relational DB's?
It's most similar to the Adjacency List method, but with less recursion, and you get ordering (by maintaining order in your child_ids array). It also seems easier to reason about as you don't need to think inversely about parents while asking for a 'top down' tree.
I already have the logic in place to interactively move/update/etc nodes in Javascript using this structure, so it would be a big win if I could use the same logic to persist the data.
is there a reason why storing child ids on the parent is not a popular solution for relational DB's
This idea is very popular, with two caveats, and under certain modeling scenario:
Since database fields store a single "thing", so storing so storing a list "on the parent" means storing the list in a separate table related to parent by ID, and
Since a single child can belong to multiple parents, enforcing "one parent per child" policy becomes a lot harder.
In effect, DB's model of storing child IDs on the parent side stores IDs on nobody's side, because you can retrieve IDs of parents of a child with the same ease as retrieving children of a parent. That is why this approach is used when you model many-to-many relationship.
Note: Since enforcing one parent per child policy when you store parent ID on the child happens automatically, you can easily model your tree like that, while converting in-memory representation to an adjacency list for the tree.
I have seen an article in Dzone regarding Post and Post Details (two different entities) and the relations between them. There the post and its details are in different tables. But as I see it, Post Detail is an embeddable part because it cannot be used without the "parent" Post. So what is the logic to separate it in another table?
Please give me a more clear explanation when to use which one?
Embeddable classes represent the state of their parent classes. So to take your example, a StackOverflow POST has an ID which is invariant and used in an unbreakable URL for sharing e.g. http://stackoverflow.com/q/44017535/146325. There are a series of other attributes (state, votes, etc) which are scalar properties. When the post gets edited we have various versions of the text (which are kept and visible to people with sufficient rep). Those are your POST DETAILS.
"what is the logic to separate it in another table?"
Because keeping different things in separate tables is what relational databases do. The standard way of representing this data model is a parent table POST and child table POST_DETAIL with a defined relationship enforced through a foreign key.
Embeddable is a concept from object-oriented programming. Oracle does support object-relational constructs in the database. So it would be possible to define a POST_DETAIL Type and create a POST Table which has a column declared as a nested table of that Type. However, that would be a bad design for two reasons:
The SQL for working with nested tables is clunky. For instance, to get the POST and the latest version of its text would require unnesting the collection of details every time we need to display it. Computationally not much different from joining to a child table and filtering on latest version flag, but harder to optimise.
Children can have children themselves. In the case of Posts, Tags are details because they can vary due to editing. But if you embed TAG in POST_DETAIL embedded in POST how easy would it be to find all the Posts with an [oracle] tag?
This is the difference between Object-Oriented design and relational design.
OO is strongly hierarchical: everything is belongs to something and the way to get the detail is through the parent. This approach works well when dealing with single instances of things, and so is appropriate for UI design.
Relational prioritises commonality: everything of the same type is grouped together with links to other things. This approach is suited for dealing with sets of things, and so is appropriate for data management tasks (do you want to find all the employees who work in BERLIN or whose job is ENGINEER or who are managed by ELLIOTT?)
"give me a more clear explanation when to use which one"
Always store the data relationally in separate tables. Build APIs using OO patterns when it makes sense to do so.
I am new to Object oriented design patterns. I have a basic idea of the domain model. However, I am stuck at the following problem. The problem is that I have a system that contains events and customers(both 1....*). Additionally, the events contain packages. The user is allowed to book events. However, he has to do it by booking a package that is contained inside an event. What should be the correct domain model of the given situation. I did a lot of research about similar questions, but could not find a suitable answer.
My guesses:
1)
In this image, The customers can book events, but I am unsure about this because customers are booking packages contained inside events. Should I select this domain model for the given system? It is intuitive because it allows customers to book events.
2)
In this image, the domain model signifies the system's structure. However, customers should reach the packages only through events. Therefore, I am unsure about this domain model. How can a customer book a package when it is contained inside an event.
Please suggest which domain model is correct. I am a beginner so please provide a good explanation. Thanks for helping me out!
First of all - there is no definite answer. Usually you can create in several different ways and have good results.
Second - both contain relationships should be aggregations in my opinion. Events to System is (probably) a composite aggregation while Package to Event can be either composite (if a particular Package is specific for one Event only) or shared (if the same Package is available through various Events).
Now to the main question. If the relationship between Event and Package is a composition (composite aggregation) then you can model book relationship as an association between Customer and Package. Then the Event is uniquely recognizable. You can also extend your model adding a relationship to the Event that is a derived one (from book).
Here is an example (note the / sign depicting this is a derived association):
Other option that is valid for both composite and shared aggregation between Event and Package is to model Book relationship between Customer and Event but model it as an association class. Then you have a class (Book) describing the association and this class can have a relationship chosenPackage to Package.
In this case your model will look like this:
I can bet that you can also find also other methods of modelling your problem that still are valid and show all the information you provided so far.
I have an MS Access database with several tables. Almost all tables contain inventory information about different classes of items (there are some utility tables which store extra information, such as a list of classes and lists of commonly used lookup values). Some classes of items have particular data specific to them - for instance, volume is relevant for liquids but not solid objects, but all objects have a location. The logical structure of my database is a textbook example of a case where an object oriented model provides clarity and maintainability benefits:
There is one basic table which is a catch-all table for all items that don't fit into other categories. It contains a few columns, like item name, date, location and notes that is applicable to any item. This would be the top superclass, e.g. class InventoryTable.
There are tables for specific classes, such as a table for printer cartridges. This table will have all the columns that InventoryTable has, but also include some specialized information that is only relevant for printer cartridges, such as printer model, ink color and brand. This table would be a subclass, e.g. class PrinterCartridgeTable : InventoryTable.
Sometimes there is a deeper inheritance structure. For example, there may be a table for all documents (class DocumentTable : InventoryTable, includes extra field for how many pages a document has) and then another table for letters (class LetterTable : DocumentTable which also has columns for sender and recipient of the letter). The assumption is that one would look for letters in the LetterTable, and if not found there, could try looking in the DocumentTable and the top level InventoryTable.
Let's say my dates are currently displayed as MM/DD/YYYY. I want to change them to ISO format (YYYY-MM-DD). Currently, I have to open every single table I have (about 20) and change the format in each one of them one by one. If there was some kind of inheritance mechanism, I could instead change the format only in my top-level InventoryTable, and all my other tables would inherit the change.
Or, suppose I decide to store a new piece of data, called "Owner", for all items. This would describe who entered the item into the inventory. I could simply add this column to InventoryTable, and it would appear in all the child tables automatically.
Lastly, let's say I make cosmetic changes such as rearranging the order of columns. Let's say in my document-related tables, the page number appeared at the end. I instead move the page number to the very beginning of the table - this would propagate to both DocumentTable as well as LetterTable but not unrelated tables.
Bear in mind that I am editing these tables manually using the GUI of MS Access 2013. When editing information pertaining to a single class of items, I would not like to switch back and forth between tables or queries to edit different parts of the same record - I want to be able to see and edit all of the information for any given record in one place. Therefore, some complicated solutions based on chaining queries may be impractical.
Is it possible for me to accomplish what I want (the inheritance structure) in Access using some kind of object oriented scheme? Is there an alternative way of obtaining the same benefits? Do I have no choice except to give up and manually propagate every change to all tables?
The relational data model does not have inheritance built in. There are several design patterns that allow the database designer to mimic the behavior of inheritance in a system of relational tables. Two common designs are known as "Single Table Inheritance" and "Class Table Inheritance". There are two tags in this area with questions that relate to these two techniques, and a brief description in the info under the tag. With one of these two techniques, you will be able to model a superclass/subclass situation.
For a more complete description, you could search for Martin Fowler's treatment of the two techniques on the web. There is a third technique, called "Shared Primary Key" which allows you to enforce the one-to-one nature of the IS-A relationship between members of the subclasses and members of the superclass.
Your big problem in MS Access is going to be implementing the code that these techniques leave to the application programmer. Get ready to do plenty of coding in VBA, and tying this code to the user's dashboard.
It is not possible to make tables in Access object-oriented because it is not possible to directly associate methods with tables. An object is defined to be both properties and methods. Access is not designed to do that.
Also note that Access is not the best that Microsoft has to offer. You will get more power and capabilities with SQL Server.
Hopefully, this fictitious example will illustrate my problem:
Suppose you are writing a system which tracks complaints for a software product, as well as many other attributes about the product. In this case the SoftwareProduct is our aggregate root and Complaints are entities that only can exist as a child of the product. In other words, if the software product is removed from the system, so shall the complaints.
In the system, there is a dashboard like web page which displays many different aspects of a single SoftwareProduct. One section in the dashboard, displays a list of Complaints in a grid like fashion, showing only some very high level information for each complaint. When an admin type user chooses one of these complaints, they are directed to an edit screen which allows them to edit the detail of a single Complaint.
The question is: what is the best way for the edit screen to retrieve the single Complaint, so that it can be displayed for editing purposes? Keep in mind we have already established the SoftwareProduct as an aggregate root, therefore direct access to a Complaint should not be allowed. Also, the system is using NHibernate, so eager loading is an option, but my understanding is that even if a single Complaint is eager loaded via the SoftwareProduct, as soon as the Complaints collection is accessed the rest of the collection is loaded. So, how do you get the single Complaint through the SoftwareProduct without incurring the overhead of loading the entire Complaints collection?
This gets a bit into semantics and religiosity, but within the context of editing a complaint, the complaint is the root object. When you are editing a complaint, the parent object (software product) is unimportant. It is obviously an entity with a unique identity. Therefore you would would have a service/repository devoted to saving the updated complaint, etc.
Also, i think you're being a bit too negative. Complaints? How about "Comments"? Or "ConstructiveCriticisms"?
#Josh,
I don't agree with what you are saying even though I have noticed some people design their "Web" applications this way just for the sake of performance, and not based on the domain model itself.
I'm not a DDD expert either, but I'm sure you have read the traditional Order and OrderItem example. All DDD books say OrderItem belongs to the Order aggregate with Order being the aggregate root.
Based on what you are saying, OrderItem doesn't belong to Order aggregate anymore since the user may want to directly edit an OrderItem with Order being unimportant (just like editing a Complaing with its parents Software Product being unimportant). And you know if this approach is followed, none of the Order invariants could be enforced, which are extremely important when it comes to e-commerce systems.
Anyone has any better approaches?
Mosh
To answer your question:
Aggregates are used for the purpose of consistency. For example, if adding/modifying/deleting a child object from a parent (aggregate root) causes an invariant to break, then you need an aggregate there.
However, in your problem, I believe SoftwareProduct and Compliant belong to two separate aggregates, each being the root of their own aggregates. You don't need to load the SoftwareProject and all N Complaints assigned to it, just to add a new Complaint. To me, it doesn't seem that you have any business rules to be evaluated when adding a new Complaint.
So, in summary, create 2 different Repositories: SoftwareProductRepository and ComplaintRepository.
Also, when you delete a SoftwareProduct, you can use database relationships to cascade deletes and remove the associated Complaints. This should be done in your database for the purpose of data integrity. You don't need to control that in your Domain Model, unless you had other invariants apart from deleting linked objects.
Hope this helps,
Mosh
I am using NH for another business context but similar entity relationships like yours. I do not understand why do you say:
Keep in mind we have already
established the SoftwareProduct as an
aggregate root, therefore direct
access to a Complaint should not be
allowed
I have this in mine, Article and Publisher entities, if Publisher cease to exist, so do all the dependent Artcle entities. I allow myself to have direct access to the Article collections of each Publisher and individual entities. In the DB/Mapping of the Article class, Publisher is one of the members and cannot accept Null.
Care to elaborate the difference between yours and mine?
Sorry this is not a direct answer but too long to be added as a comment.
I agree with Mosh. Each ones of these two entities has its own aggregate root. Let me to explain it in the real life. suppose that a company has developed a software. There are some bug in this software, that made you annoy. you are going to go to the company and aware them from this problem. this company gives you a form to be filled by you.
This form has a field - section - indicates to the software name and description. additionally, it has some parts for your complaint. Is this form the same as the software manual? No. It is a form related to the software. It is not the software. Does this form has any ID? yes. It has. In other words, you can call the company in the next day and ask the operator about your letter of complaint. It is obvious that the operator will ask you about the Id.
This evidence shows that this form has its own entity and it could not be confused with the software itself. Any relation between two different entity does not mean one of them belongs to the other.