Related
I had a simple concept for a 2d game. Think of like a Final Fantasy / D&D setting. I was working in C# but it's more of a general single-inheritance OO issue. I'm just assuming there's a scheme where you can implement many interfaces but inherit only one class.
There are three types of entities in the game: players, villagers, and enemies. To clarify, there can be multiple players (AI) because some may join the party.
For actions:
Players can do combat and dialogue. Villagers can only use dialogue. Enemies can only do combat.
For state:
All entities have a position on the map.
Combatants always have current health, max health, etc.
Dialogue entities always have some specific greeting text, dialogue options, etc.
Player, Villager, and Enemy would be my concrete classes. It seems I want 2 interfaces: Combat and Dialogue, handling all the actions. So far so good - however, these entities share state in a way problematic for single inheritance. Based on my design, it seems I want
an abstract Entity class with a position on the map
abstract classes AbstractCombatant the other AbstractDialogue both inheriting from Entity. AbstractCombatant, for example, has the state for health, equipment, etc.
The problem here is that Player would want to inherit from both Combatant and Dialogue abstract classes. With single inheritance, I can't. And if I could, I would have the diamond inheritance problem from the Entity class. Even if I just had my concrete classes inherit Entity instead, that would be another multiple inheritance problem. And of course, if I totally took the Entity part out of the equation and just mapped entities to positions separately, I would still suffer from the problem with Player inheriting from two classes.
I couldn't come up with a single-inheritance design that doesn't duplicate implementation. What is the best way to set up a class/interface hierarchy for this scenario?
It is only natural that you want to have a class for each concept (player, enemy, villager, etc.) in your problem domain / business domain. The issue arises naturally when these concepts share common features. Consider this example:
class House : IHouse
{
public int StreetNumber { get; }
}
class Boat : IBoat
{
public double SpeedKnots { get; }
}
class HouseBoat : House, Boat // does not compile
{
}
The simplest way to get around this is using aggregation.
Balanced
Keep references to all underlying concepts and implement the appropriate interfaces to provide all the required functionality.
class HouseBoat : IHouse, IBoat // implementing both interfaces is ok
{
private House house;
private Boat boat;
int IHouse.StreetNumber { get { return this.house.StreetNumber; } }
double IBoat.SpeedKnots { get { return this.boat.SpeedKnots; } }
}
Biased
Derive from one of the concepts (the one which is more similar) and implement the interface for the other concept(s).
class HouseBoat : Boat, IHouse // is more like a Boat
{
private House house; // model for the house aspects
int IHouse.StreetNumber { get { return this.house.StreetNumber; } }
}
Further Reading
This is quite a common problem since it comes naturally as mentioned above and both Java and C# do not allow multiple inheritance. A simple google query with the right search terms will provide abundant material.
I want to learn how to create good object-oriented (OO) design practice for collision between two objects situation in game development.
Let's say I have a SpaceShip class and a Meteor class. When Meteor collide with the SpaceShip, the SpaceShip will be destroyed.
The question:
What class should I put the method to check if there is collision between meteor and spaceship as well as the collision resolution method (destroy the spaceship)? Is it at SpaceShip class or Meteor class? Or maybe I should put at another class, ie. GameArea or GameController class?
Note: for the sake of simplicity, assume the Meteor and SpaceShip is in form of image resource. I'm used to use Java language, but other language is okay too.
It's more natural to think that collision detection is a responsibility which does not belong to Spaceship or Meteor classes. Especially when this gets complicated with multiple collision possibilities in different directions. If you put this logic in both these classes they will need to have references to lots of other objects that are around them which wouldn't be appropriate.
You could have this on a separate class such as CollisionDetector which keeps track of coordinates of all objects in game space and detect collisions. Collision prevention also appears to be a separate responsibility that should be in a different class in my opinion. You could have a separate class CollisionResolver for this. Depending on the requirements, CollisionDetector could talk to CollisionResolver.
CollisionResolver may need to be able to talk to Spaceships, for purposes such as advising them to change direction, or to command firing missiles towards the Meteor.
CollisionDetector and CollisionResolver could sit within the GameSpace/*GameController*. etc..
This would promote Single Responsibility Principle so each component would be doing only one focussed task.
Collision detection, in my opinion, is not part of an object... it should be defined as something else - some physics manager, etc. That way your objects will be independent on the collision algorithms.
Another thing is that in games usually object consists of several layers (components): Graphics Layer, Physics Layer, Logic Layer.
That way physics manager manages only physics component of given objects.
class GameObject
{
RenderComponent m_renderComponent;
LogicComponent m_aiComponent;
PhysicsComponent m_physicsComponent;
};
Well, I usually create a (sometimes generic) GameObject class or interface that has a collides method. For example:
template< typename T = int > class GameObject
{
public:
bool collides(const GameObject& obj);
};
// usage
GameObject<int> my_obj, your_obj;
if(my_obj.collides(your_obj)) { ... };
Another thing I sometimes (but rarely) do is to create a separate GamePhysics class:
template< typename T > class GamePhysics
{
public:
/* you may make this static or the class a singleton */
void detect_collision(const T& obj, const T& obj2);
};
In Java (or any other OO language) I would place a CollisionDetected callback/event in the common ancestor class of all moving objects in your game.
This is a simplified description of a game:
In a game, there's usually a game-loop. A game-loop is like a while(true) loop that runs continuously (kind of like the main UI thread of an application) and at every step checks what has changed with the objects, what should be updated and what events should be called (and more...).
For responsiveness, this loop should cycle many times a second.
Inside this loop, a Physics Engine object should continuously update it's status. This would be an instance object of an independent class. It's this engine that should detect collisions between objects and call the CollisionDetected event on all objects that have collided.
It's an idea, not the definitive solution...
Currently, I am trying to dissect some tight coupling between the data model and the UI in an application by introducing the MVC pattern. Basically, this means making the model aware of the associated views in order to have them informed whenever properties inside the model change.
The data model is represented by a nested structure:
Model
- Node
- Leaf
- Leaf
- Node
- Leaf
Each element inherits from a common abstract base class (StructuredNode).
The problem I've been thinking about is: observers should be able to subscribe to the Model (and only the Model), but each element should be able to emit change notifications. This could be achieved in two ways - either notifications are routed up the hierarchy until they reach the Model, where they get pushed to the observers, or by implementing notifications in the base class, with a static observers list, as in this example:
public abstract class Base {
private static Map<IObserver> observers;
protected synchronized void internalSubscribe(final IObserver observer) {
observers.add(observer);
}
protected synchronized void notifyObservers(final Base obj) {
for (IObserver observer : observers)
observer.changed(obj);
}
// .. other base class operations
}
In this implementation, only Model would offer a public subscribe method, which internally would delegate to the protected internalSubscribe method of the base class. At the same time, each derivative of the base class could send a change notification, like this:
// Perform some operations that change the object's internal state
// ...
// Then notify all observers
notifyObservers(this);
Is this rather good or rather bad practice (using a static observers list)? Any opinions on this? Are there alternative solutions?
A static observer list is not a common solution, and I would not consider it a good practice for a generic use model.
Observers would be notified of changes to models they are not interested in. This means that all the burden of identifying the model firing the notification falls on the observers, which probably have no good and efficient way of doing it other than going up the hierarchy and finding the root node... a lot of code, that must potentially be implemented several times in several observers. In the end it would be simpler for the observer to ignore considerations and just update or recalc, even when the updated model is not the one it's interested in.
Of course all this may not apply in your case. If you know you will not have more than one model of this class in your application, then you can very well go with this solution.
Anyway, the requirement of having only the Model with a public subscribe method should not constrain you to using a static observer container to share among all Model instances. As you said, there is another way. Routing the notifications up the hierarchy is IMHO the correct way to go.
If you want to avoid routing, then you could choose to have the nodes keep a reference to their model. This may be more efficient if you know the tree structure will be deep an not very dynamic. If nodes can be moved from one Model to another, than this is a bit risky and requires some further code to keep the reference updated.
Q1.
In my university studies of object-oriented modelling and design they recommend thinking about what an object can do for its method, and what its responsibilities are for its attributes. All attempts at clarification have resulted in further confusion.
This tends to generate a class diagram with actors who have all the actions, and inner classes which only hold data.
This doesn't seem correct. Is there another way of thinking about how to model the objects?
Q2. Also, the course seems to emphasize modelling the objects after their real-world counterparts but it doesn't necessarily make sense in the domain model. IE. In a medical practice, they have Patient: CreateAppointment(), CancelAppointment() but that is not how it would be implemented (you would modify a the appointment collection instead). Is there another way of thinking about this?
Example Q1
Secretary: RecordAppointment(), RecordAppointmentCancellation()
Appointment: time, date,... (no methods)
Example Q2
Doctor: SeePatient()
While SeePatient is a use-case, it does not make sense for a method on the actual class. How do you think about this?
Unfortunately, the roadblock you've hit is all too typical in academia. Academic projects tend to start with video rental stores, libraries or student registration systems (yours is a variance of this with a doctor's office) and then inheritance is taught with animals. The guideline you've provided is also very typical
they recommend thinking about what an object can do for its method, and what its responsibilities are for its attributes
In fact when beginners ask I usually explain an object's property's are the things it knows about itself and its methods are the things it knows how to do. Which is really just another way of saying exactly what you have there. As you've discovered this way of thinking quickly breaks down when you start discussing more tangible systems and not just examples.
For instance the guideline works pretty well with this object:
public class Tree
{
public int Height { get; set; }
public void Grow(int byHowMuch)
{
Height += byHowMuch;
}
}
While this certainly fits the bill your right to think that it doesn't "feel" right:
public class Secretary
{
public void MakeAppoinment(Patient patient)
{
//make the appointment
}
}
So what's the solution? It's a matter of taking what you are being taught and applying it. Learning and understanding design patterns will help a lot with developing systems which are more functional than a tree that knows how to grow.
Recommended reading:
Design Patterns: Elements of Reusable Object-Oriented Software (also known as the Gang of Four or GoF)
Head First Design Patterns
Head First Object-Oriented Analysis and Design
To solve the issue you're been presented I would probably use a combination of inherited person classes and interfaces, which would perform their actions through a series of service classes. Essentially a secretary, doctor, and patient would all inherit from person and each of these classes could be passed to accompanying service classes. The service classes may or may not do things like SeePatient(). Please don't take this example to mean that person classes wouldn't have methods.
Stack Overflow has more than a few related questions which may be of use:
Is Single Responsibility Principle a rule of OOP?
Are there any rules for OOP?
why is OOP hard for me?
Additionally, it would be good to check out:
Single responsibility principle
Don't repeat yourself
PrinciplesOfOod
Finally, there isn't a single definition of what makes an application object oriented. How you apply patterns, principles etc. will define your program. The fact that you are asking yourself these questions shows that you are on the right track.
Q1
Is it possible responsibilities of your objects should be interpreted as authorization or contract requirements, as in what actions they should take? So, to take a medical example from your Q2, an object with a Scheduler role (think C#/Java interface, or Obj-C protocol) has attributes around CanEditAppointments or EditsAppointments.
Q2
From a use case perspective, a patient may be able to create an appointment, and so you might implement a Patient in your object model with a method to CreateAppointment(). But, in terms of encapsulation, you would likely instantiate an Appointment object in CreateAppointment(), and then call methods or set properties on the Appointment object to set its time, date, patient, physician, etc.
And because the Appointment collection is likely to be permanent storage like a database, it would likely be the Appointment object's responsibility to add itself to the collection (Appointment.Schedule() goes through your data access layer to save itself to the database).
That also ties back to your Q1, in that the Appointment object's responsibility is to save itself, so it might implement an ISaveAppointment interface that requires fields and methods to carry it out. It also is the Appointment's responsibility to have a date, and time, and patient, etc., before being saved, and so the ISaveAppointment interface should require they exist, and Appointment.Schedule() should validate the values are correct or have been previously validated.
You are right that in many cases there are higher order things which more naturally contain behaviour, like the system, or the user.
You can model this behaviour in classes as static methods which operate on the data model. It isn't OO, but it's fine. You can group related methods together into such classes, and soon you have the notion of "services", as in service oriented programming.
In Java there are specifications and standards for creating such classes, namely the stateless session bean in EJB. The Spring Framework has similar notions with the stereotype "Service" which can be applied to classes to tag them as being facades for business logic.
A service is then a component which encapsulates a certain functionality or behaviour in the system. It operates on a given object model (either its own internal one, or the more general business object model from the system). If you take your use cases and create services which relate directly to them, you can write very maintainable software.
The DCI Architecture is a formalisation of this and an attempt to do the same, but at the same time trying to stay true to object orientation, by adding behaviour to objects as they need it.
I still experience the confusion: "am I telling you to do something else" or "am I doing something someone else asked of me"?
Perhaps all you have to do is play Barbie's, or G.I. Joe's to understand object interaction and where responsibilities go. G.I. Joe got wounded (or Barbie broke a nail) so he calls the Dr's office. "Hey doc, this is Joe, I need an appointment." So you, the kid, tell Barbie to go to the doctor, who needs to know the doc to call and how to call - a reference and public MakeAppointment() method. The Dr. office needs to put the appointment on the books - it's own BookAppointment() method that is the office's procedure for handling appointment requests.
public abstract GenderAppropriateDolly {
protected DrOffice Drkilldare;
public override MakeAppointment() {throw new NotImplementedException();}
}
public class GIJoe : GenderAppropriateDolly {
DrKilldare = new DrOffice();
List<Appointment> myAppointments = new List<Appointment>;
public void MakeAppointment () {
myAppointments.Add(DrKilldare.BookAppointment(this));
}
}
public class DrOffice {
List<Appointment> officeAppointments = new List<Appointments>;
public Appointment BookAppointment(GenderAppropriateDolly forWhom) {
Appointment newappt = new Appointment(formWhom);
this.Appointments.Add(newappt);
return newappt;
}
}
public class Kid {
GenderAppropriateDolly myRoleModel = new GIJoe();
// Joe got wounded so ...
myRoleModel.MakeAppointment();
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
When to use an interface instead of an abstract class and vice versa?
Hi, I am teaching OOP concepts to non-programmers. I wanted to know how can you explain the difference between an interface and an abstract class.
What I am actually looking for, is a real world example that can help highlight the difference between the two.
The player Interface
In my Java courses I often use this kind of image and ask: "What is this ?"
Every time someone will say "that's a player". From this image you can teach anybody what an interface is. This Interface allow any user to "play" something. Everybody knows what these buttons mean, even if you don't know what exactly will be done, you can use anything with this interface and you know that the little arrow will "play" and other arrows will probably send you forward or backward.
Everything that will have those buttons will provide a standard behavior that any user will know before even starting to use them.
I usually try to avoid the "contract" word which can be misunderstood.
The DVD player Abstract class
And then from the Play Interface, I go to the VCR (or DVD) player. Every constructor of DVD player must add some special functions to transform a simple unknown player into a DVD player. For example the eject button. And they must correctly implement Player.
The play button will launch the content of the DVD.
But even if DVD Player provide the basic behavior of a DVD player, not everything is done. You can't simply have "a" DVD player, it has a brand and most of the time it has its own firmware. A this time you'll need to extend the DVD Player abstract class to add your own little components.
Here's a good comparison of the two: interface vs abstract class. I've copied a specific example from there below:
Interface
Interfaces are often used to describe the peripheral abilities of a class, not its central identity, e.g. An Automobile class might implement the Recyclable interface, which could apply to many otherwise totally unrelated objects.
Abstract class
An abstract class defines the core identity of its descendants. If you defined a Dog abstract class then Dalmatian descendants are Dogs, they are not merely dogable. Implemented interfaces enumerate the general things a class can do, not the things a class is.
Interface
An interface is simply a specification. It describes what something MUST do. Nothing more, nothing less. On its own, it is meaningless. It is only useful when someone takes that specification and implements it.
Think of a USB memory stick. It conforms to the specifications of USB. A device communicating with it doesn't need to know or care how the memory stick is going about its job, all it needs to know is that when we ask for data to be written, it is written; conversely, when we ask to read data from it we expect to receive the data.
In computing terms, we use an interface in the same way. If we have:
public interface IUSB
{
Data Read();
bool Write(Data data);
}
We know that anything implementing this interface has to provide an implementation for Read and Write. How or what it does behind the scenes is of no concern to us. By passing an interface around our code we're not tying ourselves down to specific implementations.
Abstract Class
An Abstract Class simply provides us with a means to put in place specification in a base class that derived types must implement, as well as common code that can be used by all derived types.
I've been trying to thing of a good real-world example and have struggled, so can only really come up with a code example.
Say you wanted to implement an employee hierarchy in your code. So you may have:
public abstract class Employee
{
public string FirstName { get; protected set; }
public string LastName { get; protected set; }
public string Grade { get; protected set; }
public int Salary { get; protected set; }
public abstract void GivePayRise();
}
Every employee has a name and an associated job grade. We can model this in the base class with the first 3 properties. However, giving a bonus may not be a straightforward affair, depending on grade etc. So, we mark this as abstract. Every derived type of Employee (Part-Time, Full-Time, Contract, Consultant) has to implement this.
An implementation may be:
public class FullTimeEmployee : Employee
{
public void GivePayRise()
{
Salary *= 1.1;
}
}
public class PartTimeEmployee : Employee
{
public void GivePayRise()
{
Salary *= 1;
}
}
So we want to give a 10% raise to full-time employees, but nothing to part-time ones.
Difficult to give good examples - I generally tend to use interfaces, can't really remember in the past year or so when I've used an abstract class. This could start the whole Abstract Class vs Interface debate, but that's a whole new page.......
For everything computer related, I use a cooking dinner example. I start by saying that hard drives are cabinets/storage closets. Memory is like your counter. Processor is the cooking apparatus (stove). You are like the system bus (moving things around, etc...). So when you boot a computer, you take your basic ingredients out of storage and put them on the counter (loading the OS). This is a loose example, but it works well.
Now to move into OOP: an ingredient is an object, so is a tool (bowl, knife, spoon, etc...). Each one of these has properties (knife= handle_color: black, blade_type: serrated, etc...). And each one has methods/actions that you can perform with them (knife = cut(pepper)).
Now you can take this as far as you want to. For instance, there are green, yellow and red peppers. Each one is a pepper, so you can say "inherit the pepper class" (layman: take everything you know about a pepper and apply it to this specific pepper, pepper has a color attribute, a red pepper is color=red).
You can even separate class from instance (this particular pepper is an instance, whereas on the recipe card it's a class).
So you could make some pseudocode:
class pepper {
var color
var spiciness
var size
}
class redPepper extends pepper {
construct(){
$this->color=red
}
}
class cuttingKnife extends knife{
construct(){
$this->blade_type=serated
}
}
class cookingPot extends pot{
construct(){
//We all know what a cooking pot is
}
}
class stove extends apparatus{
construct(){
//We all know what a stove is
}
}
$knife = new cuttingKnife();
$myPepper = new redPepper();
$pot = new cookingPot();
$stove = new stove();
$knife->cut($myPepper);
$pot->putOn($stove);
$stove->cookOn("high");
$pot->putIn("water");
$pot->putIn($myPepper);
//This will boil a cut pepper
Of course, people won't necessarily understand the pseudocode, but they would understand how to boil something. They would understand the difference between a "pepper" and a "red pepper". I think you can pretty much use this analogy for any computer related thing with some minor tweeks.
multithreading: add more burners to the stove and another cook in a single kitchen
multicore arch.: add a second kitchen
downloading/installing software: go to store, find food, bring home, deposit in storage
partitioning a HDD: different cabinets/fridge could be Linux proc system (because it's special).
Etc...
Interface: The buttons of the remote control. Users know how these buttons are supposed to function.
Concrete class: Toshiba RC, Philips RC, JVC RC - what's inside the box is the concrete implementation.
Abstract class: The stencil a tailor uses in order to create a Made to measure garment. While You can't wear the stencil itself it is used to produce suits You can wear - the suits are "derived" from the stencil.
Interface: A dress code.
A good example is a calculator. Inside a calculator is a circuit board that has connections between its display, buttons, and a logic processor.
The circuit board acts like an abstract class. It provides the plumbing for any calculator built with it. In addition, it has certain interfaces that connect to a display, to an array of buttons, and to a logic processor.
In turn, any display manufactured to work with the circuit board must have a connector that fits the display interface on the circuit board. The same goes for the buttons and the logic processor, the latter likely having a certain arrangement of pins that align with the interface on the circuit board.
A developer using OOD would create an abstract class, CalculatorBase, to define the plumbing between the buttons, the display, and the internal logic. The abstract class would also specify how derivative classes use this plumbing to respond to certain events.
CalculatorBase, however, wouldn't depend on a specific display, a specific set of buttons, or even a specific implementation of logic. Instead, the developer specifies an interface for each, such as ICalculatorDisplay, for example. ICalculatorDisplay would specify how CalculatorBase expects to interact with a display. CalculatorBase would then work with any display that implements ICalculatorDisplay.
(In some languages, abstract class is used the same way as an interface, so it may be confusing)
A handful of classes that all have a certain common interface is like a handful of words that can fill in the the blank in a sentence. Example:
____ has wings
Chicken has wings
Airbus A320 has wings
However, the classes themselves, while they can all fit the blank in the sentence, do not have any relatioship in between. Chicken is a fowl while Airbus A320 is an aircraft. The only commonality is that they both have something that we call "wings". (You can also say that the true meanings of the "wings" are different in the two situations.)
class IHasWings : public IUnknown
{
public:
// IUnknown methods: (Inherited)
// IHasWings methods:
virtual HRESULT GetWingSpan([out] double* pdblWingSpan) = 0;
virtual HRESULT IsWingMovable([out] BOOL* pIsMovable) = 0;
virtual HRESULT IsWingDetachable([out] BOOL* pIsDetachable) = 0;
};
class Chicken : public ... ..., public IHasWings
{
};
class AirbusA320 : public ... ..., public IHasWings
{
};
Very simply put, an interface defines how you can talk to me.
Whereas an abstract class could define one of my talents such as playing the guitar. The problem is that "playing guitar," by itself isn't really that useful. But we could use this ability to create a type of person, such as a musician (which we could say is a class).