I am trying to model with papyrus Marte in eclipse, I want to know what is the difference between association navigable in both directions and associtiation navigable in only one direction.
thank you in advance.
As it represents a link, an association has two ends. An association’s end is modeled by means of a UML Property which can be owned by the classifier involved at the related end of the association, in that case the association is said to be navigable as the source classifier can directly refer to the target instance (the instance at the other end of the association) by means of that property. Otherwise the property representing the association end may be owned by the association instance itself.
You can find more details about this topic in http://lowcoupling.com/post/47801917915/understanding-uml-associations
Related
I have the code as follow :
class Synchronization
def initialize
end
def perform
detect_outdated_documents
update_documents
end
private
attr_reader :documents
def detect_outdated_documents
#documents = DetectOutdatedDocument.new.perform
end
def update_documents
UpdateOutdatedDocument.new(documents).perform
end
#documents is an array of Hashes I return from a method in DetectOutdatedDocument.
I then use this array of Hash to initialize the UpdateOutdatedDocument class and run the perform method.
Is something like this correct?
Or should I use associations or something else?
Ruby to UML mapping
I'm not a Ruby expert, but what I understand from your snippet given its syntax is:
There's a Ruby class Synchronization: That's one UML class
The Ruby class has 4 methods initialize, perform, detect_outdated_documents, and update_documents, the two last being private. These would be 4 UML operations.
initialize is the constructor, and since it's empty, you have not mentioned it in your UML class diagram, and that's ok.
The Ruby class has 1 instance variable #documents. In UML, that would be a property, or a role of an association end.
The Ruby class has a getter created with attr_reader. But since it is in a private section, its visibility should be -. This other answer explains how to work with getters and setters elegantly and accurately in UML (big thanks to #engineersmnky for the explanations on getters in Ruby, and for having corrected my initial misunderstanding in this regard)
I understand that SomeClass.new creates in Ruby a new object of class SomeClass.
Ruby and dynamic typing in UML
UML class diagrams are based on well-defined types/classes. You would normally indicate associations, aggregations and compositions only with known classes with whom there’s for sure a stable relation. Ruby is dynamically typed, and all what is known for sure about an instance variable is that it's of type Object, the highest generalization possible in Ruby.
Moreover, Ruby methods return the value of the latest statement/expression in its execution path. If you did not care about a return value of an object, you'd just mark it as being Object (Thanks engineersmnky for the explanation).
Additional remarks:
There is no void type in UML (see also this SO question). An UML operation that does not return anything, would just be an operation with no return type indicated.
Keep also in mind that the use of types that do not belong to the UML standard (such as Array, Hash, Object, ...) would suppose the use of a language specific UML profile.
Based on all this, and considering that an array is also an Object, your code would lead to a very simple UML diagram, with 3 classes, that are all specializations of Object, and a one-to-many association between Synchronization and Object, with the role #documents at the Object end.
Is it all what we can hope for?
The very general class diagram, may perhaps match very well the implementation. But it might not accurately represent the design.
It's your right to model in UML a design independently of the implementation. Hence, if the types of instance variables are known by design (e.g. you want it to be of some type and make sure via the initialization and the API design that the type will be enforced), you may well show this in your diagram even if it deviates from the code:
You have done some manual type inferencing to deduce the return type of the UML operations. Since all Ruby methods return something, we'd expect for all Ruby methods at least an Object return type. But it would be ok for you not to indicate any return type (the UML equivalent to void) to express taht the return value is not important.
You also have done some type inference for the instance variable (UML property): you clarify that the only value it can take is the value return by DetectOutdatedDocument.new.perform.
Your diagram indicates that the class is related to an unspecified number of DetectOutdatedDocument objects, and we guess it's becaus of the possible values of #documents. And the property is indicated as an array of objects. It's very misleading to have both on the diagram. So I recommend to remove the document property. Instead, prefer a document role at the association end on the side of DetectOutdatedDocument. This would greatly clarify for the non-Ruby-native readers why there is a second class on the diagram. :-) (It took me a while)
Now you should not use the black diamond for composition. Because documents has a public reader; so other objects could also be assigned to the same documents. Since Ruby seems to have reference semantic for objects, the copy would then refer to the same objects. That's shared aggregation (white diamond) at best. And since UML has not defined very well the aggregation semantic, you could even show a simple association.
A last remark: from the code you show, we cannot confirm that there is an aggregation between UpdateOutdatedDocument and DetectOutdatedDocument. If you are sure there is such a relationship, you may keep it. But if it's only based on the snippet you showed us, remove the aggregation relation. You could at best show a usage dependency. But normally in UML you would not show such a dependency if it is about the body of a method, since the operation could be implemented very differently without being obliged to have this dependency.
There is no relation, UML or otherwise, in the posted code. In fact, at first glance it might seem like a Synchronization has-many #documents, but the variable and its contents are never defined, initialized, or assigned.
If this is a homework assignment, you probably need to ask your instructor what the objective is, and what the correct answer should be. If it's a real-world project, you haven't done the following:
defined the collaborator objects like Document
initialized #documents in a way that's accessible to the Synchronization class
allowed your class method to accept any dependency injections
Without at least one of the items listed, your UML diagram doesn't really fit the posted code.
I am creating a Mongoid based application which will have a Class (called Question) whose Objects are stored in two different ways for different purposes. One group of those objects need to be stored in an N:N relationship with Class Page and another group of the same objects need to be stored as embedded (1:N) entries in a different Class (FilledPage).
I need to be able to copy a Question Object which has been referenced in a Page into a FilledPage and for the purposes of speed, I need that to be an embedded relationship.
I have tried creating a Superclass with the information and then two child classes, but I can't convert from one child class to the other without considerable work (and this same design needs to be used in a few other areas with much greater complexity).
Is there any way to support both embedding and references in the same class, or some other solution which will do similar.
Nothing block to have same class to be embedded or standalone. with reference. The limitation is about linking a master document to embedded document. It's not possible easily with mongodb, because your need get the master document and extract the embedded one.
I haven't found a clear explanation for what the association method does and how to use it properly -- I see several examples where model Alpha has_many Beta and then when creating a new Beta using a Factory we say beta.association :alpha or something along those lines. But isn't Alpha also associated with Beta (Beta belongs_to Alpha)... so I'm just pretty confused. I thought an association (at least in normal English) is usually mutual, so I am not understanding what this method is supposed to do. Can someone please clarify this?
In addition to understanding it on a broad conceptual level, I would also like to know exactly what it does on a syntactical level (ie. is it adding methods like attr_accessor does? like what is this actually doing??)
Sorry I just have not found a clear explanation for this -- if anyone can explain this to me that would be great!!
From my experience you define "association" in FactoryGirl when you need to instantiate associated object while creating other object by factory, and without this association your new object would be invalid.
Let's say you have Company and Worker models, and in your application you have validations which prevent creating Worker with invalid company_id attribute. You can have Company without workers (that's why you shouldn't define association for workers in factory), but you can't have Worker without Company. You then add association in factory to lazy-instantiate Company for every Worker created.
So to summarize - you define association when you have belongs_to in model, and when your association in model also have presence validation.
I am creating a document based project using Core Data and have run into what may simply be a conceptual issue for me, as while I am not new to Cocoa, this is my first attempt to utilize Core Data. What I am trying to accomplish should be relatively simple: with each new document launched, I would like a new instance of one of my model objects created that serves as a "root" object.
What I have done is add an NSObjectController to my xib, set its mode to Entity Name (with the correct entity name provided), checked off "Prepares Content", and bound its managed object context to File's Owner with managedObjectContext as the model key path. To test this, I bound the title of my main window to the object controller, with controller key as selection and model key path as one of the keys in my entity.
I know I can create my root object programmatically, but am trying to adopt the mediator pattern as is recommended by Apple. I have seen the instructions in the department-employee tutorial under the "adopting the mediator pattern" section and the steps detailed are exactly what I believe I have done.
Any thoughts?
Edit:
Perhaps I did not state the problem correctly. The models are created in Core Data and the relationships are setup as I need them to be (with a "root", children and leaves, using to-one parent relationships, to-many children relationships and an isLeaf boolean attribute). My issue is ensuring that this root object is instantiated as a singleton every time a new document is launched. There should be exactly a 1:1 relationship between the root object and the current document, that root object must always exist and be available without any user interaction to create it, and child nodes that are created and attached to the root are the data objects that are used and manipulated by the application.
I have implemented the above functionality programatically, but in keeping with Core Data principles, would like to adopt the mediator pattern completely and not manage any creation of data objects within my application logic.
If you want a "root" managed object like you would find in linked-list or tree, then you have to set that up in data model itself.
By default, a Core Data data model has no particular hierarchy among objects. Objects may be related but no object is logically "above" or "below" another one. You can reach in object in any relationship by starting with any other object and walking the relationship/s back to the desired object.
A hierarchy of managed objects needs a tree like structure like this:
Tree{
nodeName:string
parent<-->>Tree.children
children<<-->Tree.parent
}
... so that the "root" object is the sole Tree instances that has parent==nil.
Having said all this, I would point out that the Apple docs you refer to say that it is best NOT to use this type of built in hierarchy for most cases. It's just a simplification used for purposes of demonstration (and I think it is a bad one.)
The data model is intended to model/simulate the real-world objects, conditions or events that the app deals with. As such, the logical relationships between the entities/objects in the model/graph should reflect the real-world relationships. In this case, unless the real-world things you are modeling exist in a hierarchy with a real-world "root" object, condition or event, then your model shouldn't have one either.
This is a question for Objective-J/Cappuccino, but I added the cocoa tag since the frameworks are so similar.
One of the downsides of Cappuccino is that CoreData hasn't been ported over yet, so you have to make all your model objects manually.
In CoreData, your inverse relationships get managed automatically for you... if you add an object to a to-many relationship in another object, you can traverse the graph in both directions.
Without CoreData, is there any clean way to setup those inverse relationships automatically?
For a more concrete example, let's take the typical Department and Employees example. To use rails terminology, a Department object has-many Employees, and an Employee belongs-to a Department.
So our Department model has an NSMutableSet (or CPMutableSet ) "employees" that contains a set of Employees, and our Employee model has a variable "department" that points back to the Department model that owns it.
Is there an easy way to make it so that, when I add a new Employee model into the set, the inverse relationship (employee.department) automatically gets set? Or the reverse: If I set the department model of an employee, then it automatically gets added to that department's employee set?
Right know I'm making an object, "ValidatedModel" that all my models subclass, which adds a few methods that setup the inverse relationships, using KVO. But I'm afraid that I'm doing a lot of pointless work, and that there's already an easier way to do this.
Can someone put my concerns to rest?
I can't speak specifically to Objective-J, but the usual way of doing this without Core Data is to set the inverse relationship in the setter. So, using the employees/departments example, you would do something like this:
- (void)setDepartment:(Department *)aDepartment {
if (department == aDepartment)
return;
[department release];
department = [aDepartment retain];
[department addEmployee:self];
}
You need to make sure you don't update your instance variable if the new value already matches the existing value. If you didn't, setDepartment: would call addEmployee:, and addEmployee: would call setDepartment: in an infinite loop.
Also, note that this is an open invitation for retain cycles. It depends on how your model is structured, but the object that "owns" the the other is the one that should retain it. So my example is maybe not the best, because it's probably more accurate to say that the department "owns" the employee.
You probably want to set the relationship in your setter. Using your example the Objective-J code would look similar to this.
- (void)setDepartment:(Department)aDepartment {
if (department === aDepartment)
return;
[department addEmployee:self];
}
As you can see there is no need for retain / release. Objective-J is built upon javascript which is garbage collected. All the memory management methods are implemented but do nothing (apart from cluttering your code)
Also because this is javascript it's generally advisable to check for type equality (===) For more information on type equality see: http://www.webreference.com/js/column26/stricteq.html
check out the Cappuccino Extensions from this 280 North employee: http://github.com/nciagra/Cappuccino-Extensions
It includes an ActiveRecord port. I haven't actually looked at any of this up close yet, but it might help you.
Johannes
You can also check out this implementation of CoreData by rbartolome. I've only looked at it a little bit, but it looks like a start.
http://github.com/rbartolome/CoreData-Cappuccino