I'm currently programming a library for simple games, mostly intended to be used by myself.
Now I've run into a problem. I have a class called "Game" which looks like this:
class Game
{
private List<Entity> entities;
private int counter;
public Game()
{
entities = new List<Entity>();
counter = 0;
}
public AddEntity(Entity entity_)
{
entities.Add(entity_);
// problem! how to inform entity_ that it was added?
counter++;
}
}
Entity is a class which each object that acts in the game must be derived from. Its contents don't really matter. What I am looking for is a way for Game to inform the newly added entity_ class about its owner (current Game instance) and its id (which is what "counter" is for). Now I have been thinking about using an interface which would have a method "OnAdd(Game owner_, int id_)" for that as that would definitely work, but I wanted to make sure there is no preferred way over that. So that is my question:
Is there a better solution for my problem than interfaces? The Entity instance does not know what Game instance it is being added to, and using methods for event-like purposes doesn't feel right in my eyes. I could be wrong if course.
If your Entity has a property of type Game, it's easy to solve this without even using events:
... code ...
entities.Add(entity_);
entity_.AddToGame(this);
... code ...
and then in the AddToGame method, you would do whatever you would do in your event handler, which now is not necessary.
Yes seems correct. But need to add a difference.
Interface - Once changes, you need to track down all implementation.
Abstract Class - Virtual functions can be declared so no need to keep track for the implementations
There are lots of solutions.
You could of course call a method after the .Add:
entity_.HasBeenAdded();
Another solution would be to "reverse the add". Something like:
Entity class:
public Entity
{
...
public void AddTo(IList<Entity> list)
{
if (list == null)
{
throw new ArgumentNullException();
}
list.Add(this);
// Do some logic here, as you now know your object
// has been added.
}
}
...
entity_.AddTo(entities);
Related
I am coding an application that I thought would be a good chance to use a base class. I have Player class which holds an instance for each player on my game, I also have a PlayerManager class that has a dictionary of all the connected players, although I'll leave the PlayerManager class out of this question as this is just about the Player and PlayerData class.
So, I thought instead of having something like this, please note before checking this code snippet that I have removed a lot of the code and just shown a minimal example.
class Player
{
public PlayerData;
}
class PlayerData
{
public string Username;
public string Motto;
public string NickName;
}
class SomeOtherClass
{
public void Test()
{
var player = GetPlayer();
Console.WriteLine("Hello, I am " + player.PlayerData.Username);
}
}
I thought why have a method when I can have a base class? So I thought great, lets use a base class, this is what I ended up with.
internal class Player : PlayerData, IDisposable
{
private readonly Socket _socket;
private bool _disposeCalled;
private bool _receivingData;
private bool _hasAuthenticated;
public Player(Socket socket)
{
_socket = socket;
}
public void OnAuthenticated(MySqlDataReader reader)
{
if (_hasAuthenticated)
{
return;
}
_hasAuthenticated = true;
AssignData(reader);
}
public void Dispose()
{
if (_disposeCalled)
{
return;
}
_disposeCalled = true;
if (_receivingData)
{
_receivingData = false;
try
{
if (_socket != null && _socket.Connected)
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
}
catch
{
// ignored
}
_socket?.Dispose();
}
if (_hasAuthenticated)
{
SaveData();
}
}
}
internal class PlayerData
{
public int Id;
public string Username;
public void AssignData(MySqlDataReader reader)
{
while (reader.Read())
{
Id = reader.GetInt32("id");
Username = reader.GetString("username");
}
}
public void SaveData()
{
using (var dbConnection = Program.Server.Database.Connection)
{
dbConnection.SetQuery("UPDATE `users` SET `username` = #username WHERE `id` = #id");
dbConnection.AppendParameter("id", Id);
dbConnection.AppendParameter("username", Username);
dbConnection.ExecuteNonQuery();
}
}
}
You'll probably see the base class has a constructor, that's because I was going to just pass the PlayerData's data with the Player's constructor, but I wont actually get the data untill the Player's class has been fully initialized, I don't know when that will be as its done via socket packets, I just assign the data when I notice its been authenticated.
The point of my question is, should I use a base class like this, or should I not use a base class due to the fact I'm not initializing the data via the constructor, or is it okay to assign it via another method later on? Do I really need a base class, am I not following the right official rules for what a base class is and used for? Basically I just want to know, with this call stack should I be using a base class or method? I'm unsure on the rules.
So, the rules are not rules so much as guidelines (that not everyone really agrees on).
THAT SAID, I don't really see any benefit of lumping these classes together, although that could be because of so much of the code being removed.
In general, a good rule of thumb is not to use inheritance unless you have a good reason--a significant amount of code reuse that couldn't be achieved through composition, for example. In most cases, your code will be easier to maintain if you design with an eye for reducing dependencies (coupling), and the dependency between a subclass and its superclass is very strong. This means keeping things separate.
One technique you could do to simplify calls to player data is to "promote the interface"--basically, add the methods/properties you want as a sort of facade on the Player class, and have that relay the code to its PlayerData object. This has a few benefits:
1. It hides dependencies on PlayerData, which means you are free to change implementation to consolidate or use a different type (for example, if you just wanted to put those values in a data structure in the Player class)
2. It allows you to handle the case where PlayerData is being requested, but hasn't been initialized yet. For example, you could return default values or throw a custom exception.
3. Player and PlayerData are free to vary independently. So, if you run across a valid reason to subclass one or both of them, you won't be constrained.
In summary, it doesn't look like you really gain much from using inheritance in this way, but it would cut off design choices down the road. Also, anytime you are using inheritance to describe a relationship that is not an "IS A" relationship (PlayerData Is A Player? nope)--that smells fishy.
Again, guidelines. Bottom line is you want to design a system that you want to maintain, and design decisions come with trade-offs (often between simplicity and flexibility). So, if you decide there is a good reason to keep this as a subclass, just document it and don't worry about the OO Police coming after you for breaking the rules ;)
I have a simple interface called IEvent and it just contains this one method:
void Execute();
I have several derived classes from this interface and one of them needs access to an object that the caller of the method owns. The object is used in this fashion:
using (MyObject object = new MyObject(this.MessageService)
{
foreach (IEvent myEvent in eventList)
{
myEvent.Execute(); // <--- I need to pass object without adding argument here if possible?
}
}
I would add the object as a field in the derived class that needs access to it, but by the time I get to this part of the code, the IEvent objects are already constructed and running on a background thread. Currently, the only way I can think of is to add a setter in the IEvent interface for this object, but then I am exposing a field that most derived classes won't care about and doesn't seem like a clean solution.
I would add it as an argument to Execute(), but the problem is that the object belongs to an assembly that the assembly that contains IEvent doesn't know about (and don't want it to know about) and again 99% of the events don't care about this object anyway. Is there a better way to accomplish what I am trying to do here?
"If a class that implements IEvent does not/can not implement all the methods specified by IEvent the same way as they are declared in IEvent, that class should not implement IEvent in the first place." - Sweeper
So there's probably something wrong with your design of the whole program. I think you better revise your design a little bit and change some relationships between the classes and interfaces.
If you don't want to do that, there is another (not recommended) way to solve this problem.
Suppose your method caller is of type MethodCaller. You just change the declaration of Execute in the interface to this:
void Execute(MethodCaller obj = null);
And all the classes that implement IEvent can ignore the parameter except the class you mentioned in your question.
I'm going to piggyback on Jon Skeet's amazing knowledge of C#, .NET, CLR, IL and everything that surrounds any of those topics. You can't get to the instance of the calling object and especially the local varaible in the calling method. You can get its type, you can get the calling method through StackTrace, for example (StackTrace.GetFrames()), but none of those are going to do you any good in this situation. What you're trying to accomplish would require some heavy dive into the debugging API. As far as walking the stack, here's a quick sample I created to try see if I can figure something out for you (I made assumptions in regards to how your program is structured... obviously it's not a one to one sample):
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SampleApp
{
class Program
{
static void Main(string[] args)
{
var eventList = new List<IEvent> { new SomeClass() };
using (MyObject obj = new MyObject(new MessageService()))
{
foreach (IEvent myEvent in eventList)
{
myEvent.Execute();
}
}
}
}
public interface IEvent
{
void Execute();
}
public class SomeClass : IEvent
{
public void Execute()
{
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
var callingMethod = stackFrames[1].GetMethod();
var callingType = callingMethod.DeclaringType;
}
}
public class MyObject : IDisposable
{
public MessageService Service { get; }
public MyObject(MessageService service)
{
Service = service;
}
public void Dispose()
{
Service.Stop();
}
}
public class MessageService
{
public void Start() { }
public void Stop() { }
}
}
I like your question, because it presents an interesting and an unusual situation, but I'm afraid that you won't be able to accomplish your task without going outside of conventional routines that C# has in its arsenal. You may be able to pull something off with unmanaged code, but that's a different topic altogether.
However, aside from it being an interesting question... look at what you're trying to do. You have MyObject, which obviously implements IDisposable and will call Dispose() at the end of that using statement, and you're trying to grab its reference from a different assembly. I don't think this is a good idea.
I suggest revisiting your design and make use of things such as an optional parameter. May not be the "perfect" solution for your situation, as you'll pass it to every Execute in that foreach loop, but it's better than jumping through a thousand fiery hoops of debug API's.
Like many other posts I've found on SO, I'm trying to get my head around delegates. Hopefully this example is not classed a duplicate because I am asking a specific question about a particular example.
public delegate void HelloFunctionDelegate(string message);
public class Delegate
{
static void Main()
{
HelloFunctionDelegate del = new HelloFunctionDelegate(GoodNight); // delegate will point to the GoodNight method
del("Hello"); // invoke the delegate
}
public static void GoodMorning(string strMessage)
{
Console.WriteLine(strMessage + " and good morning!");
Console.ReadKey();
}
public static void GoodNight(string strMessage)
{
Console.WriteLine(strMessage + " and good night!");
Console.ReadKey();
}
}
So in my example I understand that my delegate is a reference to any function that matches its signature and if I pass in GoodMorning I will see:
Hello and good morning!
and if I pass in GoodNight I will see: Hello and good night!
So its kind of like going through a middle man...
I don't understand is what's the point, why wouldn't I just directly call my GoodMorning / GoodNight methods as and when I need to use them?
Maybe there are better examples for when a delegate is useful, but in this example, why don't I just bypass the middle man?
Since you are asking concretely about this example and not in general: There is no point to doing that in this particular piece of code. It teaches you the mechanics of delegates but it does not teach you the point of using them.
In short, the point is that some piece of code can take a reference to a method without knowing what method it will actually receive. It can later call that delegate at will. That enables more abstractions than otherwise possible.
Consider you have the following delegate:
public delegate void CarEvent(Car car);
And then you have an implementation like the following:
public class Car : DataRecord
{
// An event to execute when the record is deleted
public CarEvent OnDelete { get; set; }
public void Delete()
{
this.DeleteRecord(); // Deletes this record from ex. the database
if (OnDelete)
{
OnDelete(this); // Executes the event
}
}
}
By using a delegate you can subscribe different methods to the OnDelete allowing you to do different things when the record is deleted.
Ex. you can make it so when the record is deleted it's deleted from a "ListView" that holds it.
public class CarList : ListView
{
public CarList()
: base()
{
foreach (var car in CarRecords.LoadCars())
{
var listViewItem = new ListViewItem(car);
car.OnDelete = this.DeleteCarFromList;
this.Items.Add(listViewItem);
}
}
private void DeleteCarFromList(Car deletedCar)
{
this.Items.Remove(deletedCar);
}
}
Of course the above is a rough example and there is a lot more things and different kind of situations where you can use delegates and most notably if you want to use them for events you should consider implementing them using the event keyword. - https://msdn.microsoft.com/en-us/library/awbftdfh.aspx
All in all you want to use delegates when the behavior may differ depending on the overall implementation of something. Like you might want to do one thing in one situation and something else in another situation, but they should both over-all do the same thing.
If you do not need different behaviors based on implementation then there's no need to use delegates. You'd always want to call a method directly if possible.
I hope this explained it okay.
I'm trying to create a mechanism that will allow the application to decide (in runtime) whether to execute some functionality.
"Some Functionality" can be anything, it can be c# code which is contained in several classes in several dlls, it can be UI, it can be database query execution, etc.
Most importantly, it should fit in the current existing infrastructure I have, which I cannot re-design and build from scratch.
The more I think of it, it seems like the only solution I can use would be to hold some table which will be the "functionality repository" and it will tell (by unique key) if a functionality is on / off.
Then in code, I will have to place in each spot which handles such functionality an if else statement.
E.g.
If(functionalityEnabled)?
DoFunctionality()
Else
DoTheUsusal()
Is there a better way or a better design to implement it? I would like to keep the solution as simple as possible, but on the other hand, this solution is really ugly and will eventually make my code looks like spaghetti code.
Your thoughts will be appreciated,
I'm using c# with sql server, web api for web services.
Edit:
I want to say that I appreciate the time and effort of everyone answering my question, there were some really interesting ideas that you brought up.
I eventually marked #dasblinkenlight answer since it suited by need the best, though other answers here are really good and may be useful to others.
Thank you.
If you have two classes that implement the same interface, your application can call the functionality (methods, properties) of the class without knowing exactly if it is calling the basic functionality or the alternative functionality:
IFunctionalityX {
DoIt();
}
class BasicFunctionalityX: IFunctionalityX {
public DoIt() {
// Default behaviour goes here
}
}
class PluginFunctionalityX: IFunctionalityX {
public DoIt() {
// Alternative functionality.
}
}
If PluginFunctionalityX shares parts of its implementation with BasicFunctionalityX, you may inherit it from the other, but whether you do or not doesn't really matter. As long as you use the interface, that is what counts, and you can use this method regardless of whether the classes are related or not.
In the initialization of your program, you can make the decision once and create an instance of the right class. You may store this class in some container that holds all your functionalities. FunctionalityX is a property of interface IFunctionalityX, and you can make other interfaces (and properties) for other functionalities.
if (functionalityXEnabled) {
FunctionalityContainer.FunctionalityX = new PluginFunctionality();
} else {
FunctionalityContainer.FunctionalityX = new BasicFunctionality();
}
Then, in the rest of your application, you can call your functionality through:
FunctionalityContainer.FunctionalityX.DoIt();
Instead of implementing this from scratch you may use a dependancy injection library, like Unity. This also allows you to more easily get an instance of the right functionality at the time you need it without having to create them all at the start of your program, and without writing elaborate constructor code for all fucntionalities.
You want to dispatch your code differently at runtime dependent on a configuration setting. Conditionals and polymorphism are two ways of doing so.
Conditionals
At runtime, check for values using if, switch or other lookup methods. You're already doing these.
if (configFile.cloudAccount == null) {
saveFileToDisk();
} else saveFileToCloud();
Advantages
They're conditionals, you really can't avoid having to do one at some point in any nontrivial development project
Disadvantages
Doing them at every point in your application would be painful, though. So they're best combined with other strategies to minimise their use
Polymorphism
When loading your application, read through the configuration file and construct your application's components accordingly:
interface IFileSaver { /* Used to save files in your application */ }
class DiskSaver : IFileSaver { /* The default file saving class */ }
class CloudSaver : IFileSaver { /* If they've configured a cloud account */ }
// EXAMPLE USE
int Main (...) {
// Setup your application, load a config file.
// You'll need to check the config with a conditional
// here (uh oh) but other components of your application
// will just use the IFileSaver interface
if (configFile.cloudAccount != null) {
YourApplication.FileSaver = new CloudSaver(configFile.cloudAccount);
} else {
YourApplication.FileSaver = new DiskSaver();
}
}
// Somewhere else in your application
void SaveCurrentDocument() {
// No if's needed, it was front loaded when initialising
// the application
YourApplication.FileSaver.Save();
}
Advantages
Fits in nicely with object-oriented design
All your configuration checks are front loaded. After loading in the correct classes the rest of your program will use them, oblivious to their actual implementation. Because of that, you don't need to do if checks throughout your code.
Compiler will be able to statically check type errors in your approach
Disadvantages
Only as flexible as your class's interface. Maybe you want some extra steps and checks to occur with a CloudSaver, they'd better fit into the pre-existing interface; otherwise, they won't happen.
Long story short - conditionals let you explicitly perform the checks whenever they're needed so, in principle, you get a lot of procedural flexibility. For example, maybe the SaveAs routine needs to save files slightly differently than the Save routine. However, as you've identified, this leads to long repetitive code. In those cases, structuring your code to use polymorphism might help out.
Either way, you will almost certainly need to have some amount of conditional checks wherever there is flexibility in your application.
Note: There are many other ways of achieving runtime config checks, I'm just pointing out the most common (and usually straightforward)
A once-popular quip among OO programmers has been that every conditional in the code indicate a missed opportunity to subclass. Although this rule is far from being universal, and it falls short when it comes to composition, there is a grain of truth to it, especially when you see the same condition popping up in multiple ifs across different methods of the same class.
A common way of dealing with ifs like that is using some combination of inheritance and composition, and moving the decision to a single place where your object is being created.
The inheritance way looks like this:
interface Doer {
void doSomething();
}
class BasicDoer implements Doer {
public void doSomething() {
...
}
}
class EnhancedDoer extends BasicDoer {
public void doSomething() {
base.doSomething();
...
}
}
// At construction time:
Doer doer;
if (someCondition)
doer = new BasicDoer();
else
doer = new EnhancedDoer();
The composition way looks like this:
interface Doer {
void doSomething();
}
// Create several implementations of Activity, then...
// At construction time:
List<Doer> doers = new ArrayList<>();
if (someCondition1)
doers.add(new SomeKindOfDoer());
if (someCondition2)
doers.add(new AnotherKindOfDoer());
if (someCondition3)
doers.add(new YetAnotherKindOfDoer());
Now instead of an if you do this:
for (Doer d : doers) {
d.doSomething();
}
If it's just a single condition then you have no choice but to use if else and is perfect for single conditions.
If you have more then 1 condition, you may think of using Switch statement.
As far as you are worried about your code going to look complicated with if else statement, put your code within functions,
if(condition)
{
DoThis();
}
else
{
DoSomethingElse();
}
Maybe something similar to strategy design pattern (incapsulation of behaviour) will make it more managable if functionality doesn't require lots of interaction with object data (though interaction is possible). Pros: readable extendable code, cons: lots of code.
namespace SomethingLikeStrategy
{
public interface Behaviour {
void doThis();
void changeM(ref int m);
void doThat();
}
public class BehaviourOriginal : Behaviour {
public void doThis() {
Console.WriteLine("foo");
}
public void changeM(ref int m) {
m = 20;
}
public void doThat() {
throw new Exception("not implemented");
}
}
public class BehaviourSpecial : Behaviour {
public void doThis() {
Console.WriteLine("bar");
}
public void changeM(ref int m) {
m = 10;
}
public void doThat() {
throw new Exception("not implemented");
}
}
public class MyClass {
Behaviour mBehaviour;
int mM = 0;
public MyClass() {
mBehaviour = new BehaviourOriginal();
}
public void setSpecialBehaviour(bool special) {
if (special) {
mBehaviour = new BehaviourSpecial();
} else {
mBehaviour = new BehaviourOriginal();
}
}
public void doThis() {
mBehaviour.doThis();
}
public void doThat() {
mBehaviour.doThat();
}
public void changeM() {
mBehaviour.changeM(ref mM);
}
public void printM() {
Console.WriteLine(mM);
}
}
class Program
{
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.doThis();
myClass.setSpecialBehaviour(true);
myClass.doThis();
myClass.setSpecialBehaviour(false);
myClass.printM();
myClass.changeM();
myClass.printM();
myClass.setSpecialBehaviour(true);
myClass.changeM();
myClass.printM();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
Here is the conundrum. I have a specific set of state variables that are used in almost every supporting object I have, and I want those variables to be able to be read by any object that needs to read them, but I want to protect them so that only 1 object has the ability to set them.
For example, lets say I am making a poker game. Variables like:
- Minimum Ante
- Maximum Bet
- Maximum Number of Players
- Current GameState (Placing Bets, Shuffling, Dealing, Paying, etc.)
Personally, I prefer small compact component classes, so lets say I have the majority of the poker game logic in 1 controller class, but i have 50 supporting objects that handle everything that isn't the poker game logic itself, such as a PlayerInterface, a graphics controller, 'The Deck' to handle shuffle and deal logic, etc. Alot of my smaller support classes need to see what the minimum ante is, and the current method I am using is for the controller class to pass these variables into the supporting classes as parameters.
The obvious downside to this is I have 50 supporting objects all holding on to their own local variables for minimum ante to hold the same information that I am passing to them from the controller. Wasted parameters, memory, and opens a ton of risk if any of those variables ever get out of sync.
So, how to I make these variables global so everyone can access and read them? The knee jerk reactionary answer is some public static variables, however this presents the problem that anyone could also write to them. Not only do I not want my supporting objects having the power to change the minimum ante without the controller's knowledge, but I also don't want the client shell that holds the poker game to be able to change them without first going through the proper checks contained in the controller.
So what do I do? Someone once mentioned to me the idea of a Singleton, but after plenty of research, most of it a few years old or more, I found about a 50/50 split in the community who say Singletons are a good idea vs those who think they aren't.
If not singletons or statics, then what? I am open to any ideas to research and try out.
Remember, I want any object, anytime, anywhere to be able to GET the data it needs, but only a very specific object to have the ability to SET the data, should it need to change, so that it can filter through the proper checks. By proper checks, I mean for example in the poker game, if a player has the ability to change the Minimum Bet on the table, he should only be able to do so between hands, or before a tournament begins. I don't want him messing with these things during play.
Thanks in advance for any input.
You could use interfaces approach here.
Declare two interfaces as
public interface IReadOnlyAccess
{
int Property{get;}
}
public interface IFullAccess
{
int Property{get;set;}
}
Then your class would implement both interfaces like
public interface MyClass: IReadOnlyAccess, IFullAccess
{
public int Property{get;set;}
}
Then wherever you need full access you get it via IFullAccess, if otherwise - via IReadOnlyAccess.
Make an inner class, it will have access to the main classes private vars:
public class OuterClass
{
public string StringProperty { get; private set; }
public InnerClass CreateInnerClass()
{
InnerClass ic = new InnerClass(this);
return ic;
}
public class InnerClass
{
private OuterClass _outer;
public InnerClass(OuterClass oc)
{
_outer = oc;
}
public string Prop
{
get
{
return _outer.StringProperty ;
}
set
{
_outer.StringProperty = value;
}
}
}
}
So create the main class that most people have readonly access:
var oc = new OuterClass();
oc.StringProperty = "123"; <-- not allowed, is `readonly`
To write to properties, create inner class instance:
var oc = new OuterClass();
var ic = oc.CreateInnerClass();
ic.StringProperty = "123";
Seems like the cleanest, easiest solution is to have everything done in your controller class.
Let's say something like this:
AS3:
//adding the final keyword, locks this class so others can't extent/inherit from it
public final class MyController {
//create a privately scoped var (it can only be accessed in this class)
private var minBet:Number = 0;
//create a public getter that can be read by any class/object
public function get minimumBet():Number {
return minBet;
}
private function set minimumBet(value:Number):void {
//do you checks etc
minBet = value;
}
}
C#
//sealed in C# is the same as final in AS3
public sealed class MyController
{
private float minBet = 0;
public float minimumBet
{
get { return minBet; }
}
}
instanceOfMyController.minBet //will throw an error
instanceOfMyController.minimumBet = 10; //will throw an error
instanceOfMyController.minimumBet //will supply the value of the minBet var
If you're doing a lot cross-language code, consider checking out something like Haxe which can compile out to AS3 or C# with the same code.