I am having an assignment to create a class diagram for a certain software. Now, I identified the important classes and linked them and they are fine.
The thing is that I am having two different classes associated with another same class, but with different access level. For instance, I am having Admin and Clerk classes associated with Video class. The Clerk will be able to only view, whilst Admin is able to view and edit. Can I show this distinction in Class Diagram?
Yes, you can show this on a class diagram, if, in fact, the classes are part of the problem domain. If you are modeling these classes as part of the solution domain, then you should not. For more on this topic, please read the excellent article by Leon Starr, called How to Build Articulate Class Models and get
Real Beneļ¬ts from UML.
If Admin and Clerk are classes (and not actors), you cloud use something like GenMyModel http://app.genmymodel.com/engine/xaelis/accessLevel.jpg
Related
I have two classes, one for contacts and another for organisations. Each contact belongs to an organisation and an organisation can have many contacts.
I want a function which creates a contact where one of the parameters is the organisation name. If the organisation name already exists then the contact will be assigned to that existing organisation. Otherwise, a new organisation will be created on the spot for the contact.
Since this function creates a contact and can also possibly create an organisation, my first thought was to create a helper class for it since it doesn't seem to belong to either class. I've been led to believe that helper classes are bad practice in OOP so I'm looking for other suggestions. How would you implement this without the use of a helper class?
It is very difficult to define what exactly is good practice in OOP and what isn't without looking at the specific case in detail. The concerns you are stating are valid, here's my answer to those:
Helper classes are not necessarily "bad practice" in OOP
There are quite a few situations, where helper classes are the way to go. If those helper classes simplify your design, they are actually favorable.
An object function may create other objects - this does not mean it has to go into a helper class.
If your contact creates an organization, that's fine. If an organization creates a contact, that's fine as well. Those two classes are part of your object design and may depend on one another without violating any design rules in OOP. I don't see why your code "should" go into a helper class at all.
I'm hoping someone can help me decide the best way to model this design for what sounds like should be a simple use case.
I have a Client domain class. I have a Person command object and a Firm command object which represents either a firm or an organization.
I also have subclasses, lets call them for ClientSubClass1 and ClientSubClass2 for the sake of naming, that both extend Client.
Where I'm puzzled is that a client should be able to be either a person or a firm.
So the best way forward I feel is to use embedding and embed both a Firm class and Person class into the Client class and add a flag that indicates whether the client is a person or firm.
Otherwise I can't see how to use inheritance to accomplish what I need.
Any thoughts would be really appreciated, thanks.
In Grails you can use inheritance in your domain classes, and GORM will create and manage a flag in the database for you without you needing to explicitly declare one. I would create Person and Firm domain classes that inherit from Client.
Command classes are mainly useful for binding parameters in requests to controller actions, which is somewhat unrelated to how your data is stored and retrieved.
Well just to answer this question and wrap it up, I decided to create a higher level Contact domain class, which has a Person and Organization sub class (tableperHierarchy false).
A Client extends Person and contains an embedded Organization, and a flag to indicate whether when referring to that Client I should use the Person details or the Organization details, for instances such as when I want to display the name of the client, I know whether to use the personal name (title, forename, initials, surname) or the firm name from the embedded Organization.
Within the Contact class definition I also use an embedded Address class, held in 'src/groovy' so it doesn't create its own table.
So I have a mixture of composition and inheritance which work quite well.
Let's say there are two classes related to each other via some relations. For example, a Student maintains a list of the Classes he takes, and each Class has a list of Students taking it. Then I am afraid of letting the Student directly being able to modify its set of Classes, because each modification would have to be followed by a similar modification of a Class's list of Students, and vice versa.
One solution is to have a class whose sole purpose is to keep track of Class-Student relations, say Registrar. But then if some method in Student requires knowledge of its Class list, the Student needs to be passed the Registrar. This seems bad. It seems Student shouldn't have access to the Registrar, where it can also access other Students. I can think of a solution, creating a class that acts as a mediator between Student and Registrar, showing the Student only what it needs to know, but this seems possibly like overkill. Another solution is to remove from Student any method that needs to access its classes and put it instead in Registrar or some other class that has access to Registrar.
The reason I'm asking is that I'm working on a chess game in Java. I'm thinking about the Piece-Cell relations and the Piece-Player relations. If in the above example it wasn't OK for a Student to have access to the Registrar, is it OK here for a Piece to have access to the Board, since a Piece needs to look around anyway to decide if a move is valid?
What's the standard practice in such cases?
If relations can be changed - classes should be decoupled as much as possible, so along with each class create an interface, do not introduce tied relations between classes.
High level of separation you can achieve using intermediate services/helpers which encapsulates logic of communication between classes, so in this case you should not inject one class to an other even both are abstracted by interfaces, basically Student does not know anything about Class, and Class does not know anything about Student. I'm not sure whether such complexity is makes sense in your case but anyway you can achieve it.
Here is you may find a useful design pattern Mediator which can encapsulate interaction logic between two decoupled entities, take a look at it.
With the mediator pattern, communication between objects is
encapsulated with a mediator object. Objects no longer communicate
directly with each other, but instead communicate through the
mediator. This reduces the dependencies between communicating objects,
thereby lowering the coupling.
What I think you have found in your pretty nice example and explanation is that OO does not solve all problems well. As long as the responsibility is well shaped and sharp, everything is fine. And as long each responsibility fits in exactly one bucket (the class), it is pretty easy to design. But here you have a tradeoff:
If I define for each responsibility a separate class, I will get a bloated design that is pretty difficult to understand (and sometimes to maintain).
If I include for each separate responsibility at least one interface, I will get more classes and interfaces than I need.
If I decide that one of the two classes is responsible for the relation as well, this one object has more knowledge than usual about the other.
And if you introduce in each case a mediator or something similar, your design will be more complex than the problem.
So perhaps you should ask the questions:
What is the likelihood that the relation between the 2 objects will change?
What is the likelihood that the relation will exist between more 1 type of objects at each end?
Is that part of the system a highly visible part, so that a lot of other parts will interface it (and therefore will be dependent on it)?
Take the simplest solution that could possibly work and start with that. As long as the solution is kept simple, it is only your code (you don't design a library for others), there are chances that you can change the design later without hassle.
So in your concrete case,
the board field should have access to the whole board XOR
the figure on the field should have the responsibility of moving XOR
there should be an object type (ChessGame?) that is responsible for the overall knowledge about moving, blocking, attacking ...
I do think that all are valid, and it depends on your special "business case" which one is the most valid.
I see a lot of classes labelled "Manager". How is a manager class used?
For example, does it get used by composition like this?:
var m: Mananger = new ManagerClass();
m.doSomething();
Manager classes are the common dumping ground for code that somehow didn't fit somewhere else. They also tend to be or become god classes.
Classes like that are used to manage a set of objects of another class, which are often resources.
For example, let's say you have a pool of database connections, each one represented by an object of DBConnection class.
If your code needs to connect to DB via a pool of connections, it will merely ask DBConnection_Manager class for a new connection. Why do we need the manager class?
The Manager class will consult its list of DBConnection objects, and determine if any of them is un-allocated, and return one. If all are allocated, it will either create one and add to the pool (subject to max connections allowed limit) or place the request on queue, or report back failure.
ALL of this functionality is full hidden from the caller - the nitty-gritty details of managing the pool are the job of the Manager class.
This is just a specific example, but the idea is that resource management is centralized and encapsulated withing a Manager class and the user code merely asks for "a resource".
I'm not sure if there's a bona-fide "design pattern" for this approach, though I found at least one web page that says so: http://www.eventhelix.com/realtimemantra/ManagerDesignPattern.htm
Update: in case of actionscript, such a class could be used to manage sounds, or event listeners, or GUI widgets (e.g. context menus)
Some consider managers to be a code smell
it usually means somebody is implementing a design pattern and doesnt know (or doesnt want to use) the formal name for it. you'll have to read the code to draw any meaningful conclusions.
In my opinion, manager class should be used in these conditions:
Multiple objects need to be process
Pass object list to caller is not enough, you should provide some advance functions such as select the max or the min one
The objects to be managed should belong to one class (manage easily)
I have recently been studying UML and drawing simple diagrams with ordinary plain arrows between classes, but I know it's not enough. There are plenty of other arrows: generalization, realisation and etc. which have meaning to the diagram reader.
Is there a nice resource which could explain each arrow (ordinary, plain, dotted, diamond-filled, diamond)?
It would be the best if it will have some code examples for them.
Here's some explanations from the Visual Studio 2015 docs:
UML Class Diagrams: Reference: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/modeling/uml-class-diagrams-reference
5: Association: A relationship between the members of two classifiers.
5a: Aggregation: An association representing a shared ownership relationship. The
Aggregation property of the owner role is set to Shared.
5b: Composition: An association representing a whole-part relationship. The Aggregation
property of the owner role is set to Composite.
9: Generalization: The specific classifier inherits part of its definition from the general
classifier. The general classifier is at the arrow end of the connector. Attributes, associations, and
operations are inherited by the specific classifier. Use the Inheritance tool to create a
generalization between two classifiers.
13: Import: A relationship between packages, indicating that one
package includes all the definitions of another.
14: Dependency: The definition or implementation of the dependent classifier might change if
the classifier at the arrowhead end is changed.
15: Realization: The class implements the operations and attributes defined by the interface.
Use the Inheritance tool to create a realization between a class and an interface.
16: Realization: An alternative presentation of the same relationship. The label on the
lollipop symbol identifies the interface.
UML Class Diagrams: Guidelines: http://msdn.microsoft.com/library/dd409416%28VS.140%29.aspx
Properties of an Association
Aggregation: This appears as a diamond shape at one end of the connector. You can use it to
indicate that instances at the aggregating role own or contain instances of the other.
Is Navigable: If true for only one role, an arrow appears in the navigable direction. You can use
this to indicate navigability of links and database relations in the software.
Generalization: Generalization means that the specializing or derived type inherits attributes,
operations, and associations of the general or base type. The general type appears at the arrowhead
end of the relationship.
Realization: Realization means that a class implements the attributes and operations specified by
the interface. The interface is at the arrow end of the connector.
Let me know if you have more questions.
I think these pictures are understandable.
A nice cheat sheet (http://loufranco.com/wp-content/uploads/2012/11/cheatsheet.pdf):
It covers:
Class Diagram
Sequence Diagram
Package Diagram
Object Diagram
Use Case Diagram
And provides a few samples.
My favourite UML "cheat sheet" is UML Distilled, by Martin Fowler. It's the only one of his books that I've read that I do recommend.
For quick reference along with clear concise examples, Allen Holub's UML Quick Reference is excellent:
http://www.holub.com/goodies/uml/
(There are quite a few specific examples of arrows and pointers in the first column of a table, with descriptions in the second column.)
The accepted answer being said, It is missing some explanations.
For example, what is the difference between a uni-directional and a bi-directional association? In the provided example, both do exist. ( Both '5's in the arrows)
If looking for a more complete answer and have more time, here is a thorough explanation.
A very easy to understand description is the documentation of yuml, with examples for class diagrams, use cases, and activities.
Aggregations and compositions are a little bit confusing. However, think like compositions are a stronger version of aggregation. What does that mean?
Let's take an example:
(Aggregation)
1. Take a classroom and students:
In this case, we try to analyze the relationship between them. A classroom has a relationship with students. That means classroom comprises of one or many students. Even if we remove the Classroom class, the Students class does not need to destroy, which means we can use Student class independently.
(Composition)
2. Take a look at pages and Book Class.
In this case, pages is a book, which means collections of pages makes the book. If we remove the book class, the whole Page class will be destroyed. That means we cannot use the class of the page independently.
If you are still unclear about this topic, watch out this short wonderful video, which has explained the aggregation more clearly.
https://www.youtube.com/watch?v=d5ecYmyFZW0
If you are more of a MOOC person, one free course that I'd recommend that teaches you all the in and outs of most UML diagrams is this one from Udacity: https://www.udacity.com/course/software-architecture-design--ud821