I'm designing a simple game and I'm not sure how to correctly handle the access and relations between classes. E.g:
Class Game - method Start that will initialiaze objects (fields) Player, CPUPlayer, Board.
Player/CPUPlayer contains a method "Place a pawn" but they would need to access the Board object to check for coordinates.
But they do not see the Board object. Does it mean I need to pass the Board object reference (or any other objects) in their constructor?
Yes, if they have a dependency on that object you need to inject it into them when they are created. The constructor is the right place. Later on, as you get a handle on things, you may want to look into using a DI container like Unity or something, but for now, just receive an instance of the Board in their constructors.
In this particular case, it does indeed seem that they need a reference to a Board object. If you would like to over-engineer that, you could create a specialized interface ICoordinateCheckable, implement it in the Board, and have Player accept an instance of this interface (instead of the Board) in constructor.
Related
I'm developing a complex desktop client with C#, which is mainly for some scientific analysis work. The class hierarchy of my project is very complicated. The problem is that, a large amount of parameters should be able to be modified by the user at the entrance of the client.
However, many parameters are very deep in the class hierarchy (I mean the composition hierarchy, not inheritance). As a result, classes closed to the top levels must take a lot of arguments in the constructor, because they are passed all the way up from different classes at the bottom levels.
What's the best practices to handle problems like this? I have 3 ideas:
Global static variables: Just create a Constants class and store these params as static fields, like Constants.FOO, Constants.BAR.
Singleton class: Create a singleton class, and initialize it at the entrance of program. Get these params like Constants.GetInstance().FOO.
For every class, receive lower-level params in the constructor, which makes the constructor signature verbose and complicated. For example, a mid-level frequently-used class may take 15 arguments in the constructor.
If I use global variables or a singleton too often, the code will become very coupled. But if I do not use them, lots of params must be passed and received along the class hierarchy again and again. So how would a complicated commercial software do to solve this problem?
For example, the program creates a LevelOne object at the topmost level. The LevelOne contains fields like LevelTwoA and LevelTwoB. And a LevelTwoA object contains fields like LevelThree and so on. Then if the user wants to specify the value of a LevelTen field when creating the LevelOne, the value of LevelTen must be passed from the constructor of LevelOne to LevelNine.
And take a Car as an example, what if the user want to specify the Radius of a certian Gear when creating a Car? The Gear object must be at the bottom level of the whole hierarchy. However, a Car should not take a double radiusOfACertianGear as an argument in its constructor, because it's too trivial.
Thanks for all comments and answers for my question. Dependency injection is exactly the solution. I have spend one afternoon learning how dependency injection works. A class should not produce other classes(dependencies) in there constructor, it should receive one from the argument instead.
And you also need one or more configuration files/classes to provide the values of all the parameters. Then create an injector/factory to create all needed objects/dependencies based on the configurations.
I would create a builder to construct the composing parts and fit them nicely together.
I know interface reference variable can refer to any object that implements its interface. But what is the practical use of using a reference variable? We can achieve the same by using an object, then why use a reference variable?
The question leaves lots of room for interpretation, but here's mine:
Every object variable is actually a reference variable in C#:
MyClass c = new MyClass();
IMyInterface i = new MyClassThatImplementsInterface();
object o = new object();
All the above are reference variables as they "point" to reference types. I suppose that by your question you mean: Why should I write
IMyInterface i = new MyClassThatImplementsInterface();
instead of
MyClassThatImplementsInterface i = new MyClassThatImplementsInterface();
or even
object i = new MyClassThatImplementsInterface();
Simple answer is: You can call all the methods and properties defined by IMyInterface in the first and second case, and you can not in the last case.
But why not use the second case? Well, this is mostly why people use interfaces at all. Sometimes you don't know the implementing class. Or it is defined internally in some library. All you need to know, however, is that when you call a method you get some object in return that conforms to the interface you know. So that's all you need (and sometimes that's also all you get).
For example:
I've recently created an application that can display modules defined in plugin DLLs, which are dynamically loaded by a launcher application. The launcher application adds buttons for each plugin and changes the UI when a plugin button is pressed.
The launcher application knows nothing about the plugins - apart from one interface that contains properties returning titles, icons, a UserControl for the UI, etc.
I don't have any classes I can work with. All there is is a factory class that returns an instance of an object that implements my interface. And that's all you need to have.
Lets say we have an interface IRenderPage, now rendering of page may vary from device to device, you can have a common reference pointing to diffrent implementations.
This is why we have interface, a contract to be fulfilled by implementing class, and the classes implementing this interface can participate in defined set of processes with there own implementation.
I've seen various discussions about this and I suppose it may be a bit opinion based, but what I'm trying to find out is if I know I will only use a class once (one instance), should I just make it static for convenience? Is that bad practice or will it create a problem?
For example. If I make a single player game, there will only be one player at all times. So do I make public static class Player{} or do I stick with public class Player{} Player player = new Player();
The idea is that this would save time by not needing to pass around references.
Note that there is a difference between using a class only once and using only one instance of a class (more on that below).
Static classes are usually classes whose purpose is to expose a set of functionalities and/or constants which are independent of each other and do not need to maintain state information. If this is what your class does then you can declare it as a static.
In your example, I do not think that this is the way to go. A Player object might have different states and other properties, such as location, health etc. The moment you try to have 2 players in the game then your design breaks.
Using only one instance of a class is usually achieved through the Singleton design pattern. The aim of this pattern is to provide you with the same instance of a given object, regardless of how many times you actually make use of said object.
It is bad practice. You don't know how your game will scale, so in some time you will decide to make abstractions behind your class and it will turn refactoring of code into hellpit.
If you, for example, decided what your Player is inherited from class Human or from some abstract class VisibleObject you will be stuck with dilemma.
So, when to use static? Primarly on methods, Extensions classes, some very simple fields and that's all.
static class is basically same as other class but the difference is that you cannot instantiated.
In above example, it does not matter you use static class or not.
Is there any way to access the containing/enclosing class during initialization (constructor logic) of the nested owned class without needing a reference passed as a constructor parameter?
The reason I don't want to pass a reference to the containing class as a constructor parameter to the nested owned class is because virtually every single object in my program would need it, and it just feels sloppy passing in an argument manually every time that would never change anyways. I want to simplify the programming as much as possible as other team members of mine will be using my engine.
I tried making a method for the container class to use when adding new objects that would take the new instance as a parameter and then set that instance's "container" variable to "this" (the container class), but the nested owned object's initialization code happens first which defeats the purpose (I want to be able to access the container during initialization, so the container variable needs to be set before, not after the constructor code is executed).
Any ways to make this happen? Or am I doomed to manually pass in a reference to the container class every time I make a new nested owned object?
EDIT:
Example:
Let's say I'm making a video game, and the player is going to cast a magic spell that spawns a HealerGoblin:
From Player class:
spawnMonster(new HealerGoblin(30)); //30 = Monster's Combat Level
In HealerGoblin class:
public HealerGoblin(int Level)
{
Owner.Health += Level; //Owner in this case, being the player.
}
As you could probably see, the player would cast the spawn monster spell, select a level 30 healer goblin, and the healer goblin has a special effect when he spawns that increases his owner's health by some amount (in this case equal to the goblin's level). (Keep in mind this is a hypothetical, I know there are other, probably better, ways to do something like this specifically, but this is just an example of what I'm trying to do).
So the problem is, any player or NPC in the game could cast that spell and be the "owner". How would the goblin's Owner property be set by the time that initialization code that references the owner is executed?
I know I could pass the owner by reference:
spawnMonster(new HealerGoblin(this, 30); //First argument being what Owner is set to.
But I want every single object in my program to automatically have a reference to their "owners", and manually putting (this) every time I initialize a new object, and having to set up a new owner parameter to be passed every time I make a new derived class, just seems sloppy and counter-intuitive considering you would never not pass the reference.
So my question is what other ways would there be to do get a reference to the container/owner object before initialization besides passing it by reference through the constructor? If any?
I understand your pain. I've been there too. But the answer is no in a standard way of programming. It maybe possible by using the call stack, reflection and some hack work, but since you are trying to simplify your code, you don't want to have that kind of stuff in your code.
As far as I know. In short there is no such feature.
I'm thinking of creating a class in XNA 3.1 that handles the drawing of shadows. I know there are lots of ways to do this but I'm wanting to do something like a List of all the objects that should have a shadow and pass that List to the shadow class so it iterates through each object and draws a shadow.
The reason I want to do it like this is cause I could easily control whether shadows exist or not with just a boolean.
A List for all types is probably unlikely, my backup is a List of type Object but I don't know how to cast the elements in the List which are of type Object back into their respective types so I can access their properties.
My second backup is make all the objects that will have shadows derive from a class called ShadowObject or something and make the List of that type. This is a really easy solution but the reason I'm not doing it yet is cause I don't like the idea of a dummy class just to make something work, but maybe I should start liking it.
My final backup would be to go into each class that will have shadows and have a boolean to see if shadows should be drawn and handle the drawing in the class itself, which I think shouldn't even be considered an option cause if I want to change the shadow mechanics I would have to change it in every class.
So I guess a List for all types is my official question for the public but I'm open to answers, suggestions, and criticism to my backup plans.
Edit: I'm aware of interfaces but my response to that is in the comments for xixonia's answer and after reading up a little more on interfaces I think having a ShadowCaster class would be more appropriate. It can handle all the shadow drawing because all shadows are drawn the same way, I don't need to define it for each object individually like an interface would require me to.
I believe you should use an interface, and make sure all of your "DrawShadow" methods match that interface. This way you can create a list of shadow casters that match the interface.
So long as an object implements that interface, you know you can tell it to draw a shadow. The actual drawing of the shadow will be left up to the object itself, provided the correct device to draw with.
For example:
class Program
{
public static void Main()
{
var shadowCasters = new List<ICastShadow>();
shadowCasters.Add(new Car());
shadowCasters.Add(new Plane());
var castShadows = true;
if (castShadows)
{
foreach (var caster in shadowCasters)
{
caster.DrawShadow(null);
}
}
Console.Read();
}
public class Car : ICastShadow
{
public void DrawShadow(object device)
{
Console.WriteLine("Car Shadow!");
}
}
public class Plane : ICastShadow
{
public void DrawShadow(object device)
{
Console.WriteLine("Plane Shadow!");
}
}
public interface IShadowCaster
{
void DrawShadow(object device);
}
}
When you need to test if your object is capable of casting shadows, you can use the "is" keyword...
if(myTrain is ICastShadow)
{
shadowCasters.Add(myTrain);
}
Hope this helps! :)
edit:
The reason you wouldn't want to use inheritance is if your game objects all draw shadows in different ways, and if some of your derived classes don't cast shadows. For instance:
You have a BrickBuilding and a GlassBuilding. Brick building should cast a shadow, and glass building should not. They both inherit from Building, which inherits from ShadowCaster. Even if all of your shadow-casting classes drew shadows the same way, you would still need to make ShadowCaster's methods virtual, so GlassBuilding could override them and do nothing when that method is called.
Using composition instead of inheritance (i.e: use an interface), you would be able to compose the shadow drawing method on only those classes that actually cast shadows, and you have one less class in your hierarchy (which makes maintainability a breeze).
So what happens when you use an interface and you start repeating the same logic over and over again because your shadow drawing classes all draw shadows the same way? Obviously this isn't the best idea. But if they're all drawing shadows the same way, you can use another class to draw shadows for them. Then comes the "ShadowCaster" class.
The shadow drawing implementation on each object would then call a method on this ShadowCaster to draw the shadow for it. This allows each object the option of drawing shadows in a different way, but also provides a way for each object to use the default shadow drawing implementation. It also provides a way to easily add and remove the ability to draw shadows for specific objects (simple don't let the objects implement the ICastShadow interface).
To take it one step further, you could treat shadow casting just like another drawing method, and create a generalized interface for drawing shadows / particles / reflections / tron-glow, etc, and created different "modules" that do these different things. Instead of having you class implement 'ICastShadows", have it implement "IDrawModules", and then give each class the correct modules at run time.
In other words, you can add a "CastShadow" module to BrickBuilding, and add a "Reflect" module to GlassBuilding, and have your code call "DrawModules" on both objects (from the IDrawModules interface).
Ok this is getting really really long, Hope this helps, and it's not too confusing.
I would suggest reading the first couple chapters of Head First Design Patterns. It's a java-based book, but the principles are the same for most languages.
Instead of a "dummy class" ShadowObject why don't you just create an interface IShadowObject that would expose all necessary methods and use:
List<IShadowObject>
i don't know much about game development but it looks like System.Generic.Collection.List is supported by the XNA framework. That would be your list of any type.
you can use "is" operator to check for type.
public bool check(object obj)
{
return obj is ShadowStuff;
// or obj.GetType() == ShadowStuff
}
to cast :
(ShawdowStuff) obj ;