How to refactor/rewrite an association into inheritance in the following example.
The UML Diagram describes the currently working state of my program. The real code structure is more complex so please excuse this made-up example.
There is a Market which initially holds some computers types in a list. When a computer is sold a new object SoldComputer is created and added to a second list. The sold computer references to the computer type. The CPU of the first computer sold can be called by:
soldComupter.ReferenceComputerType.CPU
Is it possible to replace the association with inheritance? Removing ReferenceComputerType and inherit SoldComputer from ComputerType. A call would look like this:
soldComupter.CPU
The goal is not to disguise the reference by a decorator pattern but to descant all field and functionality by inheritance.
The problem i struggle with is, that multiple sold computer can reference the same computer type. So i cant typecast an existing computerType into a soldComputer as both list must exist at the same time in the real application.
If I understand correctly your reasoning, your market sells SoldComputer which are categorized according to a generic ComputerType. Furthermore the ComputerType pre-defines some characteristics of all the computers of that type.
Composition over inheritance
First, a Computer is not a ComputerType. But looking at the properties of these classes, it appears that my argument is only about a naming issue, because your ComputerType could also be named GenericComputer, in which case it would be less shocking.
But your ComputerType is only a small part of the problem. Because sooner or later, you'll realise that a sold computer can also have some StorageType (e.g. HDD, 1To) and maybe also some GraphicType, and many other configurable options. And tomorrow, you may even have new type of components you are not even aware off (e.g. holographic beamer 2D/3D) but that fundamentally do not change the way you describe and categorize the SoldCompter.
This is why you should prefer composition over inheritance: you could have association with other types of components. The big advantage, of your current approach is that if a user decides to extend the RAM of its SoldComputer, he/she can choose just the matching ComputerType and everything is fine.
If you'd go for inheritance, the SoldComputer would have its CPU and its memory: if the user would change their value, it would be inconsistent with the categorisation. And maybe there is no copmuter type corresponding to the new categorisation...
Alternative
Another way to look at the problem is to have a class Computer with all the fields that technically describe the computer (e.g. CPU, memory, disk, etc...):
the set of computer types in the market would be populated with Computer but with only some relevant fields filled.
the set of sold computers in the market would be populated with Computer having some owner.
The creation of a new Computer to be sold could use the prototype design pattern. But as soon as it is done, there would be no relation anymore between the computer and the prototype.
In this case, the market would no longer be categorised by compter type. The search would always be dynamic (eventually initialised using a choice list of the prototypes.
Is it possible to replace the association with inheritance?
No, it's not possible.
As pointed out by #ThomasKilian, "a computer IS NOT a computer type", or put more generally, a product IS NOT a product type.
Your model seems reasonable.
It's very common in business apps to have both a class for product types and another one for individual products, such that these two classes are associated for representing the information which type a product has.
Why would you like to use an inheritance/subclass relationship instead?
Related
I am using Core Data to store objects. What is the most efficient possibility for me (i.e. best execution efficiency, least code required, greatest simplicity and greatest compatibility with existing functions/libraries/frameworks) to store different attribute values for each object depending on the context, knowing that the contexts cannot be pre-defined, will be legion and constantly edited by the user?
Example:
An Object is a Person (Potentially =Employer / =Employee)
Each person works for several other persons and has different titles in relation to their work relationships, and their title may change from one year to another (in case this detail matters: each person may also concomitantly employ one or several other persons, which is why a person is an employee but potentially also an employer)
So one attribute of my object would be “Title vs Employer vs Year Ended”
The best I could do with my current knowledge is save all three elements together as a string which would be an attribute value assigned to each object, and constantly parse that string to be able to use it, but this has the following (HUGE) disadvantages:
(1) Unduly Slowed Execution & Increased Energy Use. Using this contextual attribute is at the very core of my prospective App´s core function (so it would literally be used 10-100 times every minute). Having to constantly parse this information to be able to use it adds undue processing that I’d very much like to avoid
(2) Undue Coding Overhead. Saving this contextual attribute as a string will unduly make additional coding for me necessary each time I’ll use this central information (i.e. very often).
(3) Undue Complexity & Potential Incompatibility. It will also add undue complexity and by departing from the expected practice it will escape the advantages of Core Data.
What would be the most efficient way to achieve my intended purpose without the aforementioned disadvantages?
Taking your example, one option is to create an Employment entity, with attributes for the title and yearEnded and two (to-one) relationships to Person. One relationship represents the employer and the other represents the employee.
The inverse relationships are in both cases to-many. One represents the employments where the Person is the employee (so you might name it employmentsTaken) and the other relationship represents the employments where the Person is the Employer (so you might name it employmentsGiven).
Generalising, this is the solution recommended by Apple for many-many relationships which have attributes (see "Modelling a relationship based on its semantics" in their documentation).
Whether that will address all of the concerns listed in your question, I leave to your experimentation: if things are changing 10-100 times a minute, the overhead of fetch requests and creating/updating/deleting the intermediate (Employment) entity might be worse than your string representation.
Im designing an application which manages the renting of lots of different equipment. And I am wondering whats the best way to design the models for the application. My software has to manage lots of different types of equipment (with data types) for example:
Speaker
Make - String
Model - String
Wattage - Integer
Price - Decimal
Light
Make - String
Model - String
Wattage - Integer
Price - Decimal
Microphone
Make - String
Model - String
Use - Choice of: Instrumental, Vocal, Versatile
Price - Decimal
Cable
Length - Decimal
Connector 1 - String
Connector 2 - String
Price - Decimal
Stand
Type - Choice of: Microphone, Speaker
Height - Decimal
Boom - Boolean
Price - Decimal
Ways I have thought about the design:
An individual model for each type of product then a polymorphic association in the cart so that it can handle all the types of equipment.
A single product model that has fields for all types of equipment with a type field which can be checked when ever the product is used.
A product model with a price attribute then every type of product extends that model.
But what is the best way in rails to handle these different types of products?
The Dynamic Attributes gem should allow you to do this automatically:
https://github.com/moiristo/dynamic_attributes
There may be better gems that do what you need, but this is the first I found.
If you're using Postgres as your database, then you can use hstore. There are gems to work with hstore. If you can afford, get a subscription to railscast and watch the screencast about implementing hstore.
Activerecord-postgres-hstore seems to be the go to gem for this.
I'd personally go with a single model Product and another model called ProductAttribute.
In this table, you'd have a name column and a value column.
This way, you're not limited by your schema. A product has n product_attributes, named dynamically. You can in the admin section develop shortcuts so if you create a microphone product, it'll automatically create the specific attributes names in the linked table. You'd just have to input the values.
This way, your application is fully able to sell any sort of produts with any amount of attributes. No need to code again when in 3 months the manager will want to add another type of product :)
Edit : And of course, you'd have a ProductType model to manage all the different product types you can sell.
Another option would be to make a product attributes table, and build each product type over an admin interface instead of in low-level code. That way you would not need to alter te application to sell new products.
This is a problem that has caused headaches to many vendors of ERP solutions before.
The most elegant solution I would suggest to you based on what I've seen at one such vendor is this.
You define 4 models:
Equipment, EquipmentType, Characteristic, Choice.
There would be a many-to-many relationship between Equipment and Characteristic, going through EquipmentType.
The Characteristic model has an attribute called "value_type" and also one attribute for each value type you have (String, Integer, Decimal, Boolean).
Finally, there would be a one-to-many relationship between Characteristic and Choice.
This is actually a watered-down version of that vendor's implementation which is suited to your particular requirements.
That vendor's actual implementation is actually built at one or two levels of abstraction above what I'm showing you, in order to make the solution more generic. But those people are well-known for over-engineering things.
HTH.
The third approach is pretty close the right one. You will definitely want to abstract out all of the universal parameters for the items (such as store ID, and, as you mentioned, price) into the base model that every other item will extend. Then, as you mentioned in your first proposed solution, you will have references between the rest of the item classes where necessary, using :references.
As for the "type" and "use", you will probably be best off using a one to one relationship with the parent model. Then, store a list of possible field types for each of the models (for example, for Stand, something like possible_uses = "Microphone, Speaker"). Finally, do server-side validation when the model is instantiated that ensures that it's of a valid type. You can also do some hacks that will allow you to see make sure that Microphone and Speaker are the only two possible "uses" that your code actually uses.
A completely different, but cleaner way to do this would be to do everything I mentioned in the first paragraph, but continue the inheritance down to the lower levels. Specifically, have Microphone extend BaseItem, give Microphone the Make and Model parameters, and then have models InstrumentalMicrophone, VocalMicrophone, andVersatileMicrophoneextend theMicrophone` class. This will be the cleanest and will allow for full functionality.
I'm designing a Ruby on Rails reservation system for our small tour agency. It needs to accommodate a number of things, and the table structure is becoming quite complex.
Has anyone encountered a similar problem before? What sort of issues might I come up against? And are performance/ validation likely to become issues?
In simple terms, I have a customer table, and a reservations table. When a customer contacts us with an enquiry, a reservation is set up, and related information added (e.g., paid/ invoiced, transport required, hotel required, etc).
So far so good, but this is where is gets complex. Under each reservation, a customer can book different packages (e.g. day trip, long tour, training course). These are sufficiently different, require specific information, and are limited in number, such that I feel they should each have a different model.
Also, a customer may have several people in his party. This would result in links between the customer table and the reservation table, as well as between the customer table and the package tables.
So, if customer A were to make a booking for a long trip for customers A,B and C, and a training course for customer B, it would look something like this.
CUSTOMERS TABLE
CustomerA
CustomerB
CustomerC
CustomerD
CustomerE
etc
RESERVATIONS TABLE
1. CustomerA
LONG TRIP BOOKINGS
CustomerA - Reservation_ID 1
CustomerB - Reservation_ID 1
CustomerC - Reservation_ID 1
TRAINING COURSE BOOKINGS
CustomerB - Reservation_ID 1
This is a very simplified example, and omits some detail. For example, there would be a model containing details of training courses, a model containing details of long trips, a model containing long trip schedules, etc. But this detail shouldn't affect my question.
What I'd like to know is:
1) are there any issues I should be aware of in linking the customer table to the reservations model, as well as to bookings models nested under reservations.
2) is this the best approach if I need to handle information about the reservation itself (including invoicing), as well as about the specific package bookings.
On the one hand this approach seems to be complex, but on the other, simplifying everything into a single package model does not appear to provide enough flexibility.
Please let me know if I haven't explained this issue very clearly, I'm happy to provide more information. Grateful for any ideas, suggestions or comments that would help me think through this rather complex database design.
Many thanks!
I have built a large reservation system for travel operators and wholesalers, and I can tell you that it isn't easy. There seems to be similarity yet still large differences in the kinds of product booked. Also, date-sensitivity is a large difference from other systems.
1) In respect to 'customers' I have typically used different models for representing different concepts. You really have:
a. Person / Company paying for the booking
b. Contact person for emergencies
c. People travelling
a & b seem like the same, but if you have an agent booking, then you might want to separate them.
I typically use a => 'customer' table, then some simple contact-fields for b, and finally for c use a 'passengers' table. These could be setup as different associations to the same model, but I think they are different enough, and I tend to separate them - perhaps use a common address/contact model.
2) I think this is fine, but depends on your needs. If you are building up itineraries for a traveller, then it makes sense to setup 'passengers' on the 'reservation', then for individual itinerary items, with links to which passenger is travelling on/using that item.
This is more complicated, and you must be careful to track dependencies, but the alternative is to not track passenger names, and simply assign quantities to each item (1xAdult, 2xChildren). This later method is great for small bookings, so it seems to depend on if your bookings are simple, or typically built up of longer itineraries.
other) In addition, in respect to different models for different product types, this can work well. However, there tends to be a lot of cross over, so some kind of common 'resource' model might be better -- or some other means of capturing common behaviour.
If I haven't answered your questions, please do ask more specific database design questions, or I can add more detail about specific examples of what I've found works well.
Good luck with the design!
One of the databases that I'm working on has some quirky behavior that I want to account for in the entity-relationship diagram.
One of the behaviors is that there is a 'booking' table and a 'invoice' table. When a 'booking' is invoiced, then the record is inserted into the 'invoice' table and then deleted from the 'booking' table.
However, a reference is still kept of the booking number.
How do we model this? Big arrow between the tables and some text beside it describing what happens?
No, changing the database schema is not possible at this point in time
Edit: This is the type of diagram that I want to use:
alt text http://img813.imageshack.us/img813/5601/erdartistperformssong.png
Link
If, by ERD, you mean the original "Chen" diagrams where the relationship was words written in a diamond, then you have a relationship between between Booking and Invoice. It's a special kind of relationship that's NOT implemented with a simple foreign key; it's implemented via a complicated move and a constraint.
If, by ERD, you mean the diagrams that ERwin draws, then you don't have an easy way to do this. It tends to focus you on drawing PK-FK relationships. You have a non-PK-FK relationship between these things. Some kind of line with text is about all you can do.
Arrows, BTW, aren't appropriate because the ERD shows the "state" of the database. Data flowing around isn't part of an ERD. You do have a relationship, it's just not a typical PK-FK relationship. It's an atypical relationship based on rows existing in some places and not existing in others.
In the UML you can easily draw this as a "constraint" among the relationships.
I don't know what these people are talking about.
The Entity Relation Diagram doesn't describe the data fully; yes of course, it only shows Entities and Relations, it doesn't show Attributes. That's why it is called an ERD and not a Data Model. Evidently many people here can't tell the difference.
The Data Model is supposed to show as much as possible. But it depends on (a) the standard [if any] that you use and (b) the Notation. Some show more than others. IDEF1X which is the only Relational modelling Standard (NIST 184 of 1993). It is the most complete, and shows intricacies and complexities that other notations do not show. Recently MS and others have come out with "simplified" notations, of course, much is lost in the "ERDs".
It is not "process flow", it is a relation in a database.
UML is completely inappropriate for modelling data, especially when there is at least one Standard plus several non-standard but commonly used data modelling notations. There is nothing that can be shown in UML that can't be shown in IDEF1X. But most developers here have never heard of it (developers should not be modelling unless they have acquired modelling skills, but that is another story)..
This is a perfectly legal; it may not be commonly known, but it is legal and named. It is a Supertype-Subtype relation, except that the Cardinality is 1::0-n instead of 1::0-1. The IDEF1X Notation (right) has a Subtype symbol. Note there is only one relation at the parent end; and one each at the child end. And of course the crows feet show the cardinality. These relations can be Exclusive or Non-exclusive; yours is Exclusive; that is what the X through the half-circle means.
ERwin is the only modelling (not diagramming) tool that implements IDEF1X, and thus has the full complement of the IDEF1X Notation.
Of course, the Standard, the modelling capability, are all in the mind, not in the tool. I draw Data Models that are IDEF1X-compliant using a simple drawing tool.
I find that some developers baulk at the Subtype symbol, so I show a simplified version (left) in my IDEF1X models; it is intended to convey the sense of exclusivity, while the retention of the single line at the parent end indicates it is a subtype.
Lott: Click here▶Link to Data Model◀Lott: Click here
Link to IDEF1X Notation for those who are unfamiliar with the Relational Modelling Standard.
Sounds like a process flow, not an entity relationship. If at the time the entry is added to invoice, and the entry is deleted from booking, then there is never a relationship between the two. There is never a situation where you can traverse that relationship because there is never a record in both places that can be related together.
ERD don't describe the database fully. There are other things like process flow and use cases that detail other facets of the system.
This is kind of an analogy to UML for software. A class diagram doesn't show you all the different ways classes interact. One class might initialize locally and call functions of another class, but because there is not composition or inheritance that relates those two classes, then the class diagram doesn't show this relationship. Only when you fully document the system with all the various types of diagrams can you see all the facets of how it operates.
I'm trying to comprehend ontology basics.
Here's an example:
car (class)
2009 VW CC (sub-class or instance?)
My neighbor's 2009 VW CC (instance)
My issue is understanding what is "2009 VW CC" (as a car model). If you're making product model a sub-class in the ontology - all of a sudden your ontology becomes bloated with thousands of subclasses of a "car". That's redundant. At the same time we can't say "2009 VW CC" is an instance, at least it's not material instance of a class.
Does it make sense to distinguish between regular instances and material (distinct physical objects)?
At the other hand, if both are instances (of different nature so to say), then how can instance inherit properties / relations of a non-class?
I hate to say it depends, but it depends.
If you need to model every single car in the world, and have methods that you can call on them (like "change tyre", which is a process that is very different for each model) then yes, you are going to have a lot of bloated classes, because your real world situation is bloated too.
If you just want to have a database of pictures of archetypal cars, and you don't car whether it is a picture of your neighbour's instance or your sister's instance, then you can drop the bottom layer. "2009 VW CC" could well be an instance, even though you can visualise that it is also a class in another model.
Alternatively, maybe you don't need to make it a true subclass at all. A simple reference might be sufficient. For example, an insurance company knows about a large list of car models and years, but the developers don't write one subclass for each. Instead, they have a database of car models, where one row may represent 2009 VW CC. When you insure your car, they create an instance of "Insured Car" with a reference to the "2009 VW CC" instance.
This doesn't strictly follow the "Use inheritance for a 'is-a' relationship", but the operations on all the car types are identical - it is just the parameters (e.g. insurance price per annum) that change, and new car models are recorded in the database, not in the code.
An assumption here is that you can model the differences between the difference models as merely parameters to the same methods on car.
(Aside: When the iPhone started becoming available through phone company web sites, I noticed that it broke their class models - their web-sites seemed to handle dozens of brands and models of phone on one page - presumably using a simple database of phones and their features - and then needed a special page to handle the iPhone models, presumably because new special methods were required on their classes to support some aspects of the iPhone sale. Automated sales desks would say "Press 1 to buy a phone. Press 2 to buy an iPhone.")
You have it backwards.
2009 VW CC inherits from the class car. Thus 2009 VW CC needs to know about car, but car doesn't need to know about 2009 VW CC. Though we do occasionally use the term "subclass" in reality, car knows nothing about any of its subclasses.
What's more interesting is if you consider prototypal inheritance (like in javascript), where objects inherit directly from other objects (imagine if your 2009 VW CC inherited the aspects of your neighbor's 2009 VW CC). In reality how this is implemented is that new object have a secret pointer back to the object they inherited from. If you think about this secret pointer you can see how the originating object doesn't become bloated.
Now if you're suggesting that multiple inheritance and long family trees can lead to confusing structures, then I would agree with you.
I really agree with Oddthinking. Plus, if you need car models as classes, "all of a sudden your ontology becomes bloated with thousands of subclasses of a car" actually is not a problem. Why should it be? You just define classes instead of individuals, you might have an 'abstract' ontology, with base classes, and a 'concrete' ontology, with classes that represent the particular situation in real world. This is not OOP, defining thousand classes that are actually somewhat in between between instances and classes is no big deal, at least conceptually, nobody consider this 'bloated' or strange in any other way. Indeed, they do it all the time in my field (life science, where we typically don't care about the proteins P53 in our body, so P53 is a class, even though it's also used to model a record in a relational database).
Except, well, my experience is that tools like Virtuoso seem optimised for the situation of few classes and many instances. In fact, I've observed significant performance improvements when I turned million of classes in Virtuoso into instances. So, well, it's complicated...