I am creating entities for a simulation using aggregation and composition.
In the following C++ example:
class CCar
{
CCar( CDriver* pDriver )
{ m_pDriver = pDriver; }
CDriver* m_pDriver;
CEngine m_Engine;
CDriverControls m_Controls;
};
in the above example, a car consists of an engine and a set of driving controls (by composition). A car must also have a driver (by aggregation).
But this only explains the hierarchial relationships - a driver belongs to a car, and an engine and controls also belong to the car. But these members all relate to each other also - a driver must perform an action on the controls, the controls must perform actions on the engine. These relationships also work in multiple directions - the engine can stall and cause the controls to seize up, or the controls could spin wildly and hurt the driver? And what if the driver doesnt like the sound of the engine and leaves the car? How do these relationships work?
I am compositing many different entities from many different objects which often interact with other objects, and am interested in how to manage these relationships in a designed way.
thankyou!
edit:
as responses suggest, one way to manage this is through pointing the car to the driver, and giving the driver a pointer to the car, etc. This makes sense and solves this specific example. However, in a design sense, this increases responsibility of the driver, where this object is tasked with keeping track of which car it belongs to, but surely this is the duty of the container to keep track of which objects belong together? Likewise, tasking CCar with managing these relationships will turn CCar into a blob. Is there a designed solution to dealing with these kinds of relationships?
You build those into the methods of each class. What you're describing is the behavior of each class. Your requirements suggest that the relationships are bi-directional as well. Your Controls class will have methods that take an Engine parameter and call its methods. The Engine will have limits on its RPM, HP, torque, etc., manipulated by the Control, that will have limits built into them (e.g., "If your RPM drops too low, stall out").
It's more than just composition. Your build behavior and rules into the methods. The methods might take parameters that express what you need.
The question should be "does my application need this relationship?" For example, if you are modelling steering a car for a simple driving game, you probably don't need to worry about the motor for the sunroof at all. The steering wheel may need to know it is connected to the road wheels, but there is no need for the reverse relationship.
Bottom line - in the real world everything is connected, but in the computer models we make of that world to solve particular problems, they are not.
It may be useful to emphasize interfaces rather than composition, aggregation, or inheritance. For example, your driver class could be written such that it can use the "steering wheel" interface. Naturally, your implementation of the steering wheel provides an implementation of the "steering wheel" interface. Likewise, the car supplies a "car interface" which the steering wheel implementation might be written to take advantage of.
Your implementations may use composition, aggregation, and inheritance. But in this approach it is really the interfaces that drive the design. Whether you use composition, aggregation, or inheritance in a given instance becomes merely an implementation detail.
You probably want a two way association between the car and the driver:
CCar( CDriver* pDriver ) :
m_pDriver(pDriver)
{
m_pDriver->SetCar(this);
}
Then the driver can access the members of Car through the Car's public interface.
To solve this question, it is first important to establish what each component does.
CCar - a container holding components and aggregates.
CDriver - an object representing a driver
CEngine - an object representing an engine
etc.
For a small and simple program, a simplified design should be used where the driver is given a pointer to the car
CCar( CDriver* pDriver )
{
m_pDriver = pDriver;
m_pDriver->SetCar(this);
}
For a larger application this is unacceptable where a CCar may require new components adding, etc. and it would be poor design practice to give a driver access to the whole CCar - here the driver would be able to change not only the steering wheel, but the cars colour, etc. which is clearly not the intention.
What about just giving the driver access to the bits it needs?
m_pDriver->SetSteeringWheel( m_SteeringWheel );
m_pDriver->SetHandBrake( m_HandBrake );
this solves that problem, now the driver has no access to the cars other attributes ( such as colour ). However, it gives the CDriver class more responsibilities. Where CDriver may be able to use alot of controls, the class can get very large, and holds the responsibility for operating these steering wheel and handbrake objects. What if the driver gets in a different type of car that doesnt have the same controls as the others? Now the driver has to figure out how to operate the vehicle with the controls it has? Extra logic. Extra blob.
The solution to all of this is to use a mediator class (or variant), to control how the driver interacts with the vehicle. This could be done in one of two ways, the driver can have a mediator to the car, which controls how the driver interacts with the car. Or the driver can have a mediator for each component or aggregate of the car that it must deal with. This is probably a better solution as the mediators can be reused for different types of car. The mediators must be able to handle the bi-directional relationships between components.
The CCar, being the container, is responsible for maintaining the mediators and hence the relationships between its components. Just the way it should be.
The mediator is responsible for handling this relationship between the components.
class CMediatorDriverToSteeringWheel
{
CMediatorDriverToSteeringWheel( CDriver* pDriver, CSteeringWheel* pSteeringWheel )
{
m_pDriver = pDriver;
m_pSteeringWheel = pSteeringWheel;
m_pDriver->AddMediator(this);
m_pSteeringWheel->AddMediator(this);
}
};
...
CCar::CCar( CDriver* pDriver )
{
m_pDriver = pDriver;
new CMediatorDriverToSteeringWheel( m_pDriver, &m_SteeringWheel );
new CMediatorDriverToHandbrake( m_pDriver, &m_HandBrake );
}
Related
In game development there is a notion of Entity System which is aiming to simplify the game loop by gaining a flexible architecture. For details see the links below:
http://www.richardlord.net/blog/what-is-an-entity-framework
http://shaun.boyblack.co.za/blog/2012/08/04/games-and-entity-systems/
Now I wonder how it is possible to realize automatic Node creation when a Component is added to an Entity in C++? Please tell me the principle of identifying what Nodes can be spawned from a specific Entity, i.e. you should have list of Component and classes that aggregate components. And you should understand what classes can be created with the list of data.
For example I have Components:
class PositionComponent
{
int m_x;
int m_y;
int m_rotation;
};
class VelocityComponent
{
int m_vX;
int m_vY;
int m_vAngular;
};
class RenderableComponent
{
Sprite m_view;
};
And nodes:
class MoveNode
{
PositionComponent m_position;
VelocityComponent m_velocity;
};
class RenderNode
{
RenderableComponent m_rend;
PositionComponent m_position;
};
Now if I create an Entity like this:
Entity * e = new Entity;
e.add(new PositionComponent);
e.add(new VelocityComponent);
Then I want to have a code that creates a MoveNode automatically, and if I add also this:
e.add(new RenderableComponent);
Then I want to know that also RenderNode is created. Consequently, when I delete it:
e.remove(new RenderableComponent);
the RenderNode should be deleted. And this process, of course, should not be bind to the specific Nodes and Components I have defined.
How is it possible to realize this in C++?
I am slightly confused, since it appears to mix concepts. I will try to shed some light on the two concepts.
Entity & Component
The entity component system is quite common in game engines, for example Unity implements it quite visibly. It tries to address the issue that simple inheritance does not work well in many cases, such as mixing rendering and collision information; is a Collidable also a Renderable? And since multiple inheritance is a scary thing for many and not supported in many languages, the only way out of this is the Entity/Component design. (Actually not the only solution, but that is a different issue.)
The design for entity component is quite simple, you have a class Entity that takes multiple objects of type Component. There will be multiple components that "do" something, like a MeshRenderer, TriMeshCollision or RigidBodyMotion. As stated in the articles, the actual logic does not need to be implemented in the components themselves. The component just "flags" the entity for specific logic. It makes sense to delegate the actual work to be done in a tight loop in a system, maybe even in a different thread, but more to that later.
Then the actual entity is composed. There are two basic ways to do this, in code or in data.
For example you compose objects in code that represent one "real world" object; the object of type Goblin exists and it is derived from the class Entity. The constructor from Goblin will then create all components and register them on itself. Inheritance is now only done for high level logic, for example the FastGoblin is derived from Goblin and only has a different material and speed setting.
The second way to create objects is through data, that is you have some form of object description language. (Take something in XML or JSON) This will then create in a factory method something based on a given template in that is defined in this object description language.
Node Based Work Scheduling
It may make sense to have objects that are fully defined, but the logic not being executed. Think about objects on the server or in the editor. On the server you do not want the rendering code to be in the way. So the basic approach is to create components that contain no data. The problem to solve is, how do you efficiently get things done without iterating through the entire scene each frame and typecasting the objects around?
What your second link describes is basically a botched version of Designing the Framework of a Parallel Game Engine
There needs to be a way to schedule the work in an efficient way. The proposed solution is to have "nodes" that each do a specific task. The nodes are then scheduled, by submitting them to either a work scheduler or a specific system.
Take for example rendering. You have an entity and it has a MeshRenderer component. This component will create a RenderNode and submit it to the RenderSystem. Then when it is time to render the frame the RenderSystem will simply iterate over each RenderNode and call its display method. In the display method the actual rendering is done.
Alternatively the system, engine or entity can create nodes based on specific component configurations. Take for example physics. The Entity has the TriMeshCollision and RigidBodyMovement components. The PhysicsSystem seeing this configuration creates a RigidBodyNode that takes the two components as inputs and thus implements rigid body motion. Should the entity only have a TriMeshCollision component the PhysicsSystem would then create a StaticColliderNode to implement the behavior.
But like the construction mechanic for components from data, the nodes can also be created and attached to the entity through a factory function. This can be part of either the object definition or a rule based system.
Mapping this design into C++ should be straight forward. The rather difficult bit is to figure out a way how the different bits get connected; for example, how the MeshRenderer gets access to the RenderSystem so it can submit its RenderNode. But this can be solved with a singleton (shudder) or by passing a Game/Engine object around at the construction of the Entity or Component.
Is this good design?
But the issue I want to address here is: Is this good design?
I have troubles with your second link (Games And Entity Systems), since I think the design will fall flat on its nose quite quickly. This is true for other aspects like physics, but this will become quite inefficient when considering modern 3D rendering.
When you need to organize the scene spatially to efficiently cull hidden objects, organize the objects into batches for lighting and reduce resource switching then the entire "list of nodes" concepts is moot since you need a separate organisational structure anyway.
At this point you can let the components "talk" directly to the systems and each system has its own unique specific API that is fit for its specific purpose. The requirements of rendering, sound and input are each significantly different and tying to cram them into on API is futile.
See Also
Entity/Component based engine rendering separation from logic
Problem statement
I have a model class that looks something like (extremely simplified; some members and many, many methods omitted for clarity):
class MyModelItem
{
public:
enum ItemState
{
State1,
State2
};
QString text() const;
ItemState state() const;
private:
QString _text;
ItemState _state;
}
It is a core element of the application and is used in many different parts of the code:
It is serialized/deserialized into/from various file formats
It can be written into or read from a database
It can be updated by an 'import', that reads a file and applies changes to the currently loaded in-memory model
It can be updated by the user through various GUI functions
The problem is, this class is has grown over the years and now has several thousands lines of code; it has become a prime example of how to violate the Single responsibility principle.
It has methods for setting the 'text', 'state', etc. directly (after deserialization) and the same set of methods for setting them from within the UI, which has side effects like updating the 'lastChangedDate' and 'lastChangedUser' etc. Some methods or groups of methods exist even more than twice, with everyone of them doing basically the same thing but slightly different.
When developing new parts of the application, you are very likely using the wrong of the five different ways of manipulating MyModelItem, which makes it extremely time consuming and frustrating.
Requirements
Given this historically grown and overly complex class, the goal is to separate all different concerns of it into different classes, leaving only the core data members in it.
Ideally, I would prefer a solution where a MyModelItem object has nothing but const members for accessing the data and modifications can only be made using special classes.
Every one of these special classes could then contain an actual concrete implementation of the business logic (a setter of 'text' could do something like "if the text to be set begins with a certain substring and the state equals 'State1', set it to 'State2'").
First part of the solution
For loading and storing the whole model, which consists of many MyModelItem objects and some more, the Visitor pattern looks like a promising solution. I could implement several visitor classes for different file formats or database schemas and have a save and load method in MyModelItem, which accept such a visitor object each.
Open question
When the user enters a specific text, I want to validate that input. The same validation must be made if the input comes from another part of the application, which means I can not move the validation into the UI (in any case, UI-only-validation is often a bad idea). But if the validation happens in the MyModelItem itself, I have two problems again:
The separation of concerns, which was the goal to begin with is negated. All the business logic code is still 'dumped' into the poor model.
When called by other parts of the application, this validation has to look differently. Implementing different validating-setter-methods is how it is done right now, which has a bad code smell.
It is clear now that the validation has to be moved outside both the UI and the model, into some sort of controller (in a MVC sense) class or collection of classes. These should then decorate/visit/etc the actual dumb model class with its data.
Which software design pattern fits best to the described case, to allow for different ways of modifying the instances of my class?
I am asking, because none of the patterns I know solves my problem entirely and I feel like I'm missing something here...
Thanks a lot for your ideas!
Plain strategy pattern seems the best strategy to me.
What I understand from your statement is that:
The model is mutable.
the mutation may happen through different source. (ie. different classes)
the model must validate each mutation effort.
Depending on the source of an effort the validation process differs.
the model is oblivious of the source and the process. its prime concern is the state of object it is modeling.
Proposal:
let the Source be the classes which somehow mutate the model. it may be the deserializers, the UI, the importers etc.
let a validator be an interface/super-class which holds a basic logic of validation. it can have methods like : validateText(String), validateState(ItemState)...
Every Source has-a validator. That validator may be an instance of the base-validator or may inherit and override some of its methods.
Every validator has-a reference to the model.
A source first sets its own validator then takes the mutation attempt.
now,
Source1 Model Validator
| setText("aaa") | |
|----------------------->| validateText("aaa") |
| |----------------------->|
| | |
| | setState(2) |
| true |<-----------------------|
|<-----------------------| |
the behavior of different validators might be different.
Although you don't state it explicitly, refactoring thousands of lines of code is a daunting task, and I imagine that some incremental process is preferred over an all-or-nothing one.
Furthermore, the compiler should help as much as possible to detect errors. If it is a lot of work and frustration now to figure out which methods should be called, it will be even worse if the API has been made uniform.
Therefore, I would propose to use the Facade pattern, mostly for this reason:
wrap a poorly designed collection of APIs with a single well-designed API (as per task needs)
Because that is basically what you have: a collection of APIs in one class, that needs to be separated into different groups. Each group would get its own Facade, with its own calls. So the current MyModelItem, with all its carefully crafted different method invocations over the years:
...
void setText(String s);
void setTextGUI(String s); // different name
void setText(int handler, String s); // overloading
void setTextAsUnmentionedSideEffect(int state);
...
becomes:
class FacadeInternal {
setText(String s);
}
class FacadeGUI {
setTextGUI(String s);
}
class FacadeImport {
setText(int handler, String s);
}
class FacadeSideEffects {
setTextAsUnmentionedSideEffect(int state);
}
If we remove the current members in MyModelItem to MyModelItemData, then we get:
class MyModelItem {
MyModelItemData data;
FacadeGUI& getFacade(GUI client) { return FacadeGUI::getInstance(data); }
FacadeImport& getFacade(Importer client) { return FacadeImport::getInstance(data); }
}
GUI::setText(MyModelItem& item, String s) {
//item.setTextGUI(s);
item.getFacade(this).setTextGUI(s);
}
Of course, implementation variants exist here. It could equally well be:
GUI::setText(MyModelItem& item, String s) {
myFacade.setTextGUI(item, s);
}
That is more dependent on restrictions on memory, object creation, concurrency, etc. The point is that up till now, it is all straight forward (I won't say search-and-replace), and the compiler helps every step of the way to catch errors.
The nice thing about the Facade is that it can form an interface to multiple libraries/classes. After splitting things up, the business rules are all in several Facades, but you can refactor them further:
class FacadeGUI {
MyModelItemData data;
GUIValidator validator;
GUIDependentData guiData;
setTextGUI(String s) {
if (validator.validate(data, s)) {
guiData.update(withSomething)
data.setText(s);
}
}
}
and the GUI code won't have to be changed one bit.
After all that you might choose to normalize the Facades, so that they all have the same method names. It isn't necessary, though, and for clarity's sake it might even be better to keep the names distinct. Regardless, once again the compiler will help validate any refactoring.
(I know I stress the compiler bit a lot, but in my experience, once everything has the same name, and works through one or more layers of indirection, it becomes a pain to find out where and when something is actually going wrong.)
Anyway, this is how I would do it, as it allows for splitting up large chunks of code fairly quickly, in a controlled manner, without having to think too much. It provides a nice stepping stone for further tweaking. I guess that at some point the MyModelItem class should be renamed to MyModelItemMediator.
Good luck with your project.
If I understand your problem correctly, then would I not decide yet which design pattern to chose. I think that I have seen code like this several times before and the main problem in my point of view was always that change was build upon change build upon change.
The class had lost is original purpose and was now serving multiple purposes, which were all not clearly defined and set. The result is a big class (or a big database, spaghetti code etc), which seems to be indispensable yet is a nightmare for maintenance.
The big class is the symptom of a process that is gone out of control. It is where you can see it happen, but my guess is that when this class has been recovered that a lot of other classes will be the first to redesign. If I am correct, then is there also a lot of data corruption, because in a lot of cases is the definition of the data unclear.
My advice would be go back to your customer, talk about the business processes, reorganize the project management of the application and try to find out if the application is still serving the business process well. It might be not - I have been in this type of situation several times in different organizations.
If the business process is understood and the data model is converted in line with the new data model, then can you replace the application with a new design, which is much easier to create. The big class that now exists, does not have to be reorganized anymore, because its reason for existence is gone.
It costs money, but the maintenance now costs also money. A good indication for redesign is if new features are not implemented anymore, because it has become too expensive or error prone to execute.
I will try to give you a different perspective of the situation you have. Please note that explanations are written in my own words for the simplicity's sake. However, terms mentioned are from the enterprise application architecture patterns.
You are designing the business logic of the application. So, MyModelItem must be some kind of a business entity. I would say it's the Active Record you have.
Active Record: business entity that can CRUD itself, and can manage
the business logic related to itself.
The business logic contained in the Active Record has increased and has become hard to manage. That's very typical situation with Active Records. This is where you must switch from the Active Record pattern to the Data Mapper pattern.
Data Mapper: mechanism (typically a class) managing the mapping (typically between the entity and the data it translates from/to). It
starts existing when the mapping concerns of the Active Record are so
mature that they need to be put into the separate class. Mapping becomes a logic on its own.
So, here we came to the obvious solution: create a Data Mapper for the MyModelItem entity. Simplify the entity so that it does not handle the mapping of itself. Migrate the mapping management to the Data Mapper.
If the MyModelItem takes part in the inheritance, consider creating an abstract Data Mapper and concrete Data Mappers for each concrete class you want to map in a different way.
Several notes on how I would implement it:
Make entity aware of a mapper.
Mapper is a finder of the entity, so the application always starts from the mapper.
Entity should expose the functionality that is natural to be found on it.
And entity makes use of (abstract or concrete) mapper for doing the concrete things.
In general, you must model your application without the data in mind. Then, design mapper to manage the transformations from objects to the data and vice verca.
Now about validation
If the validation is the same in all the cases, then implement it in the entity, as that sounds natural to me. In most cases, this approach is sufficient.
If the validation differs and depends on something, abstract that something away and call the validation through the abstraction. One way (if it depends on the inheritance) would be to put the validation in the mapper, or have it in the same family of objects as mapper, created by the common Abstract Factory.
In my game engine, that is written in C++, I've moved away from the classical hierarchical entity system and build up a component-based one. It works roughly in this way:
An entity is merely a container for components. Some example components are: Point, Sprite, Physics, Emitter.
Each entity can hold at most one component of each type. Some component depend on another, like Physics and Sprite depend on Point, because they need a position and angle delivered by it.
So everything works fine with the component system, but now I have trouble implementing more specialized entities, like:
A camera, which needs additional functions to handle movement and zoom
A player, which needs support to receive input from the user and move
Now, I could easily solve this with inheritance. Just derive the camera from the entity and add the additional zoom functions and members. But this simply feels wrong.
My question:
How can I solve the problem of specialized entities with a component system in C++?
You seem to be doubting the IS-A relationship here. So why not make it a HAS-A relationship? Instead of being an entity, the camera and the player could be objects that have an entity (or a reference to the entity), but exist outside of your component-system. That way, you can easily keep the uniformity and orthogonality of your component system.
This also fits nicely with the meaning of those two examples (camera/player) as 'glue' objects. The player glues the entity system to the input system and acts as a controller. The camera glues the entity system to the renderer and acts as a kind of observer.
What about just creating components that enable that behavior? For example, an InputComponent could handle input from the player. Then your design remains the same, and a player is just an entity which allows input from a keyboard, rather than input from an AI controller.
Components based system usually have a general method allowing to send "messages" to entities, like a function send(string message_type, void* data). The entity then pass it to all its components and only some of them will react to it. For example, your component Point could react to send("move", &direction). Or you could introduce a moveable component to have more control. Same thing for your camera, add a component view and make it handle "zoom" message.
This modular design already allow to define different types of cameras (like a fixed one not having the moveable component), reuse some component for other stuff (another type of entity may use a "view") and you can also gain flexibility by having various components handling each message differently.
Of course, some optimization tricks could be needed, especially for frequently used messages.
How about giving each entity some restrictions to what kind of components it may hold (and maybe also what it should hold), and loosening those restrictictions when you derive from that entity. For example by adding a virtual function that verifies whether a certain component can be added to the entity.
A common solution is to use the visitor pattern. Basically, you'll have your entity being "visited" by a Visitor class. Inside your entity, you'd have :
void onVisitTime(Visitor* v)
{
// for each myComponent...
v->visit(myComponent);
// end for each
}
And then, you'd have, in the Visitor class :
void visit(PointComponent* p);
void visit(CameraComponent* c);
Be aware that it's a bit of violation of OOP (data-manipulation being handled outside the object, since the visitor will handle it). And visitors tend to become over-complicated, so it's a not-so-great solution.
in a C++ program I have graphs to which I'd like to add some objects. Those can be, for example, common "stand-alone" objects like text, lines etc, or more "smart" objects of different types which act differently and can be connected to an external model to read/write its state.
The simplest thing I have in mind is creating a common interface to all objects with virtual functions like Draw() etc, but the objects can be essentially different (just like text box and scroll bar are different and thus have a different interface). On the other hand, If I don't create a common interface, I'll need to dispatch on objects types, which is usually considered bad practice in C++.
All this is supposed to be kept simple, for example creating widgets and custom message queues would be an overkill, but I want to make something easy to support/extend.
I know there are many patterns for GUI, such as MVC, MVP etc, but those are very general and I'm a bit lost, so if you could give me some directions (or even better, a reference to inspire from) that would be helpful! Thanks.
One possibility would be to use multiple inheritance. Define a drawable base class that only defines enough to draw a visible object, and require all your drawable objects to derive from that. They might (often will) derive from other base classes as well, to define other interfaces they support; that one will just ensure that every item can be drawn when needed.
For flexibility and scalability, you can use interfaces instead of a single base class. For example extend all objects that can be painted from a IDraw interface. If objects can be updated add and implement a IControl interface and so on. This may look first as an overhead but offers you a good scalability.
Edit:
void* Class::GetInterface(const int id)
{
if (IDraw::GetId() == id)
{
return (IDraw*)this;
}
else if (IControl::GetId() == id)
{
return (IControl*)this;
}
return NULL;
}
What does data abstraction refer to?
Please provide real life examples alongwith.
Abstraction has two parts:
Hide details that don't matter from a certain point of view
Identify details that do matter from a certain point of view and consider items to be of the the same class if they possess those details.
For example, if I am designing a program to deal with inventory, I would like to be able to find out how many items of a certain type the system has in stock. From the perspective of the interface system, I don't care if I am getting this information from a database, a csv file, a remote repository via a SOAP interface or punch cards. I just care that I can can say widget.get_items_in_stock() and know that it will return an integer.
If I later decide that I want to record that number in some other way, the person designing the interface doesn't need to know, care or worry about it as long as widget still has the get_items_in_stock() method. Like wise, the interface doesn't need to care if I subclass the widget class and add a get_square_root_of_items_in_stock() method. I can pass an instance of the new class to it just as well.
So in this example, we've hidden the details of how the data is acquired and decided that anything with a get_items_in_stock() method is an instance of the same class (or a subclass thereof) for certain purposes.
Data abstraction is any device that allows you to treat data as humans encounter it rather than as it is stored on machine.
At the lowest level, all primitive data types are abstractions -- as programmers, we don't usually have to deal with data at the bit level (which is how it is ultimately stored) but as integers, floating point numbers, characters, etc.
We then add layers onto that abstraction -- maybe two integers represents a Point, or we and enumerations to represent the months of the year, days of the week, etc.
With each abstraction layer, we move further from the machine and (hopefully) closer to human understanding of the data. This can extract a performance penalty -- it may not always be the case that points can be most efficiently represented by two integers. This is compensated for by the shorter development (and maintenance) time when abstractions are used.
The technique of creating new data type that is well suited to an application to be programmed is known as data abstraction.
Abstraction means providing only essential information to the outside world and hiding their background details..examp. In ur Computer u can see only monitor, keyboard nd mouse..u don't know anything about internal wiring this is abstraction.
Data abstraction seems to be explained as breaking data down as far as you can get it. food would be the abstraction of apple, orange, pizza. animal would be the abstraction of cat, cow, pig. A food object would be something like this pseudo code:
class food{
name;
calories;
weight;
public eat(name);
}
all foods have a name, calorie amount, and a weight. That's pretty abstract.
You could then make objects that inherit, which would be a bit less abstract.
class pizza inherits food{
toppings;
say_toppings();
}
pizza now has toppings, but it inherits name, calories, and weight from food.
basically abstraction has been explained as getting to the lowest level of each item and making classes that extend from them. It makes your code more reusable too... If you've bade your base class of food well enough, and included everything abstract about it anyone working in the food industry could use your class.
Abstraction is hiding the skeleton from the human body. The skin does a great way of containing it. (See how abstract I'm being there? Pun intended. I digress...)
If I have a water bottle, then I'm able to drink from it by opening the lid, twisting it until it pops off.
bool lid_open = false;
void open_water_bottle_by_twisting() { lid_open = true; }
But water bottles are containers. Containers hold liquids until they become open and they are able to be drunk from (assuming the liquid is drinkable).
class Container
{
bool lid_open = false;
protected:
Container() {}
void open_by_twisting()
{
lid_open = true;
}
public:
virtual ~Container();
};
class WaterBottle : public Container
{
WaterBottle() : Container() {}
public:
~WaterBottle();
};
However, not all containers are opened the same way. Some containers, such as the water bottle, have lids that can be twisted off. Others don't have lids, such as exercise bottles - those contain bendy straws that can be bent down for storage or up for drinking.
class Container
{
bool lid_open;
bool straw_open;
protected:
void TurnLid() { lid_open = true; }
void BendStraw() { straw_open = true; }
Container() : lid_open(false), straw_open(false){}
public:
virtual void open() = 0;
virtual ~Container();
};
class WaterBottle : public Container
{
public:
WaterBottle() : Container() {}
void open()
{
TurnLid();
}
~WaterBottle();
};
class ExerciseBottle : public Container
{
public:
ExerciseBottle() : Container() {}
void open()
{
BendStraw();
}
~ExerciseBottle();
};
But the client doesn't know what ExerciseBottle's implementation of ExerciseBottle's open() is. It calls BendStraw(), which then sets straw_open to true. But ExerciseBottle simply calls one function to do all of this work. The client doesn't have to perform several actions that are used in the implementation of open(). The case goes similarly for WaterBottle. And that's what abstraction is: letting the client know that the back-end will do all of the work for it. When the term "separating implementation from interface" is used, this is what is meant.
Is the complex system that uses data details which are easy to interact or encounter with humans, which differ from the way computer system stores such as in binary number system.
Answered by Neema, Rohan and Upendo (The programmers)
The technique of limiting the data attributes according to given scenario for development of software and removing all irrelevant attributes.This makes software development simpler.
Let's take one real life example of a TV which you can turn on and off, change the channel, adjust the volume, and add external components such as speakers, VCRs, and DVD players BUT you do not know it's internal detail that is, you do not know how it receives signals over the air or through a cable, how it translates them, and finally displays them on the screen.
It refers to the act of representing essential feature without including the background detail or the explanation
It is difficult to find day to day life example of DATA abstraction. However, any data types in programming language, tables and view in DBMS, data structures like LinkedList, List, Queue, Stack are data abstractions. These abstractions provide you the way to access the data in particular manner.
This article may help you understand data abstraction and control abstraction in depth. It also has some of the real life examples of control and data abstractions.
Abstraction rrefers to the act of representing essential features without including the background detail or explanation.
Simply Data Abstraction is nothing but the hiding unnecessary datails from user.
Example:Person simply just wants to make a call, he just select or dial no. and click on call button this info. is enough for him.He dont want to know about how connection is made and whatever process behind making call or how voice is transferred.
I know this question was asked long time ago. But still like to share one real life example which might help others to understand concept of abstraction very easily.
A real-world analogy of abstraction might work like this: You (the object) are arranging to meet a blind date and are deciding what to tell them so that they can recognize you in the restaurant. You decide to include the information about where you will be located, your height, hair color, and the color of your jacket. This is all data that will help the procedure (your date finding you) work smoothly. You should include all that information. On the other hand, there are a lot of bits of information about you that aren't relevant to this situation: your social security number, your favorite football players all are irrelevant to this particular situation because they won't help your date to find you.
Data Abstraction:
It is used to provide the necessary information to the user and hide the unnecessary information from the user. It is called data abstraction.
It will hide your business logic from outside the world.
Technical Example: Console.WriteLine();
Non Technical Example: TV remote, Car Remote.
More Detail: Data Abstraction with real-time example
data hiding deals the security features of oops. according to this property private data member of a class is accessible or visual only inside the class not outside the class.