I have 2 classes, player and game and a method called get_player_games($player_id). Which class does this method belong to?
I seem to run into this problem a bit, where I'm not 100% sure which class the method should go in. Is it just a matter of preference?
Thanks
It's a typical cross-reference sort of situation -- to be completely objective, it can go in either class. It really is a matter of preference, assuming that a player can have multiple games and a game can be associated with multiple players.
That said, I've always approached it philosophically from the way you're inclined to name the method in the first place -- get_player_games() sounds like you're interested in the games for a particular player. The player is the subject of interest (based on the limited English-style grammar of the method name), the games happened to be the detail associated with that. If you had said get_game_players() or get_games_for_player(), then I would say that the games are the subject of interest, not the player.
Obviously, I'm biased by the noun you chose first (again, from a biased English grammar point of view), but since you can argue that the method belongs in either class, it's the only possible basis to use in such a case.
Again, it's somewhat of an arbitrary decision, but I've always been inclined to follow what the method naming rhetorically suggests to me about in which class it belongs.
I see it as:
Game
Class Game stores information about a game.
Game includes current game details such as score, players (in game), and other details.
There may be one or more games at one time.
Player
Class Player stores information about a player in a game.
Player includes details about the player, such as name, UID, contact, and other details.
So, if you need a player's list of current games, you need to have a list of games, and a list to store players. This feels like a static method.
So... Where does it go? I would say in neither Game nor Player class. Why not a Games class? One that...
Referenced current games (and associated players)
High score charts
Game histories (who has played, when, how long, etc...)
So, to me, you need a Games class that allowed you to statically call lists of information related to what games were in progress, who is playing, high score lists, etc...
Here is one way to think of it: A game can have 1 player. A game can have 2 players. A game can have N players. Does that sound good?
How about this: A player can be a part of 1 game. A player can be a part of 2 games. A player can be a part of N games.
Now, think about how your application is architected. Which one of the above works best? The answer largely depends on whether or not it's a one to many relationship between games and players, a one to many relationship between players and games.
Of course, if it's a many to many relationship, then both classes may need that method.
Assuming that a Game object models a single game, then the method clearly does not belong there as any given game would have no knowledge of other games. It is conceivable that a Player object could keep a list of all games in which the player has participated. But the way you have phrased the question suggests that we don't have a reference to a Player object but rather only a player ID. Therefore, Player doesn't work either.
It sounds like that method would belong on a class named MatchHistory or Tournament or Ladder or something like that.
Related
So I am developing a web text-based game and whatever business requirement shows up it adds a new method to the Player class. If you have developed a game in OOP way you possible know what I am talking about.
On my daily job I am developing a game server project and again, it has a HUGE Player class. The way they made that class to not be even bigger is making something like "managers": PlayerAttributeManager, PlayerFoodManager and those are just examples. So you would not call Player.getFood, Player.getTastyFood and so on, but those would be in PlayerFoodManager for example.
A friend was making a game for android and again most if his logic was in the Player class. However a huge Player class does not break the design patterns I think, because in those games a Player can do so much things and everything is related to the player.
Please give me any advice on how to have a smaller class when creating a game.
A way to keep your Player class small(er) is to take the OOP pattern further. Let's assume that your player does, at the moment, know about food, knows how to eat, etc. Why not factor out those things and take a different point of view: Your player has, for want of a better word, a digestion - or, in OOP, an attribute of type "Digestion", which is in itself a class covering hunger, eating, etc.
A similar principle can be applied to other aspects of your player.
At the end, your player would have fields of type Digestion, Health, Armory, ..., and these aspects would be self-contained classes, keeping the player class small.
Of course, health would have some interaction with digestion presumably - this can be managed by using interfaces.
I've been tasked with writing an essay extolling the virtues of object oriented programming and creating an accompanying game to demonstrate them.
My initial idea is to find a tutorial for a simple game written in a programming language which does not follow the OOP paradigm (or written in an OOP language but not in an OOP way) and recreate it in an OOP way using either C# or Java (haven't yet decided). This would then allow me to make concrete comparisons between the two.
The game doesn't have to be anything complex; Tetris, Pong, etc. that sort of thing. The problem I've had so far is finding a suitable tutorial, any suggestions?
Let's say that you found source code for a game not in OOP. There are some OOP virtues that you can point out in your essay:
Organization.
Since a game has many tasks, it is a good idea to assign a responsibility to one class. This means write one class that keeps score, one class that does file access (reading and writing game state, for example), classes to represent your characters, etc. Otherwise, you will have one huge text file with thousands of lines of code. It would be a nightmare to even look at it, let alone find what you need and fix it.
Encapsulation.
This is grouping together properties and functions for better organization. We used to have a different array to store each property - (example) one array for aircraft names, one array for firepower, another array for top speed, etc. That sucks because you need to make sure that the same index across all those arrays actually describes the correct aircraft. It's better to create an Aircraft object and give it those property names. You'll then have one array that holds aircraft - no need to keep track of too many arrays.
Reusability.
As you write more games (and even other apps), you will come across the need to reuse classes. For example, you would use the same Card class in your Solitaire game as any card game you'll write in the future.
Polymorphism/Inheritance.
Say that you want to display each character - both heroes and villains in some sort of a grid. You will want both Hero and Villain to inherit Character. Character will have common properties and even a[n abstract] Display() function. You would then write the custom Display() function for Character and Villain (that access class-specific data for drawing). You then create an array of Character objects, and you may store either a Villain or Hero in each slot. When the game goes through that list to display, each item.Display() call will automatically pick the correct Display() function based on the Character's actual type. Try to do this without OOP and you'll end up with a long if-else (and probably even nested) statement and all drawing routines in one place.
That's just from the type of my head from experience in general programming that you can definitely apply in game programming. There are probably more OOP aspects than mentioned, so you may want to research. Best of everything for your essay!
You can try grabbing a (simple) TI-Basic game from TICalc, Omnimaga, or most other calculator programming websites and try to understand its code.
Try a BASIC game from this site:
http://www.atariarchives.org/basicgames/
Context:
In a game, when each level is completed, a Rating is stored based on player performance: Poor, Good, Excellent.
The ratings are later used to evaluate the game play as a whole.
Question:
Should the Rating object contain a rating choice as an enum {RatingPoor, RatingGood, RatingExcellent} or should I make an abstract base class Rating with subclasses RatingPoor, RatingGood, RatingExcellent.
Other details
Ratings don't have complex behaviors, they are just generated from play stats at a very low frequency like every minute. They're assigned to a collection and averaged at the end of a game to generate a Rank (like Cadet, Pilot, Captain, Admiral). At the end of a level, the rating is shown as an icon (think stars, like in Angry Birds). They also get stored when the player pauses or suspends the game.
I would also appreciate knowing how to decide on enum vs. subclass, given this context.
This situation is basic enough that you should just use an enum. I typically use enum's when something can be represented by an integer (a mode, a setting, or in your case, a rating,). A subclass is only necessary if your ratings would include additional attributes or relationships.
I think that a subclass would be overkill for this situation, as it doesn't sound like you're attaching any particular methods to each rating. I would use an enum.
I'm no expert in software design, but I generally err towards using the simplest data structures that will get a job done-- in general, if the problem doesn't require you to have methods travelling with the data, a class would be more heavyweight than necessary.
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!
I'll be as direct as I can concerning this problem, because there must be something I'm totally missing coming from a structured programming background.
Say I have a Player class. This Player class does things like changing its position in a game world. I call this method warp() which takes a Position class instance as a parameter to modify the internal position of the Player. This makes total sense to me in OO terms because I'm asking the player "to do" something.
The issue comes when I need to do other things in addition to just modifying the players position. For example, say I need to send that warp event to other players in an online game. Should that code also be within Player's warp() method? If not, then I would imagine declaring some kind of secondary method within say the Server class like warpPlayer(player, position). Doing this seems to reduce everything a player does to itself as a series of getters and setters, or am I just wrong here? Is this something that's totally normal? I've read countless times that a class that exposes everything as a series of getters/setters indicates a pretty poor abstraction (being used as a data structure instead of a class).
The same problem comes when you need to persist data, saving it to a file. Since "saving" a player to a file is at a different level of abstraction than the Player class, does it make sense to have a save() method within the player class? If not, declaring it externally like savePlayer(player) means that the savePlayer method would need a way to get every piece of data it needs out of the Player class, which ends up exposing the entire private implementation of the class.
Because OOP is the design methodology most used today (I assume?), there's got to be something I'm missing concerning these issues. I've discussed it with my peers who also do light development, and they too have also had these exact same issues with OOP. Maybe it's just that structured programming background that keeps us from understanding the full benefits of OOP as something more than providing methods to set and get private data so that it's changed and retrieved from one place.
Thanks in advance, and hopefully I don't sound too much like an idiot. For those who really need to know the languages involved with this design, it's Java on the server side and ActionScript 3 on the client side.
I advise you not to fear the fact, that player will be a class of getters and setters. What is object anyway? It's compilation of attributes and behaviours. In fact the more simple your classes are, the more benefits of an OOP you'll get in the development process.
I would breakdown your tasks/features into classes like that:
Player:
has hitpoints attribute
has position attribute
can walkTo(position), firing "walk" events
can healUp(hitpoints)
can takeDamage(hitpoints), firing "isHurt" event
can be checked for still living, like isAlive() method
Fighter extends Player (you should be able to cast Player to Fighter, when it's needed) :
has strength and other fighting params to calculate damage
can attack() firing "attack" event
World keeps track of all players:
listens to "walk" events (and prevents illegal movements)
listents to "isHurt" events (and checks if they are still alive)
Battle handles battles between two fighters:
constructor with two fighters as parameters (you only want to construct battle between players that are really fighting with each other)
listens to "attack" events from both players, calculates damage, and executes takeDamage method of the defending player
PlayerPersister extends AbstractPersister:
saves player's state in database
restores player's state from database
Of course, you game's breakdown will be much more complicated, but i hope this helps you to start thinking of problems in "more OOP" way :)
Don't worry too much about the Player class being a bunch of setters and getters. The Player class is a model class, and model classes tend to be like that. It's important that your model classes are small and clean, because they will be reused all over the program.
I think you should use the warpPlayer(player, position) approach you suggested. It keeps the Player class clean. If you don't want to pass the player into a function, maybe you could have a PlayerController class that contains a Player object and a warp(Position p) method. That way you can add event posting to the controller, and keep it out of the model.
As for saving the player, I'd do it by making Player implement some sort of serialisation interface. The player class is responsible for serializing and unserializing itself, and some other class would be responsible for writing the serialised data to/from a file.
I would probably consider having a Game object that keeps track of the player object. So you can do something like game.WarpPlayerTo(WarpLocations.Forest); If there are multiple players, maybe pass a player object or guid with it. I feel you can still keep it OO, and a game object would solve most of your issues I think.
The problems you are describing don't belong just to game design, but to software architecture in general. The common approach is to have a Dependency Injection (DI) and Inversion of Control (IoC) mechanisms. In short what you are trying to achieve is to be able to access a local Service of sorts from your objects, in order for example to propagate some event (e.g warp), log, etc.
Inversion of control means in short that instead of creating your objects directly, you tell some service to create them for you, that service in turn uses dependency injection to inform the objects about the services that they depend on.
If you are sharing data between different PCs for multiplayer, then a core function of the program is holding and synchronising that piece of state between the PCs. If you keep these values scattered about in many different classes, it will be difficult to synchronise.
In that case, I would advise that you design the data that needs to be synchronised between all the clients, and store that in a single class (e.g. GameState). This object will handle all the synchronisation between different PCs as well as allowing your local code to request changes to the data. It will then "drive" the game objects (Player, EnemyTank, etc) from its own state. [edit: the reason for this is that keeping this state as small as possible and transferring it efficiently between the clients will be a key part of your design. By keeping it all in one place it makes it much easier to do this, and encourages you to only put the absolute essentials in that class so that your comms don't become bloated with unnecessary data]
If you're not doing multiplayer, and you find that changing the player's position needs to update multiple objects (e.g. you want the camera to know that the player has moved so that it can follow him), then a good approach is to make the player responsible for its own position, but raise events/messages that other objects can subscribe/listen to in order to know when the player's position changes. So you move the player, and the camera gets a callback telling it that the player's position has been updated.
Another approach for this would be that the camera simply reads the player's position every frame in order to updaet itself - but this isn't as loosely coupled and flexible as using events.
Sometimes the trick to OOP is understanding what is an object, and what is functionality of an object. I think its often pretty easy for us to conceptually latch onto objects like Player, Monster, Item, etc as the "objects" in the system and then we need to create objects like Environment, Transporter, etc to link those objects together and it can get out-of-control depending on how the concepts work together, and what we need to accomplish.
The really good engineers I have worked with in the past have had a way of seeing systems as collections of objects. Sometimes in one system they would be business objects (like item, invoice, etc) and sometimes they would be objects that encapsulated processing logic (DyeInjectionProcessor, PersistanceManager) which cut across several operations and "objects" in the system. In both cases the metaphors worked for that particular system and made the overall process easier to implement, describe, and maintain.
The real power of OOP is in making things easier to express and manage in large complex systems. These are the OOP principles to target, and not worry as much whether it fits a rigid object hierarchy.
I havent worked in game design, so perhaps this advice will not work as well, in the systems I do work on and develop it has been a very beneficial change to think of OOP in terms of simplification and encapsulation rather than 1 real world object to 1 OOP class.
I'd like to expand on GrayWizardx's last paragraph to say that not all objects need to have the same level of complexity. It may very well fit your design to have objects that are simple collections of get/set properties. On the other hand, it is important to remember that objects can represent tasks or collections of tasks rather than real-world entities.
For example, a player object might not be responsible for moving the player, but instead representing its position and current state. A PlayerMovement object might contain logic for changing a player's position on screen or within the game world.
Before I start simply repeating what's already been said, I'll point towards the SOLID principles of OOP design (Aviad P. already mentioned two of them). They might provide some high-level guidelines for creating a good object model for a game.