I have three components, A, B and C, and I associate A to B and B to C. If I create a new diagram and drop these three components onto the diagram, EA automatically shows the relationships between the components.
If I only drop A and C on a new diagram, is there a way to get EA to show that A is associated to C without creating an explicit association between A and C?
Whilst this is not a default behavior in EA, and some EA practitioners even argue against such a request.
I've seen one of my client in a similar situation, where there was a need to traverse from a business process to use cases without adding the requirements on to the picture (Their usual hierarchy business process -> Requirements -> UCs)
We ended up automating trace connectors creation in this particular instance. Where everytime a requirement is linked to a usecase, and if the same requirement is linked to a business process, a trace relationship is created between UC & BP.
NB - This could end up in really messy relationships, if you don't constraint it for specific purpose
The Associations A->B and B->C imply nothing about any potential relationship between A and C. For example, if the Association between B->C defines that B has a private attribute of type C, then A may not even know that C exists. Creating an explicit relationship is the way forward.
To what the other posters have said, I'll add that implicit relationships are simply not part of UML. So I don't see EA supporting it any time soon. If you really need it, Nizam Mohamed's automation suggestion will work but you can't get EA to do it out of the box.
If it's enough to see these implicit relationships on demand, you can use EA's Traceability window (under the View menu). This lets you follow relationships between elements in a tree view, so you can navigate from A to B to C.
Related
Good morning,
I have a rather special scenario and I would like to have your opinion on the best way to handle this situation.
We have an application divided into several functional microservices, but a common database (it's not ideal but for the moment we have no choice).
From a microservice A, I index entity A with entities B, C and D, like IndexedEmbeded.
1- if I make modifications on A, by changing B or C or D, is it automatically propagated in the indexing document or does it require additional configuration?
2- the tables of entities B, C and D are updated by other microservices and in this case I have to update my index of entity A. What is the best way to do this?
I thought of doing manual indexing trimmed every change in the other microservices. but I'm not sure that's the best way to do it.
Thank you
I'll state the obvious and say that if you use the same model across microservices, you're in for some headaches, especially when updating your schema, but I guess you know that and can't do anything about it. So, let's have a look at solutions...
if I make modifications on A, by changing B or C or D, is it automatically propagated in the indexing document or does it require additional configuration
Assuming everything happens in the same microservice, and the updates are performed using Hibernate ORM (and not native SQL), it should be automatic. See https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-reindexing-basics .
the tables of entities B, C and D are updated by other microservices and in this case I have to update my index of entity A. What is the best way to do this?
Assuming your other microservices share the same Hibernate ORM mapping (they know of entity A, they just don't deal with it), e.g. they all import a common JAR that contains your annotated entities... you could simply rely on outbox-polling coordination, which allows multiple instances of an application (or of different applications with the same model/mapping) to cooperate and index safely and reliably, as long as they all use Hibernate Search with compatible configuration.
If that's not your case, e.g. each microservice has its own entity classes, and may not include all entities from other microservices... I'm afraid Hibernate Search can't solve that problem for you (yet). Hibernate Search exposes a way to trigger reindexing based on entity events (entity created, entity property 'foo.bar' updated, entity deleted, ...) that you input manually, via the SearchIndexingPlan, but you will have to devise a way to propagate these events from one microservice to another. And that kind of makes Hibernate Search a lot less useful, unfortunately.
I have an ERD Diagram of an E-commerce with the following entities Product , Tag , ProductTag,Category and other entities of course.
I tried to convert it into class diagram as follows:
1- removed the id
2- converted the foreign key into object of the type i'm refering to(product_id converted into => product: Product)
my question is , is this good approach to follow on all my entities? does it like achieve the SOLID principle? I have a presentation in 2 days and I want to be very sure of what I have made , any comment or modification would be really enough .I also chose these tables because they represent one to many and many to many. thanks in advance.
Basically your approach is correct. It's just a couple of UML specifications you got wrong.
The label in the middle of the connectors is just the name of the connector. Unless you do some OCL wizardry this name is meaningless. There is a way to adorn it with a black triangle to show the reading direction. This sometimes helps business people to understand how classes are related to each other (see Fig. 11.27 on p. 202 of UML 2.5). But usually you would not use it.
The shared aggregation has no semantics (p. 110 of UML: Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.). So leave the open diamond away. Composite (filled diamond) can be used to show responsibility (when I'm killed I will kill my composites first). Usually it adds too little to be really useful, it only heats up the futile composition-discussion.
The navigation-direction is incorrect. The AC in the middle sees both connected classes so it's shown without any arrow. If you have an additional (directed) association you place it as lone (extra) connector. In that case put role names towards any end. That makes navigation clearer than just a simple arrow. I for myself use arrows only on rough sketches on the drawing board.
P.S. Just noticing that you have operations in your classes that have the same name as the class and take one paramter being also the class. I would guess you intend to show a constructor here. In that case you would make it Classname():Classname and provide only the paramaters that are needed for the constructor. Else these opreations don't seem to make much sense. Similarly the CRUD operations seem to work on a list of 'itself' which is also probably not desired. You would have a collection class which handles the base class where these operation make sense. So to summarize: you would only add getter/setter operations for the (private) properties matching the columns from your table.
P.P.S.: As per Christophe's comment it's a good idea to adorn the class instantiation operation with a <<create>> stereotype which highlights its purpose. See p. 196 of UML 2.5:
This stereotype is part of the standard (see p. 677) and the table on p. 678 states:
Specifies that the designated feature creates an instance of the classifier to which the feature is attached.
On the modeling part of your question, there’s already a perfect answer. For the records, I’d nevertheless like to add a complementary answer on the SOLID part:
Single responsibility: your classes have more than one reason to change, because you may want to change Product for what it is (e.g. add more product-related attributes), but you may also want to change the class to add new getByXxx() operations to find products in the database based on other criteria, independently of what a product really is. SO it's not complying.
Open-closed principle: we cannot tell
Liskov substitution principle: in absence of inheritance, this is not relevant. Moreover, you couldn't tell without having precondition, postcondition and invariant constraints.
Interface segregation principe: is probably not compliant, because you impose an implicit interface that all inheriting class would have to provide, even if they don't need it (e.g. products not stored in a database). A first step in the right direction, would be to use an interface for the common database operations.
Dependency inversion: we cannot tell but probably it isn't , because update(), delete(),... probably depends on some database, so that you can't switch it to another database. With DIP, you'd inject the database in the class that use it, so that you could at any moment inject another database that offers the same interface.
You didn't ask, but your design seems to correspond to active records. If you want to go for a cleaner, more SOLID design, you should prefer factor out the database related code to either repositories or table data gateways.
Besides using EA for developing and maintaining various model definitions - is it possible to use it as a repository of instance data?
Let's say that I have defined an class, "Activity". Can I use EA as a repo for the instances of this class?
In my particular use case I'm trying to document various aspects of our helpdesk. In addition to documenting the components pertaining to our support process, I would also like to store the actual implementation information pertaining to these components.
An example:
In a sense, I would like to use EA as a central database of configuration data (the collection of defined activities) and at the same time be able to trace each configuration data item to the formal class definition. Having the possibility to trace these relationships would make it easy for us to know what defined activities nned to be updated if we change the class model, and vice versa.
How can I implement this in EA?
Does this make sense, or am I completely off when it comes to what EA can be used for?
Yes you could do that by creating instances of your classes and setting the run-state.
Create an instance by (Ctrl+) dragging your class onto a class diagram and choosing Instance(Object) for Drop As:
Then use the context menu option Features | Set Run State (Ctrl + Shift + R) to set the run states.
Whether or not this is a good idea I'll leave in the middle.
In a project I work on there is a C# library containing business objects which are related to the backing database tables/stored procedures.
We imported the code into EA model (where we already have database model) and now I'd like to show dependency between a class and a table (or stored procedure output).
Since these are loosely coupled (i.e. only a portion of properties are shared between them) I'd like to have a relation between a class A and table B and in the properties of this relation to have the mapping (A.a <-> B.a , ...).
Is this possible and how?
You can draw connectors between two elements and then link one or both ends to an element feature (an attribute or an operation). Draw the connector, then right-click near the end and select Link to Element Feature.
You can draw any number of connectors between two elements, and link any number of them to any features at either or both ends.
You should note that this is an EA feature which is not in the UML standard. As such, it is also a little trickier to automate (the feature link is not documented in the API), but I've done it before for a client so it can be done. However, from your question I assume it's the manual case you're interested in.
I have three entities, A, B and C.
Where A has a to-many relationship with B
and B has a to-many relationship with A
Then C has a to-one (correct terminology?) relationship to A, and a to-one relationship to B.
However I want it so C's relationship with A must be an instance of A that is in a relationship with the B related to C.
Normally in code I'd use NSArrays in place of relationships and then in C have store the index of the needed instance. This is my first time using CoreData, so I'm unsure about most of it.
EDIT: To clarify:
First, it'd be easier to discuss your situation if you'd avoid using b to mean several different things. There are four relationships in your diagram; for the sake of the discussion, you could name them d, e, f, and g.
To answer your question, you can't and don't need to include the kind of restriction that you're talking about in the model. The model defines relationships between kinds of managed objects, but it doesn't say anything about individual objects. It's usually better to try to think in terms of objects when you're learning Core Data, but you should know that the entities you define in the model are analogous to tables in a relational database: they define can be stored, not what the code should or must (or must not) store.
To restrict C.a to one of the A's in C.b.bs, you'll need to write some code. If C.a is only set in one place, you might choose to implement the restriction in that code. If the restriction is essential to the proper operation of C, you might instead (or in addition) choose to add a check to the setter for C.a that verifies that the A is one of the allowed ones. You may also need to fix up the setter for C.b so that if C.b changes, it verifies that C.a is still valid and does something appropriate if it's not (clear C.a, pick a new C.a, refuse to accept the new C.b, post a notification, throw an exception, whatever).