Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Among the terms:
Motorized Vehicle, Car, Motor, Truck
I was thinking the following:
a Car is a Motorized Vehicle, a Car has a Motor, a Truck has a Motor, a Truck is a Motorized Vehicle
Q1: Am I correct in the above relations?
Q2: We now want to relate the word fan... how would that look?
my Attempt:
a fan has a motor, a Motorized Vehicle has a motor, a Car is a Motorized Vehicle, a Car has a Motor, a Truck has a Motor, a Truck is a Motorized Vehicle
I need some clarification on this please....
This can be a good solution to the above mentioned. As a motor can be replaced in a car with a new one so you can keep aggregation in place of composition . Kindly refer the below image
I think that there is no a 100% accurate response for your question without the context.
For example, to separate truck and car in our context, we should be definatelly able to tell, that car and truck behaves differently.
If both car and truck are just simple containers for (for example) "name" and "mass", or owner etc. with exactly the same behaviour in application, then we propably think in terms of specific objects, not classes, which can drive us to implement Vehicle (or just motorized vehicle) class with two instances
Vehicle car = new Vehicle("Car",1200,someMotor);
Vehicle truck = new Vehicle("Truck",3400,someMotor);
That is simple thing with just "terms", but there is also a relationship issue with context. By relations I mean connections. It's almost sure that Motorized vehicle will have a Motor (but remebmer that also can have more that one), but it is a quite much chance, that "motor has a vehicle" (as the owner, espacially in context of database entities and especialy if our context is more concentrated aroud motors than vehicles - for example when we are building system for motor dealer).
There is another tiny thing that can be not so clear for everybody, it's not only "car has a motor" and "truck has a motor" but more as "motorized vehicle has a motor", so car has a motor not just because "car has a motor", but "because it is motorized vehicle!".
Also, going into details (as question is oop tagged), in object oriented terms we should think about class vs interface and we can end up in conclusion, that MotorizedVehicle is more the interface (from which we can get a motor) than class - if our enviroment (like most) don't allow multiple inheritance. This will prevent us from problems like "Obama's car should be both MotorizedVehicle and ArmoredVehicle but I have motorized/armored in separate class hieries".
TL;DR all depends on context, prefer composition and interfaces instead of complicated class hierarchy
[Car, Truck] "is a" [Motorized Vehicle] "has a" [Motor, Fan]
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I've been doing some research on OOP concepts and am having a bit of an issue in trying to understand what exactly Abstraction is. I've gone over numerous Stack Overflow posts on the topic but haven't really been able to pinpoint a satisfying answer.
I've seen a lot of discussions on the differences between Abstraction and Encapsulation, and naturally started started thinking about Abstraction in terms of hiding how a particular class works and providing abstraction through the class API. Here are some posts that steered me in this direction:
Best voted answer refers to functions being Abstract. The very next answer starts talking about abstract classes...
Best voted answer seems to refer to exposing through the class API while the next two goes off in an Inheritance setting. Third answer even suggests Composition and Aggregation is considered an Abstraction
However, as I read through more posts, I noticed answers portraying Abstraction in an Inheritance context, specifically using interfaces and abstract classes to provide an Abstraction of a certain entity (class). I assumed Abstraction given in this manner would allow developers to extend new objects appropriately according to the "guidelines" outlined by this Abstraction. Here are some posts that lead me in this direction:
First couple of answers talk about Abstraction in an abstract class/interface setting, while some down the line start talking about exposing classes through APIs
Top two voted answers refer to abstract classes/interfaces
I'm not sure if I'm just completely missing the point here, but it's getting pretty confusing because every answer seems to add a slight variation to the mix. I definitely see why both contexts are crucial in Object Oriented Programming, but I really wanted a clear-cut definition of what Abstraction is.
Which brings me to my point: does Abstraction work in multiple contexts? Does Abstraction portray both of these concepts?
Hiding away "unnecessary details" as done through interfaces and
abstract classes
Providing an abstraction on a class to be created through interfaces and abstract classes. We can provide an interface of IPet which would act as an abstraction of a Dog class. Additionally, we could provide an Animal base class as an abstract class to provide a higher level abstraction. This could let us use Polymorphism and allow different classes that fall under our Animal abstraction to interact with one another.
Abstracting the implementation of a class by exposing it through the class API
given a Dog class, we just need to know that it has a feed() function as part of its API, and call that function to feed it without knowing how the feeding is actually done. This provides abstraction on the Dog class and lets us easily interact with the class
One of the links I've included above contains the following quote by Matthew Watson that says:
"The problem is that there are no precise definitions for these concepts, and the words themselves have multiple meanings even within the context of object orientation."
Is it just that Abstraction is so abstract, even the definition is abstract :P? Thanks for any guidance in advance!
Edit: I'm rather new to SO and am not really aware of what the "primarily opinion based" flag entails. I don't see how this question is any less valid than the slew of questions regarding Abstraction on SO. I think it would be considered less opinion-based as I'm actually pinpointing two different contexts in which I think Abstraction makes sense in. I've seen many questions that just ask what Abstraction is, which I'd think is an even broader question than what I have here.
To me, abstraction is one of the most beautiful concepts of oo, which is actually what makes the program language very close to human thinking: we, humans always want to classify. Think of a car: your car. And let's approach that car in the context of a banker asking about your assets in the context of a loan: you will say you have assets (highest level of abstraction): an expensive car, a family car, a house, a boat, etc. They all have a specific value. Then suppose the context of the conversation switches to the banker having a personal interest in that car, given he's a car freak him selves. Now the cars will be described in more detail, and you can see different abstraction levels being defined: sport car with brand names, and lots more characteristics.
During the design time, your interest is about the levels of abstraction: What you want to do with it, i.e. its context. So, we will have the levels of abstraction: Asset, Car (and Boat and House), SportCar, FamilyCar. And so on. The context should never have more details than it needs, and this is what you're concerned about during design phase.
During the implementation phase, you will implement these levels of abstraction by encapsulating the properties that belong at these levels. E.g. Asset has a value, where Car has colour and SportCar might have some specific characteristics that a FamilyCar doesn't have.
So, key difference is: design time vs implementation time.
This blog post described the difference in much detail:
http://javarevisited.blogspot.be/2017/04/difference-between-abstraction-and-encapsulation-in-java-oop.html
Here's another post at stackoverflow: What's the difference between abstraction and encapsulation?
Hope this helps.
As for me, the abstraction is when you solve a problem without going into the details at all. If you need to output list of cars, then I do not think "take a list of cars, walk through them, get their data, print them", I rather think "I need a set of objects, preferably cars, that can display data about themselves in the format that I need.". It's more about way of thinking.
its very simple and basic question.
I have a query regarding abstraction:
Abstraction is defined as Showing what is necessary from user's perspective! its filtering un-necessary info from users perspective.
its right.
example:
Implementation of Abstraction
To implement abstraction let's take an example of a car. We knows a car, Car is made of name of car, color of car, steering, gear, rear view mirror, brakes, silencer, exhaust system, diesel engine, car battery, car engine and other internal machine details etc.
Now lets think in terms of Car rider or a person who is riding a car. So to drive a car what a car rider should know from above category before he starts a car driving.
Necessary things means compulsory to know before starting a car
Name of Car
Color of Car
Steering
Rear View Mirror
Brakes
Gear
Unnecessary things means not that compulsory to know for a Car rider
Internal Details of a Car
Car Engine
Diesel Engine
Exhaust System
Silencer
In Driver perspective. That is okay. Its classic implementation of the Abstraction.
Now, what if I am different user of the class, say Mechanic??? it will be very weird to define same class for me with different access modifiers.
Right?
Please let know.
So you want to provide multiple simplified interfaces for a complex class or set of classes.
The standard way to do this is by implementing the facade design pattern. This will also encourage you to put each of the different aspects of the car into its own class and aggregate these classes only when the full functionality is required.
Let us say I have a car class and paint class(which consists of different colors). Now In terms of Object oriented design what can be the relation between these two classes is it composition or aggregation. First I thought it would be composition and then I thought it would be aggregation since even if car class is destroyed paint can exist independently. Am I thinking right over here?
I would say it depends on the context of your model. What does your Paint class specifically represent? Is it "a paint job specific to that car"? If so, it is part-of that car and would be considered composition. If it is paint as an independent concept, and an instance can be applied to multiple cars, then a car has-a Paint instance, and it would be considered aggregation.
Your example is a bit awkward but the question you're asking is exactly what you must answer in order to have the answer. No one but you can answer what is correct for your system.
For example, it will be composition if you're actually talking about an applied paint since it can't reuse/reapply/have paint without a recipient (e.g., a car). It should also be a composition if in your system there is no use for independent paint object.
On the other hand, if a paint is a spray container, it can very much exist without the car concept and can be applied to different cars.
It depends on the circumstance, it would be aggregation IMO as there is no strong relationship between a car and its paint, if the paint is removed it does not actually affects the functioning of the car,
But if you think of a relationship between car and engine and if you remove the engine the car cannot move. So this will be composition.
Even thought I think I understand Single Responsibility Principle and high/low cohesion principle, the following questions are still causing me some confusion
1) Assume Planet and Bird properties are put arbitrarily / at random in Car class ( ie. no code within Car needs or operates on the two objects returned by these two properties ) - in other words, Planet and Bird properties don't belong in Car class
a)
SRP states that object should have only one reason to change.
public class Car
{
public void StartEngine()
{ ... }
private Planet Planet
{
get { ... }
}
private Bird Bird
{
get { ... }
}
}
Is Car class violating SRP? I would say it doesn't break SRP, since any changes to Planet or Bird instances don't propagate to the Car class?
b)
Cohesion refers to how closely related methods and class level
variables are in a class. In highly cohesive class all the methods
and class level variables are used together to accomplish a specific
task. In a class with low cohesion functions are randomly inserted
into a class and used to accomplish a variety of different tasks
Assume that even though Car class contains these two random properties, it still accomplishes just a single specific task ( or several closely related task ):
Would we say that Car has low cohesion, even though it still performs a specific task ( or several closely related tasks )?
2) Assume that Planet and Bird properties are used by methods of a Car instance to accomplish a specific task, would then Car have high cohesion, even though conceptually the two properties don't belong to Car ( and thus it would be better if instead Planet and Bird instances were passed as arguments to a methods of a Car which operate on them )
thank you
HELTONBIKER:
1)
as you encapsulated Bird and Planet inside Car (worse yet if they are
private), so now Car class has THREE reasons to change:
I fail to see how Car has three reasons to change since in my first question Car's methods don't even operate on the two properties and thus any changes to Planet's and Bird's public API won't affect Car class?
2)
The problem here has two components:
1. Bird and Planet are contained (as opposed to aggregated) in Car class;
2. Bird and Planet are not conceptually related to Car, much less by some containment relationship.
a) This is confusing: aren't the chances ( at least with my first question ) of Car having to be modified due to modification of Planet or Bird instances exactly the same regardless of whether Planet and Bird instances are contained or aggregated?
b) In second question methods of Car do operate on the two properties in order to perform a single specific task, so aren't they conceptually at least somewhat related? Would you say that even in second question class has low cohesion, even though it performs only a single task ( and is using the two properties to accomplish the task )?
The car class does have low cohesion, as it refers to classes wholly dissimilar to it's set of responsibilities. It also has a higher coupling surface, because since Planet and Bird are public, you've provided access to consumers to these properties, meaning that you're now adding two more "reasons for change" to any consumer, regardless of whether or not Car uses these internally.
At any rate, SRP has been violated if only because Car now has the responsibility of "a way to get planets or birds", disregarding any coupling/cohesion arguments.
1)
I would say that Car cannot hold Planet and Bird. That way Car has two different responsibilities: car functionality and holding some strange objects.
There should be some other object/class that would hold objects in world: eg: class WorldContainer
2)
I would say that both of your examples have low cohesion. Managing car and some different objects should be done using some other interface. Interface that would glue them together.
SRP means that a class should have only one reason to change.
So, a modification in Car class should mean that the Car conceptual model changed.
BUT, as you encapsulated Bird and Planet inside Car (worse yet if they are private), so now Car class has THREE reasons to change:
Modifying the Car conceptual model and/or behaviour;
Modifying the Bird conceptual model and/or behaviour;
Modifying the Planet conceptual model and/or behaviour;
The problem here has two components:
Bird and Planet are contained (as opposed to aggregated) in Car class;
Bird and Planet are not conceptually related to Car, much less by some containment relationship.
Or, plainly speaking (and I hope you did so as a didactic exercise), the architecture shown simply doesn't make sense.
Example with aggregation (in Python). The non-cohesive classes are defined outside the Car class definition, which references them. Car depends from Bird and Planet, but now Bird and Planet exist on their own.
class Bird():
hasWings = True
class Planet():
isFlat = False
class Car():
owner = Bird()
substrate = Planet()
Example with parameter-passing (just the car class, suppose the other classes are similar as above). Now the Car constructor (the __init__ method in python) takes instances as parameters. This might or might not be prefered. The dependency and coupling remains, but perhaps more concrete now.
class Car():
def __init__(bird, planet)
owner = bird
substrate = planet
In the end this whole issue of cohesion and coupling doesn't have so much to do with the software itself, but with the developers. Compilers won't mind if your namespaces, project folders and file distribution is messy, as long as it "compiles". But it wouldn't make ANY SENSE to do as you did (put a Bird and a Planet class inside a Car class). Just to begin, your versioning of each class would be very messed.
So, the purity you shouldn't violate is not that written in books for the sake of it. This purity is (or should have been) derived of human beings struggling with machine instructions. Object-Orientation, and Software Architecture in general, is not intended for the machine, but for the developer's (piece of) mind.
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!