I'm getting started with UML after years of programming and I want to make sure that I'm properly using the symbols in my diagrams.
Does the following diagram look like a proper representation of a simple Car class?
Update:
Actually, I just realized that Make knows about model so I removed the arrowhead, but Make and Model do not know about Car so I added arrowheads:
I would make some adjustments to your original diagram:
Make
The Make identifies the manufacturer, so Make will have many Models, and because no other manufacturer can take ownership of those models, the black diamond is shown to denote composition
The relationship is bidirectionally navigable, so no arrows are shown
Because we can navigate from Make to Model, there is a SortedSet (sorted by year) of Models shown in Make
Model
Model holds the only direct relationship to Make; this guarantees the validity of the relationships and avoids incorrect connections that could result from allowing other classes to create relationships with Make
Because Model may be used to navigate to Make, Model contains a reference to its Make; this ensures that any Car may navigate to its Model information and from there (and only there) navigate to its Make
For year, the immutable type Integer was chosen, because the value will never change once it has been assigned
Car
The relationship between Model and Car is only navigable from Car to Model, because the business domain has no need to obtain a set of all Cars that mere manufactured for any given Model (and it keeps things simpler)
Each car is assigned a VIN, shown as an instance of UUID - Universally Unique Identifier
The relationship between Car and Engine is only navigable from Car to Engine, so Car has an Engine member; there are use cases where parts of the system that receive a reference to a Car may want to navigate to the Car's Engine
Engine
Given that an Engine may start its life in one Car but then be moved into a different Car, the relationship is shown using a white diamond, denoting aggregation
The Engine is assigned a Part Number, which is a specific identifier for that instance of Engine; therefore the immutable type String is shown
The Engine maintains a mileage counter, which is defined to be of type: int, because the value is mutable and will change over the lifetime of the Engine
I hope this is helpful and provides some good feedback that makes your modeling exercise thought provoking. I know I had fun creating the diagram and thinking about the relationships and some of the details. Haven't done this in awhile -
Related
I'm trying to make a class diagram for an Online Auction System and I'm having this problem. Bids belong to both the Auction and the Buyer (Correct me if i'm wrong). So can I say that User is composed of bid AND auction is composed of Bid or is this against the rules of UML? I'm confused
In general
The term composition is ambiguous and this explains your confusion:
In OOP, object composition means to use an object in another one.
In UML, composition is a special kind of association that represents a part-whole relationship, with an exclusive ownership of the parts by the whole.
So in the UML sense, it is not possible to have an object that is part of two different compositions, because the ownership would no longer be exclusive. But you could use the object in several aggregations, which are a whole-part relations allowing a shared ownership.
In the OOP sense, there is no problem of having the same object used in (or using) several compositions. The object composition corresponds to a navigable UML association.
In your practical case
The situation is straight forward: A Bid has one Buyer, a Buyer may have several Bids, and an Auction has several Bids. You can model this with simple associations:
You could alternatively use an aggregation here, since one could argue that there is a whole-part relation between an Auction and the corresponding Bids (personally, I wouldn't see it like this):
You should however not see an aggregation on the other side, because there is no real whole-part relation between a Buyer and a Bid: a Buyer is not "made of several Bids".
Additional remarks
You could use also an association class here. But it's not required. And the semantic would be different: it would mean that there is a Bid association between a Buyer and an Auction:
Technically speaking, you'd still have three classes.
But the focus is different: the Bid is accessory to the Buyer and the Auction and cannot exist on its own (e.g. if the buyer disappears)
Have you learned about association classes in UML? They represent an object that is created from the relationship between two other classes, exactly what you are trying to map. There are plenty of contents detailing Association Classes (e.g. Correct use of an association class)
That way you shouldn't get confused reading the diagrams (which you were doing correctly btw), it would be clear to you that exists the entity Bid, which exists only associated to both Buyer and Auction.
I am trying to develop a data model for a very diverse set of interconnected objects. As the application matures, the types of objects supported will increase significantly. I want to avoid having to modify the model/schema whenever new object types are added.
As a simple example, let's say I'm starting with a model of people and buildings. A building can have multiple owners; a person can own multiple buildings; a person can live in a house and work in an office... Future versions might add cars and corporations. Cars can have owners, corporations can manufacture cars, people can work for corporations, etc. Most of the relationships will be many-to-many, some will be one-to-many, very few will be one-to-one.
While concepts like "owner", "employer", or "manufacture" can be considered properties of a "building", "corporation", or "car" object, I don't want to redefine the data model to support a new property type.
My current idea is to model this similar to a graph, where each piece of data is its own node. The node object would be very simple:
Unique identifier
Name (human representation)
Node type
Relationships
Extending the previous example, the possible node types would be:
Person
Car
Company
Building
A relationship would be:
Node A
Node B
Relationship type - uses, owns, has, is, etc
I have a few questions:
Are there any drawbacks to this approach?
Is there an existing pattern or model that describes this?
Are there better approaches?
Is there an existing pattern or model that describes this?
What you describe sounds like a network data model, also known as an object or object-oriented data model.
Are there any drawbacks to this approach?
Your model doesn't support ternary and higher relationships. It also creates fixed access paths between nodes, which supports node-to-node navigation, but which can make many queries convoluted. I also don't see any support for subtyping.
Without composite determinants, some situations will be difficult to model or query. You don't support predicates like (Object, Language) -> Name (or (Company, Role) -> Person, etc). One way is to create special relationship types, but your model is going to be asymmetric and more complicated to query.
Are there better approaches?
The relational model of data handles n-ary relations between object types / domains, and allows for the representation of complex predicates. N-ary relations mean it supports object hypergraphs, and user-defined joins mean ad-hoc access paths. Composite determinants are supported, and most implementations support a variety of integrity constraints.
In particular, look at Object-Role Modeling (http://www.orm.net, https://www.ormfoundation.org).
I want to avoid having to modify the model/schema whenever new object types are added.
Try doing a web search for "universal schema for knowledge representation". Facts about the world aren't limited to simple atomic observations like "John Smith has a dog named Spot". We have to deal with facts like "Company A is not allowed to distribute product B in regions within 100km of point C after date D if that product contains ingredients E or F". The most powerful knowledge representation we've got so far is natural language, and as far as I know we don't yet have a simple model of its structure.
I'm currently reading Ologs: A Categorical Framework For Knowledge
Representation. Perhaps this will be of interest to you too.
Say you need to architect an app with an entity that can be associated with multiple other kinds of entities. For example, you have a Picture entity that can be associated with a Meal entity, a Person entity, a Boardroom entity, a Furniture entity, etc. I can think of a number of different ways to address this problem, but -- perhaps because I'm new to Core Data -- I'm not comfortable with any of them.
The most obvious approach that comes to mind is simply creating a relationship between Picture and each entity that supports associated pictures, but this seems sloppy since pictures will have multiple "null pointers."
Another possibility is creating a superentity -- Pictureable -- or something. Every entity that supports associated pictures would be a subentity of Pictureable, and Picture itself would have a one-to-one with Pictureable. I find this approach troubling because it can't be used more than once in the context of a project (since Core Data doesn't support multiple inheritance) AND the way Core Data seems to create one table for any given root entity -- assuming a SQLite backing -- has me afeard of grouping a whole bunch of disparate subentities under the umbrella of a common superentity (I realize that thinking along these lines may smack of premature optimization, so let me know if I'm being a ninny).
A third approach is to create a composite key for Picture that consists of a "type" and a "UID." Assuming every entity in my data model has a UID, I can use this key to derive an associated managed object from a Picture instance and vice versa. This approach worries me because it sounds like it might get slow when fetching en masse; it also doesn't feel native enough to me.
A fourth approach -- the one I'm leaning towards for the app I'm working on -- is creating subentities for both Picture and X (where X is either Meal, Person, Boardroom, etc.) and creating a one-to-one between both of those subentities. While this approach seems like the lesser of all evils, it still seems abstruse to my untrained eye, so I wonder if there's a better way.
Edit 1: In the last paragraph, I meant to say I'm leaning towards creating subentities just for Picture, not both Picture and X.
I think the best variations on this theme are (not necessarily in order):
Use separate entities for the pictures associated with Meal, Person, Boardroom, etc. Those entities might all have the same attributes, and they might in fact all be implemented using the same class. There's nothing wrong with that, and it makes it simple to have a bidirectional relationship between each kind of entity and the entity that stores its picture.
Make the picture an attribute of each of the entity types rather than a separate entity. This isn't a great plan with respect to efficiency if you're storing the actual picture data in the database, but it'd be fine if you store the image as a separate file and store the path to that file in an attribute. If the images or the number of records is small, it may not really be a problem even if you do store the image data in the database.
Use a single entity for all the pictures but omit the inverse relationship back to the associated entity. There's a helpful SO question that considers this, and the accepted answer links to the even more helpful Unidirectional Relationships section of the docs. This can be a nice solution to your problem if you don't need the picture->owner relationship, but you should understand the possible risk before you go down that road.
Give your picture entity separate relationships for each possible kind of owner, as you described in the first option you listed. If you'll need to be able to access all the pictures as a group and you need a relationship from the picture back to its owner, and if the number of possible owner entities is relatively small, this might be your best option even if it seems sloppy to have empty attributes.
As you noticed, when you use inheritance with your entities, all the sub-entities end up together in one big table. So, your fourth option (using sub-entities for each kind of picture) is similar under the hood to your first option.
Thinking more about this question, I'm inclined toward using entity inheritance to create subentities for the pictures associated with each type of owner entity. The Picture entity would store just the data that's associated with any picture. Each subentity, like MealPicture and PersonPicture, would add a relationship to it's own particular sort of owner. This way, you get bidirectional Meal<->MealPicture and Person<->PersonPicture relationships, and because each subentity inherits all the common Picture stuff you avoid the DRY violation that was bugging you. In short, you get most of the best parts of options 1 and 3 above. Under the hood, Core Data manages the pictures as in option 4 above, but in use each of the picture subentities only exposes a single relationship.
Just to expand a bit on Caleb's excellent summation...
I think it's important not to over emphasize the similarities between entities and classes. Both are abstractions that help define concrete objects but entities are very "lightweight" compared to classes. For one thing, entities don't have behaviors but just properties. For another, they exist purely to provide other concrete objects e.g. managed object context and persistent stores, a description of the data model so those concrete objects can piece everything together.
In fact, under the hood, there is no NSEntity class, there is only an NSEnitity***Description*** class. Entities are really just descriptions of how the objects in an object graph will fit together. As such, you really don't get all the overhead an inefficiency of multiplying classes when you multiply entities e.g. having a bunch of largely duplicate entities doesn't slow down the app, use more memory, interfere with method chains etc.
So, don't be afraid to use multiple seemingly redundant entities when that is the simplest solution. In Core Data, that is often the most elegant solution.
I am struggling with esactly this dilemma right now. I have many different entities in my model that can be "quantified". Say I have Apple, Pear, Farmer for all of those Entities, I need a AppleStack, PearStack, FarmerGroup, which are all just object+number. I need a generic approach to this because I want to support it in a model editor I am writing, so I decided I will define a ObjectValue abstract entity with attributes object, value. Then I will create child entities of ObjectValue and will subclass them and declare a valueEntity constant. this way I define it only once and I can write generic code that, for example, returns the possible values of the object relationship. Moreover if I need special attributes (and I actually do for a few of those) I can still add them in the child entities.
I am getting really confused about OOD when designing relatively large system. Always, we talk about has-a relationship between two entities. My question is about which one owns the other?
when designing a parking lot, there are many parking space. Should the car has an data field called parking space, or should the parking space hold the car? or both?
in a library reservation system, I am assuming there is a class Library, a class Book, and a class User. Shall the user call checkout(book), or the book call checkout(user), or the library call checkout(book, user)?
It's been very confusing for me. Any comment/suggestion is welcomed.
Lily
It depends on the situation, and what you mean by "own".
In your first example there is a one-one relationship between a car and a parking space. From a database perspective you will have to make a judgement about which should "own" the other (which table 'owns' the foreign key). You would base this judgement on expected usage - for example - since a parking space is likely to remain fixed, but you have cars coming and going all the time, it might make more logical sense for the carpark to "own" the car. That's where your design skills come into play.
In the second example, it seems to me that a single book can only be checked out to one user at a time, and "checking out" is an action that occurs on a book. Therefore the correct solution is Book.checkout(user). Building on that, a user is likely to checkout more than one book at a time, so I would be inclined to do have a checkout method on Library, such that Library.checkout(Books[], user) called Book.checkout(user) in turn.
For #1, the parking space should keep a record of if it is occupied and if so, what car is in it. Otherwise to see if you could park somewhere, you would have to poll every car to see if they are in that spot.
My immediate thinking for #2 is that it should be Library.checkout(Book, User) such that you make a note that a User has checked out a specific book.
This is heavily dependent on what you're trying to do however, and you should design it in such a way that is easiest for the problem at hand.
Sometimes replicating the data in two places isn't a terrible idea as long as you keep it synchronized. For instance, if you need to know where a specific car is parked, you're going to end up wanting to keep track of that data in the Car class as well, otherwise you're going to have to poll every parking spot to know if that car is parked there.
In Object Oriented design the object can be considered an entity. At this point you may use the Entity relationship modelling to better understand who has to own what.
When you design your model you shouldn’t care how you are going to implement it. I mean you shouldn’t think who is going to own what because this is another process of the design that is when you are going to convert your model to objects (that can be data table, XML, C# object ,…. ) : only at this point against the relationship the entity got you can decide who has to own what(sometime even against the requirements as I’ll show you later).
At the design time you must focus just on the requirements you have. In the case of the car and car parking you should think about :
How many park car one can occupied ?
How many cars a park can host ?
What kind of answer has my system to answer ? EX: as user I want know where a car is parked against its car plate number (in this case the previous answer would be wrong because if you let the park own the car you should iterate through the park to get what car is on it)
As you can see it really depends by you business requirements especially when you have “one-to-one” relationship(as in this case).
So I can suggest you to have a look at “Entity relationship Modelling” and stick to its concept to better design you object model.
In this case undoubtedly parking space should hold a car(it's called aggregation), because the relationship between car and parking space isn't permanent(different cars can be parked in the same parking place in the same day)
In this case, I think, the user wants to get a book, so the GUI of this system must have some button(or smht else) that user has to click to reserve a book. So, user calls a method checkout(book) of the system(object Library represents it) to check if the book is free(or available). Then the system(Library) checks whether the book wasn't reserved earlier by other user, so it calls method Book.check() for all instances of this book. In such solution every user account in the system should have a list of reserved books which method Book.check() uses.
To think out of box, I don't think the examples you provided have a natural "has a" or "owns a" relationship, and there are more relationships than "has a" or "owns a". In my opinion, I'd like to use a loosely coupled relationship for your examples, in implementation perspective, I would use a map to describe and maintain this relationship, which means, for a parking lot and a car, I would put a map in the Parking class, and map its slots to cars, if we find a slot existing in the map, we know that slot is occupied, if not, it's a free slot, for me, it doesn't make much sense either saying car owns the slot or the slot owns the car; for the library example, the same thing, the book and its borrower are in a very loose relationship, I'd put a map in the Library class, and map the book to its borrower. And who's the guy really does the checkout action? it's either the library staff or the auto machine or simply the library, so we can have a library.checkout(user, books), and inside the method, put books and user into the map.
For the bonus, what is really a "has a" relationship scenario? not a man has a car, this is not really a "has a", even we have "has a" in the sentence (don't let the human language mislead you), this just means, inside the car's class, there is a String field called ownerName or ownerId, that's it. One example for a real "has a" relationship scenario is human has a heart or a car has an engine, which means, in the implementation, there is really a Heart class field inside the Human Class.
How beautiful the object oriented design is!
So there are many ways of structuring objects (I'm talking of OOP here). For the question, I will use the classic "Car" example of OOP. Basically, How do I know when to make the car an object, or the wheel of a car an object, when both program structures would accomplish the goal?
How do I classify and categorize the parts of an object to determine whether or not they are better suited as simple attributes or variables of an object, or if they really need to be an object themselves?
Well the first thing you have to realize is the OOAD ("Object-oriented analysis and design") is a tool and not a means to an end. What you get out of that process is a model, not a true representation of what you're modelling. That model makes certain assumptions. The purpose of that model is to solve a problem you have.
So how do you know how to design objects? How do you know if you've done it right? By the end result: has it solved your problem?
So, for the Car example, in some models a car count could simply be an integer count, for example the car traffic through an intersection in a traffic model. In such a model rarely do you care about the make, model or construction of cars, just the number. You might care about the type of vehicle to the point of is it a truck or car (for example). Do you model that as a Vehicle object with a type of Car or Truck? Or just separate carCount and truckCount tallies?
The short answer is: whichever works best.
The normal test for something being an object or not is does it have behaviour? Remember that ultimately objects = data + behaviour.
So you might say that cars have the following state:
of wheels;
Height of suspension;
Left or right drive;
Colour;
Width;
Weight;
Length;
Height;
of doors;
Whether it has a sunroof;
Whether it has a stereo, CD player, MP3 player and/or satnav;
Size of the petrol tank;
Number of cylinders;
of turbo charges and/or fuel injection;
Maximum torque;
Maximum brake-horsepower;
and so on.
Chances are you'll only care about a small subset of that: pick whatever is relevant. A racing game might go into more detail about the wheels, such as how hot they are, how worn, the width and tread type and so on. In such a case, a Wheel object could be said to be a collection of all that state (but little behaviour) because a Car has a number of Wheels and the Wheels are interchangeable.
So that brings up the second point about objects: an object can exist because of a relationship such that the object represents a complete set of data. So a Wheel could have tread, width, temperature and so on. You can't divide that up and say a Car has tread but no wheel width so it makes sense for Wheel to be an object since a Wheel in it's entirety is interchangeable.
But again, does that make sense for what're doing? That's the key question.
Don't start out by classifying things - seems like people are too eager to start building inheritance hierarchies.
write down a list of specific, concrete scenarios - what your app will do, step by step. An object model is only useful if it does what you need it to do - so start working back from the scenarios to see what common objects and behaviours you can shake out of each one.
identify the "roles" in your scenarios - not necessarily actual class names - just vague "roles" that turn up when you think through concrete scenarios for how your software will work. These roles might later become classes, interfaces, abstract classes - whatever you need - at the start they're just placeholders for doing a type of work.
Work out what each role "does". The key is having a bunch of named roles - that identify things that the objects will do. Thins is about distilling out a set of things each role can do - they might do the whole thing, or put together a bunch of other objects to do the work, or they might co-ordinate the work... it depends on your scenarios.
The most important thing in OOD/OOP - is OBJECTS DO THINGS - not what's inside them - what they do.
Don't think about inheritance early on - because it will tie you up in overcomplicated hierarchies and make you think in terms of SQL-oriented programming rather than object-oriented programming. Inheritance is just one way of sharing common code. There are lots of other ways - delegation, mixins, prototype-based programming...
Here are some guidelines I came up with to help with this:
What should be on a checklist that would help someone develop good OO software?
There are some good answers here, but possibly more than you were looking for. To address your specific questions briefly:
How do I know when to make the car an object, or the wheel of a car an object, when both program structures would accomplish the goal?
When you need to distinguish one instance from another, then you need an object. The key distinction of an object is: it has identity.
Extending this answer slightly to classes, when the behaviors and/or properties of two similar objects diverge, you need a new class.
So, if you're modeling a traffic simulation that counts wheels, a Vehicle class with a NumberOfWheels property may be sufficient. If you're modeling a racing simulation with detailed road-surface and wheel-torque physics, each wheel probably needs to be an independent object.
How do I classify and categorize the parts of an object to determine whether or not they are better suited as simple attributes or variables of an object, or if they really need to be an object themselves?
The key distinctions are identity and behavior. A part with unique existence is an object. A part with autonomous behavior requires its own class.
For example, if you're creating a very simple car-crash simulation, NumberOfPassengers and DamageResistance may be sufficient properties of a generic Vehicle class. This would be enough to tell you if the car was totalled and the passengers survived. If your simulation is much more detailed, perhaps you want to know how far each passenger was thrown in a head-on collision, then you would need a Passenger class and distinct Passenger objects in each Vehicle.
I like Wirfs-Brock's Responsibility-Driven Design (RDD) and also recommend this updated (free paper) Responsibility-Driven Modeling approach by Alistair Cockburn.
In over 15 years of OO development, whenever I've felt I'm getting lost in a software architecture, going back to the RDD basics always helps me clarify what the software is supposed to be doing and how.
If you like a test-driven approach, this article shows how to relate RDD to mocking objects and tests.
Attributes or variables are often "base" types of a language. The question is what you can sensibly abstract.
For example, you can reduce a Wheel to descriptors made up of base types like integers, floating-point values and strings, which represent characteristic attributes of any wheel: numberOfTreads, diameter, width, recommendedPressure, brand. Those attributes can all be expressed with base types to make a Wheel object.
Can you group some of those attributes into a more abstract arrangement that you can reuse, independent of a Wheel? I think so. Perhaps create a Dimensions object with the attributes diameter and width. Then your Wheel has a Dimensions object instance associated with it, instead of diameter and width. But you could think about using that Dimensions object with other objects, which may not necessarily be Wheel instances.
Going up the list, you can reduce a Car to be made up of base types, but also other objects, such as Wheel objects. It is sensible to do so, because other motor and non-motor vehicles (such as a Bicycle) also contain Wheel instances.
Abstracting Wheel and Dimensions lets you re-use these object types in different contexts you may not initially consider. It makes your life a little easier because you have less code to rewrite, in theory.
If you can create a hierarchy of objects, to the point where the deepest, lowest-level object is only made up of a few base types, that is probably a good place to start.
If it's true that "both program structures would accomplish the goal" equally well, then it doesn't matter which you pick.
If, however, the program does not have a single fixed "goal" but will evolve significantly over its lifetime, then pick either one for now, and refactor as necessary as future modifications dictate. We call it "software" for a reason.
Grow your classes bottom-up.
1) Class boundaries and semantics depend on context. Until you have a context, you don't have anything. (You may not even have a car in your example). Context is given by the user story (or use case).
2) Throw all the state and behavior suggested by the given context into one class (you could name this after the user story if you would like).
3) Use systematic Refactoring to tease this class apart into separate classes. While refactoring, use existing classes as reuse opportunities.
When you're done, you'll have a set of well-defined classes that are just enough to fulfill the needs of the given user story (and the user stories that came before).