So I'm having trouble with figuring out a way to implement spells in my game. The problem is that I want to add many spells that are different(like teleportation, telekinesis, fire control etc.). The first thing I tried was making a big class hierarchy like :
Spell -> Passive ->Speed
->Flying
-> Active ->Teleportation
Telekinesis
At the start it seemed good but when I started implementing a lot of spells it started to get messy.
I've searched for other solution and I found about the Entity-Component based system. But I don't think it'll be a good solution.
So do any of you know of any other approach to this problem?
What if you used something like the Strategy Design Pattern and you where to have an interface which defines an method such as ApplySpell() and maybe a Name property and the concrete spell implemented said interface?
That way, for each character, you could iterate over their assigned spells and use the Name property to get the name (maybe you want to list them through a UI or something like that), or maybe store them in a dictionary where the name of the spell is the key, and the actual spell implementation is the value.
What you could do then is that once that the user has selected the spell, all that you need to do is to call ApplySpell() and what the actual spell does is delegated to the class which represents the spell.
In this way, you would not need to worry which spell you need to invoke because everything is being done behind the scenes.
Inheritance is ok, but for properties you can use interfaces or base classes as properties:
class SpellBase
{
public string Name { get; protected set; } // all spells have to have name
public virtual void Animate() { ... } // abstract?
...
}
Then for teleportation
class TeleportationSpell: SpellBase, IEffect
{
... // set name, override Animate() and implement IAreaEffect (as OnSelfEffect() for teleport)
}
interface IEffect
{
public EffectBase Effect {get; set;}
...
}
class EffectBase { ... }
class OnSelfEffect: EffectBase { ... }
class OnTargetEffect: EffectBase { ... }
class OnSelfAndTargetEffect: EffectBase { ... }
Interfaces will make your hierarchy less branchy, but will required more code to implement (which is not really a problem, as you can move common code into methods and call them).
The Entity-Component approch is a good solution for your problem. :)
You should invest more time in understanding it.
You always have to make a decision between "is a" or "have a" relationship.
Where "is a" means inheritance and "have a" means composition.
The thing on EntityComponents is to put every game object attribute into a component class and then just put these components together. You could create every combination of properties without or less code changes (depending on the implementation).
With using that approch it's also easy to create a multiplayer game, because you have just a few places in your code to put the communication stuff.
The other side is you will have a lot of classes and everything is highly decoupled. In general that's a plus and what we want as OO developers.
But for a new developer or a developer with not that high skills, this could be horrible to read.
So i would advise you to choose the entity component approach, because your game will be easier to extend in the future.
Instead of creating multiple classes for each type of magic, just start casing them all in one Magic class and handle them from there as per a trigger?
switch(castID) {
default:
break;
case 1: //air strike
Spell AirStrike = new Spell('AirStrike');
break;
case 2:
...
}
And then have a class for Spell and handle each spell in there based on params sent
Related
I've been experimenting with the decorator pattern to extend functionality of code you do not want to touch for example and I see how to implement it however I am now unsure why you don't just inherit from the original class and extend that way.
I have read that the decorator pattern allows you to add functionality at runtime whereas inheritance means its there at compile time.
I don't understand this.
Could someone explain this, provide examples and explain when its better to use decorator vs inheritance.
Thanks
Suppose you create a View class that displays your items in a certain way.
Now you decide you also want a version of it which is scrollable, so you create a ScrollableView which inherits the View.
Later you decide you also want a version with a border so you now need to make a BorderedView and a BorderdScrollableView.
If on the other hand you could make a decorator for each added styling. You would have the following classes:
View
ScrollableDecorator
BorderedDecorator
When you want a bordered scroll view you do:
new BorderedDecorator(new ScrollableDecorator(new View())).
So you can configure any combination of this with just the 3 classes. And you can add or remove them at runtime (suppose you click a button that says add border, you now wrap your view with a BorderDecorator ... while whith inheritance you need to implemented this view class if you haven't already, or you need to create a new view instance and copy all relevant data from the first view to the second view which is not as easy to do as just adding or removing wrappers).
Imagine a game like Civilization, where each square on the map can have a variety of resources attached to it (like, say, various ores, or wood, or oil, etc.).
If you used straight inheritance, you'd need to create a class for each kind of square. It'd be unwieldy to have
public class OilSquare {}
public class OilAndGoldSquare {}
public class GoldAndSilverSquare {}
// etc.
The Decorator Pattern allows one to mix and match without needing to create a rigid hierarchy. So, you'd have instead:
public class Square {}
public class GoldDec {}
public class SilverDec {}
public class OilDec {}
// ...
var crazyMix = new GoldDec(new SilverDec(new OilDec(new Square())));
Put another way, Decorators allow for the creation of pipeline behavior, with each step in the pipeline being swappable with another step.
As others have already said Decorators are good for adding "options" to things... The benefits come in the way you can chain methods etc. through the decorators.
Imagine I buy a car with options for leather interior, metallic paint and awesome spoiler...
There are 8 different combinations of the three options but with decorators you only need three extra classes.
The interesting thing though is the way the decorator pattern works. As a brief example:
public class MetallicPaint : Car
{
private Car car;
public MetallicPaint(Car wrappedCar)
{
car = wrappedCar;
}
public decimal Cost()
{
return car.Cost() + 500;
}
public string Description()
{
return car.Description() + ", Metallic Paint";
}
public string Speed()
{
return car.Speed();
}
[... {pass through other methods and properties to the car object}]
}
This isn't a complete example but highlights how the decorator can interact with the object it is decorating. And of course because it implements car it can be used just like a car in every other way (and passes through anything the decorator doesn't effect to the inner car object).
Of course if you had multiple of these decorators with a car nested inside each would in turn add their cost, their part of the description and maybe the spoiler would alter the speed whereas the others didn't...
In essence it allows you to modify an object in a much more modular and less fundamental way than inheritance would. Decorators should always be used as if they were the base object (in this case Car) so they should never expose any new methods or properties, just slightly change the effect of existing ones.
Decorator pattern is better than inheritance if you have many features to be added and you also require to have combination of these features. Suppose your base class is A, and you want to extend(decorate) this base class with feature f1,f2,f3,f4 and some combination of them like (f1,f2) and (f1,f3) and .. ; so you would require to create 4!=4*3*2*1=24 class in your hierarchy (4 for each feature and the rest for their combination). While, Using decorative pattern, you would only need to create 4 classes!
for #Seyed Morteza Mousavi in #Razvi post:
You are right, we can add two properties Scrollable and Bordered to View class, then check if the property is set to true so run the desired behaviour. But this requires that we already be aware of the number of the feature we require(which is not the case in decorator pattern). otherwise, with every new feature (say f1) we want to add to our class, we need to alter our main class, or inherit the main class (you would say) and add the property. Taking latter approach, you would further need to alter the part of the code which handles feature combination (this is not good, since it is not obeying the rule of thumb of "loose coupling!")
hope this helps.
I have looked on line for information that would help me solve a design issue that is confusing me. I am new to complicated inheritance situations so my solution could actually just be rooted in a better design. But in trying to figure out what my design should be, I keep ending up thinking I really just need to inherit more than 1 base class.
My specific case involves Assets and different types of Assets.
Starting with the Asset...
Every PhysicalDevice is an Asset
Every VirtualDevice is an Asset
Every Server is an Asset
Every PhysicalServer would need to be both a PhysicalDevice and a Server
Every VirtualServer would need to be both a VirtualDevice and a Server
Every NetDevice is a PhysicalDevice
Every StorageArray is a PhysicalDevice
One solution I guess is to duplicate the Server code for both PhysicalServers, and VirtualServers however, I feel like this goes against what im trying to do, which is inherit.
They need to be separate classes because each of the types will have properties and methods. For instance, Server will have OSCaption, Memory, Procs, etc. PhysicalDevice will have things like Location, Serial, Vendor etc. And VirtualDevice will have a ParentDevice, State, VHDLocation etc.
If the inheritance is liner then i run into the problem of not being able to describe these types accurately.
Something that seems intriguing is Interfaces. It seems that i can define all base classes as interfaces and implement them in my main classes as needed. but, I am simply unsure of what the implications are if I were to do that.
for instance, something like... PhysicalServer : IAsset : IServer : IPhysical
I am in deep water so I’m really just looking for suggestions or guidance.
Interfaces are an appropriate way of ensuring contract integrity across types, but you may end up with duplicate code for each implementation.
Your scenario may lend itself better to composition than inheritance (or a combination thereof).
Example - Inheritance + Composition
public class PhysicalServer : Asset
{
public PhysicalInfo PhysicalProperties
{
get;
set;
}
}
public class VirtualServer : Asset
{
public VirtualInfo VirtualProperties
{
get;
set;
}
}
Example - Composition Only
public class VirtualServer
{
public VirtualInfo VirtualProperties
{
get;
set;
}
public AssetInfo AssetProperties
{
get;
set;
}
}
You could then add polymorphism/generics into the mix and create derivatives of types to represent more specific needs.
Example - Inheritance + Composition + Genericized Member that inherits from a common type
public class VirtualServer<TVirtualInfo> : Asset
where TVirtualInfo : VirtualDeviceInfo
{
public TVirtualInfo VirtualProperties
{
get;
set;
}
}
public class VirtualServerInfo : VirtualDeviceInfo
{
// properties which are specific to virtual servers, not just devices
}
There are countless ways that you could model this out, but armed with interfaces, composition, inheritance, and generics you can come up with an effective data model.
Use mixins.
You first decide which is the primary thing you want your object to be. In your case I think it should be server.
public class PhysicalServer : Server
Then you add interfaces for the other functionalities.
public class PhysicalServer : Server,IAsset,IVirtualDevice
And you add extension methods to the interfaces.
public static int WordCount(this IAsset asset)
{
//do something on the asset
}
Here's an article on mixins in case my answer is too simple: http://www.zorched.net/2008/01/03/implementing-mixins-with-c-extension-methods/
C# doesn't support multiple inheritance from classes (but does support multiple implementations of interfaces).
What you're asking for is not multiple inheritance. Multiple inheritance is where a single class has more than one base class. In your example each class inherits from one/zero other classes. Asset and Server being the ultimate base classes. So you have no problem doing that in c#, you can just define the functionality common in eg server and then do different things in VirtualDevice and PhysicalDevice.
However you will end up with a possibly complex class hierarchy and many people would advocate composition over inheritance. This is where you'd have interfaces defining behaviour and classes implement the interface to say that they do something but each class can implement the interface methods differently. So your example for the PhysicalServer interfaces may be encouraged.
To start with remember that inheritance is the obvious result of the kind of problem that you have mentioned. Every class does have more than one behavior and everyone falls into this trap. So chill. You are not the first nor the last.
You need to modify your thinking a bit to break away from the norm.
You need to look at it from the angle of what "changes" in future rather than look at a hierarchical kind of class diagram. A class diagram may not be hierarchical instead it needs to represent "what changes" and what "remains constant". From what I see, in future you may define a MobileDevice, VirtualMobileDevice.
In your current classes you seem to have properties like Vendor, Serial. These may be needed in MobileDevice too right ? So you need to modify your thinking to actually think of behaviors instead of classes that make hierarchical sense.
Rethink, you are going down the track of multiple inheritance, very dangerous and complex design. Its not the correctness of your thought process that is in question here. Its the question of you coding something and someone up ahead in the near future complicating it beyond repair.
No multiple inheritance in java is there for this one reason, to ensure that you dont think the hierarchical way.
Think "factories" (for creation), strategy (for common functionality/processing).
Edited :
Infact you should also consider creating layers in the form of library, so that there is complete abstraction and control on the main parts of your processing. What ever you intend to do with the Asset/Device class should be abstracted into a library, which can be protected by change.
I'm trying to explain to my team why this is bad practice, and am looking for an anti-pattern reference to help in my explanation. This is a very large enterprise app, so here's a simple example to illustrate what was implemented:
public void ControlStuff()
{
var listOfThings = LoadThings();
var listOfThingsThatSupportX = new string[] {"ThingA","ThingB", "ThingC"};
foreach (var thing in listOfThings)
{
if(listOfThingsThatSupportX.Contains(thing.Name))
{
DoSomething();
}
}
}
I'm suggesting that we add a property to the 'Things' base class to tell us if it supports X, since the Thing subclass will need to implement the functionality in question. Something like this:
public void ControlStuff()
{
var listOfThings = LoadThings();
foreach (var thing in listOfThings)
{
if (thing.SupportsX)
{
DoSomething();
}
}
}
class ThingBase
{
public virtual bool SupportsX { get { return false; } }
}
class ThingA : ThingBase
{
public override bool SupportsX { get { return true; } }
}
class ThingB : ThingBase
{
}
So, it's pretty obvious why the first approach is bad practice, but what's this called? Also, is there a pattern better suited to this problem than the one I'm suggesting?
Normally a better approach (IMHO) would be to use interfaces instead of inheritance
then it is just a matter of checking whether the object has implemented the interface or not.
I think the anti-pattern name is hard-coding :)
Whether there should be a ThingBase.supportsX depends at least somewhat on what X is. In rare cases that knowledge might be in ControlStuff() only.
More usually though, X might be one of set of things in which case ThingBase might need to expose its capabilities using ThingBase.supports(ThingBaseProperty) or some such.
IMO the fundamental design principle at play here is encapsulation. In your proposed solution you have encapsulated the logic inside of the Thing class, where as in the original code the logic leaks out into the callers.
It also violates the Open-Closed principle, since if you want to add new subclasses that support X you now need to go and modify anywhere that contains that hard-coded list. With your solution you just add the new class, override the method and you're done.
Don't know about a name (doubt such exists) but think of each "Thing" as a car - some cars have Cruise Control system and others do not have.
Now you have fleet of cars you manage and want to know which have cruise control.
Using the first approach is like finding list of all car models which have cruise control, then go car by car and search for each in that list - if there it means the car has cruise control, otherwise it doesn't have. Cumbersome, right?
Using the second approach means that each car that has cruise control come with a sticker saying "I has cruise control" and you just have to look for that sticker, without relying on external source to bring you information.
Not very technical explanation, but simple and to the point.
There is a perfectly reasonable situation where this coding practice makes sense. It might not be an issue of which things actually support X (where of course an interface on each thing would be better), but rather which things that support X are ones that you want to enable. The label for what you see is then simply configuration, presently hard-coded, and the improvement on this is to move it eventually to a configuration file or otherwise. Before you persuade your team to change it I would check this is not the intention of the code you have paraphrased.
The Writing Too Much Code Anti-Pattern. It makes it harder to read and understand.
As has been pointed out already it would be better to use an interface.
Basically the programmers are not taking advantage of Object-Oriented Principles and instead doing things using procedural code. Every time we reach for the 'if' statement we should ask ourselves if we shouldn't be using an OO concept instead of writing more procedural code.
It is just a bad code, it does not have a name for it (it doesn't even have an OO design). But the argument could be that the first code does not fallow Open Close Principle. What happens when list of supported things change? You have to rewrite the method you're using.
But the same thing happens when you use the second code snippet. Lets say the supporting rule changes, you'd have to go to the each of the methods and rewrite them. I'd suggest you to have an abstract Support Class and pass different support rules when they change.
I don't think it has a name but maybe check the master list at http://en.wikipedia.org/wiki/Anti-pattern knows? http://en.wikipedia.org/wiki/Hard_code probably looks the closer.
I think that your example probably doesn't have a name - whereas your proposed solution does it is called Composite.
http://www.dofactory.com/Patterns/PatternComposite.aspx
Since you don't show what the code really is for it's hard to give you a robust sulotion. Here is one that doesn't use any if clauses at all.
// invoked to map different kinds of items to different features
public void BootStrap
{
featureService.Register(typeof(MyItem), new CustomFeature());
}
// your code without any ifs.
public void ControlStuff()
{
var listOfThings = LoadThings();
foreach (var thing in listOfThings)
{
thing.InvokeFeatures();
}
}
// your object
interface IItem
{
public ICollection<IFeature> Features {get;set;}
public void InvokeFeatues()
{
foreach (var feature in Features)
feature.Invoke(this);
}
}
// a feature that can be invoked on an item
interface IFeature
{
void Invoke(IItem container);
}
// the "glue"
public class FeatureService
{
void Register(Type itemType, IFeature feature)
{
_features.Add(itemType, feature);
}
void ApplyFeatures<T>(T item) where T : IItem
{
item.Features = _features.FindFor(typof(T));
}
}
I would call it a Failure to Encapsulate. It's a made up term, but it is real and seen quite often
A lot of people forget that encasulation is not just the hiding of data withing an object, it is also the hiding of behavior within that object, or more specifically, the hiding of how the behavior of an object is implemented.
By having an external DoSomething(), which is required for the correct program operation, you create a lot of issues. You cannot reasonably use inheritence in your list of things. If you change the signature of the "thing", in this case the string, the behavior doesn't follow. You need to modify this external class to add it's behaviour (invoking DoSomething() back to the derived thing.
I would offer the "improved" solution, which is to have a list of Thing objects, with a method that implements DoSomething(), which acts as a NOOP for the things that do nothing. This localizes the behavior of the thing within itself, and the maintenance of a special matching list becomes unnecessary.
If it were one string, I might call it a "magic string". In this case, I would consider "magic string array".
I don't know if there is a 'pattern' for writing code that is not maintainable or reusable. Why can't you just give them the reason?
In order to me the best is to explain that in term of computational complexity. Draw two chart showing the number of operation required in term of count(listOfThingsThatSupportX ) and count(listOfThings ) and compare with the solution you propose.
Instead of using interfaces, you could use attributes. They would probably describe that the object should be 'tagged' as this sort of object, even if tagging it as such doesn't introduce any additional functionality. I.e. an object being described as 'Thing A' doesn't mean that all 'Thing A's have a specific interface, it's just important that they are a 'Thing A'. That seems like the job of attributes more than interfaces.
I've been learning C# over the summer and now feel like making a small project out of what I've done so far. I've decided on a sort of text based adventure game.
The basic structure of the game will involve having a number of sectors(or rooms). Upon entry into a room, a description will be outputted and a number of actions and such you may take; the ability to examine, pick up, use stuff in that room; possibly a battle system, etc etc. A sector may be connected up to 4 other sectors.
Anyway, scribbling ideas on paper on how to design the code for this, I'm scratching my head over the structure of part of my code.
I've decided on a player class, and a 'level' class that represents a level/dungeon/area. This level class would consist of a number of interconnected 'sectors'. At any given time, the player would be present in one certain sector in the level.
So here's the confusion:
Logically, one would expect a method such as player.Move(Dir d)
Such a method should change the 'current sector' field in the level object. This means class Player would need to know about class Level. Hmmm.
And Level may have to manipulate the Player object (eg. player enters room, ambushed by something, loses something from inventory.) So now Level also needs to hold a reference to the Player object?
This doesn't feel nice; everything having to hold a reference to everything else.
At this point I remembered reading about delegates from the book I'm using. Though I know about function pointers from C++, the chapter on delegates was presented with examples with a sort of 'event based' programming viewpoint, with which I did not have much enlightenment about.
That gave me the idea to design the classes as follows:
Player:
class Player
{
//...
public delegate void Movement(Dir d); //enum Dir{NORTH, SOUTH, ...}
public event Movement PlayerMoved;
public void Move(Dir d)
{
PlayerMoved(d);
//Other code...
}
}
Level:
class Level
{
private Sector currSector;
private Player p;
//etc etc...
private void OnMove(Dir d)
{
switch (d)
{
case Dir.NORTH:
//change currSector
//other code
break;
//other cases
}
}
public Level(Player p)
{
p.PlayerMoved += OnMove;
currSector = START_SECTOR;
//other code
}
//etc...
}
Is this an alright way to do this?
If the delegate chapter was not presented the way it was, I would not have thought of using such 'events'. So what would be a good way to implement this without using callbacks?
I have a habit of making highly detailed posts... sorry v__v
What about a 'Game' class which would hold the majority of the information like a Player and a current room. For an operation such as moving the player, the Game class could move the player to a different room based on the room's level map.
The game class would manage all the interactions between the various components of the games.
Using events for something like this brings the danger that your events will get tangled. If you're not careful you'll end up with events firing each other off and overflowing your stack, which will lead to flags to turn events off under special circumstances, and a less understandable program.
UDPATE:
To make the code more manageable, you could model some of the interactions between the main classes as classes themselves, such as a Fight class. Use interfaces to enable your main classes to perform certain interactions. (Note that I have taken the liberty of inventing a few things you may not want in your game).
For example:
// Supports existance in a room.
interface IExistInRoom { Room GetCurrentRoom(); }
// Supports moving from one room to another.
interface IMoveable : IExistInRoom { void SetCurrentRoom(Room room); }
// Supports being involved in a fight.
interface IFightable
{
Int32 HitPoints { get; set; }
Int32 Skill { get; }
Int32 Luck { get; }
}
// Example class declarations.
class RoomFeature : IExistInRoom
class Player : IMoveable, IFightable
class Monster : IMoveable, IFightable
// I'd proably choose to have this method in Game, as it alters the
// games state over one turn only.
void Move(IMoveable m, Direction d)
{
// TODO: Check whether move is valid, if so perform move by
// setting the player's location.
}
// I'd choose to put a fight in its own class because it might
// last more than one turn, and may contain some complex logic
// and involve player input.
class Fight
{
public Fight(IFightable[] participants)
public void Fight()
{
// TODO: Logic to perform the fight between the participants.
}
}
In your question, you identified the fact that you'd have many classes which have to know about each other if you stuck something like a Move method on your Player class. This is because something like a move neither belongs to a player or to a room - the move affects both objects mutually. By modelling the 'interactions' between the main objects you can avoid many of those dependencies.
Sounds like a scenario I often use a Command class or Service class for. For example, I might create a MoveCommand class that performs the operations and coordinations on and between Levels and Persons.
This pattern has the advantage of further enforcing the Single Responsibility Principal (SRP). SRP says that a class should only have one reason to change. If the Person class is responsible for moving it will undoubtedly have more than one reason to change. By breaking the logic of a Move off into its own class, it is better encapsulated.
There are several ways to implement a Command class, each fitting different scenarios better. Command classes could have an Execute method that takes all necessary parameters:
public class MoveCommand {
public void Execute(Player currentPlayer, Level currentLevel) { ... }
}
public static void Main() {
var cmd = new MoveCommand();
cmd.Execute(player, currentLevel);
}
Or, sometimes I find it more straightforward, and flexible, to use properties on the command object, but it makes it easier for client code to misuse the class by forgetting to set properties - but the advantage is that you have the same function signature for Execute on all command classes, so you can make an interface for that method and work with abstract Commands:
public class MoveCommand {
public Player CurrentPlayer { get; set; }
public Level CurrentLevel { get; set; }
public void Execute() { ... }
}
public static void Main() {
var cmd = new MoveCommand();
cmd.CurrentPlayer = currentPlayer;
cmd.CurrentLevel = currentLevel;
cmd.Execute();
}
Lastly, you could provide the parameters as constructor arguments to the Command class, but I'll forgo that code.
In any event, I find using Commands or Services a very powerful way to handle operations, like Move.
For a text-based game, you're almost certainly going to have a CommandInterpretor (or similar) object, which evaluates the user's typed commands. With that level of abstraction, you don't have to implement every possible action on your Player object. Your interpreter might push some typed commands to your Player object ("show inventory"), some commands to the currently-occupied Sector object ("list exits"), some commands to the Level object ("move player North"), and some commands to specialty objects ("attack" might be pushed to a CombatManager object).
In that way, the Player object becomes more like the Character, and the CommandInterpretor is more respresentational of the actual human player sitting at the keyboard.
Avoid getting emotionally or intellectually mired in what the "right" way to do something is. Focus instead on doing. Don't put too much value on the code you've already written, because any or all of it may need to change to support things that you want to do.
IMO there's way too much energy being spent on patterns and cool techniques and all of that jazz. Just write simple code to do the thing you want to do.
The level "contains" everything within it. You can start there. The level shouldn't necessarily drive everything, but everything is in the level.
The player can move, but only within the confines of the level. Therefore, the player needs to query the level to see if a move direction is valid.
The level isn't taking items from the player, nor is the level dealing damage. Other objects in the level are doing these things. Those other objects should be searching for the player, or maybe told of the player's proximity, and then they can do what they want directly to the player.
It's ok for the level to "own" the player and for the player to have a reference to its level. This "makes sense" from an OO perspective; you stand on Planet Earth and can affect it, but it is dragging you around the universe while you're digging holes.
Do Simple Things. Any time something gets complicated, figure out how to make it simple. Simple code is easier to work with and is more resistant to bugs.
So firstly, is this an alright way to
do this?
Absolutely!
Secondly, if the delegate chapter was
not presented the way it was, I would
not have thought of using such
'events'. So what would be a good way
to implement this without using
callbacks?
I know a lot of other ways to implement this, but no any other good way without some kind of callback mechanism. IMHO it is the most natural way to create a decoupled implementation.
Every so often, I run into a case where I want a collection of classes all to possess similar logic. For example, maybe I want both a Bird and an Airplane to be able to Fly(). If you're thinking "strategy pattern", I would agree, but even with strategy, it's sometimes impossible to avoid duplicating code.
For example, let's say the following apply (and this is very similar to a real situation I recently encountered):
Both Bird and Airplane need to hold an instance of an object that implements IFlyBehavior.
Both Bird and Airplane need to ask the IFlyBehavior instance to Fly() when OnReadyToFly() is called.
Both Bird and Airplane need to ask the IFlyBehavior instance to Land() when OnReadyToLand() is called.
OnReadyToFly() and OnReadyToLand() are private.
Bird inherits Animal and Airplane inherits PeopleMover.
Now, let's say we later add Moth, HotAirBalloon, and 16 other objects, and let's say they all follow the same pattern.
We're now going to need 20 copies of the following code:
private IFlyBehavior _flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
private void OnReadyToLand()
{
_flyBehavior.Land();
}
Two things I don't like about this:
It's not very DRY (the same nine lines of code are repeated over and over again). If we discovered a bug or added a BankRight() to IFlyBehavior, we would need to propogate the changes to all 20 classes.
There's not any way to enforce that all 20 classes implement this repetitive internal logic consistently. We can't use an interface because interfaces only permit public members. We can't use an abstract base class because the objects already inherit base classes, and C# doesn't allow multiple inheritance (and even if the classes didn't already inherit classes, we might later wish to add a new behavior that implements, say, ICrashable, so an abstract base class is not always going to be a viable solution).
What if...?
What if C# had a new construct, say pattern or template or [fill in your idea here], that worked like an interface, but allowed you to put private or protected access modifiers on the members? You would still need to provide an implementation for each class, but if your class implemented the PFlyable pattern, you would at least have a way to enforce that every class had the necessary boilerplate code to call Fly() and Land(). And, with a modern IDE like Visual Studio, you'd be able to automatically generate the code using the "Implement Pattern" command.
Personally, I think it would make more sense to just expand the meaning of interface to cover any contract, whether internal (private/protected) or external (public), but I suggested adding a whole new construct first because people seem to be very adamant about the meaning of the word "interface", and I didn't want semantics to become the focus of people's answers.
Questions:
Regardless of what you call it, I'd like to know whether the feature I'm suggesting here makes sense. Do we need some way to handle cases where we can't abstract away as much code as we'd like, due to the need for restrictive access modifiers or for reasons outside of the programmer's control?
Update
From AakashM's comment, I believe there is already a name for the feature I'm requesting: a Mixin. So, I guess my question can be shortened to: "Should C# allow Mixins?"
The problem you describe could be solved using the Visitor pattern (everything can be solved using the Visitor pattern, so beware! )
The visitor pattern lets you move the implementation logic towards a new class. That way you do not need a base class, and a visitor works extremely well over different inheritance trees.
To sum up:
New functionality does not need to be added to all different types
The call to the visitor can be pulled up to the root of each class hierarchy
For a reference, see the Visitor pattern
Cant we use extension methods for this
public static void OnReadyToFly(this IFlyBehavior flyBehavior)
{
_flyBehavior.Fly()
}
This mimics the functionality you wanted (or Mixins)
Visual Studio already offers this in 'poor mans form' with code snippets. Also, with the refactoring tools a la ReSharper (and maybe even the native refactoring support in Visual Studio), you get a long way in ensuring consistency.
[EDIT: I didn't think of Extension methods, this approach brings you even further (you only need to keep the _flyBehaviour as a private variable). This makes the rest of my answer probably obsolete...]
However; just for the sake of the discussion: how could this be improved? Here's my suggestion.
One could imagine something like the following to be supported by a future version of the C# compiler:
// keyword 'pattern' marks the code as eligible for inclusion in other classes
pattern WithFlyBehaviour
{
private IFlyBehavior_flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
[patternmethod]
private void OnReadyToLand()
{
_flyBehavior.Land();
}
}
Which you could use then something like:
// probably the attribute syntax can not be reused here, but you get the point
[UsePattern(FlyBehaviour)]
class FlyingAnimal
{
public void SetReadyToFly(bool ready)
{
_readyToFly = ready;
if (ready) OnReadyToFly(); // OnReadyToFly() callable, although not explicitly present in FlyingAnimal
}
}
Would this be an improvement? Probably. Is it really worth it? Maybe...
You just described aspect oriented programming.
One popular AOP implementation for C# seems to be PostSharp (Main site seems to be down/not working for me though, this is the direct "About" page).
To follow up on the comment: I'm not sure if PostSharp supports it, but I think you are talking about this part of AOP:
Inter-type declarations provide a way
to express crosscutting concerns
affecting the structure of modules.
Also known as open classes, this
enables programmers to declare in one
place members or parents of another
class, typically in order to combine
all the code related to a concern in
one aspect.
Could you get this sort of behavior by using the new ExpandoObject in .NET 4.0?
Scala traits were developed to address this kind of scenario. There's also some research to include traits in C#.
UPDATE: I created my own experiment to have roles in C#. Take a look.
I will use extension methods to implement the behaviour as the code shows.
Let Bird and Plane objects implement a property for IFlyBehavior object for an interface IFlyer
public interface IFlyer
{
public IFlyBehavior FlyBehavior
}
public Bird : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
public Airplane : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
Create an extension class for IFlyer
public IFlyerExtensions
{
public void OnReadyToFly(this IFlyer flyer)
{
flyer.FlyBehavior.Fly();
}
public void OnReadyToLand(this IFlyer flyer)
{
flyer.FlyBehavior.Land();
}
}