Design with interfaces in C# - c#

Problem
I have a design issue I can't solve clevely. I'm sure there's an elegent solution, but I can't figure out how achieve it. I still managed to my my code work, but the result is ugly, and I want to learn better designs.
I did my best to provide a minimal implementation with only the bare minimum. Some aspects might therefore look weird. I hope I will get myself clear.
Context
So first, I have these simple classes that both implement the same interface:
public interface Human
{
string getName();
}
public class Adult : Human
{
public Adult(string name, string job)
{
Name = name;
Job = job;
}
public string Name { get; set; }
public string Job { get; set; }
public string getName()
{
return Name;
}
}
public class Child : Human
{
public Child(string name, string toy)
{
Name = name;
Toy = toy;
}
public string Name { get; set; }
public string Toy { get; set; }
public string getName()
{
return Name;
}
}
I use those classes in another, more complex class, that basically have the folloing structure:
class MasterClass
{
public string Name;
public string Job;
public string Toy;
private ObservableCollection<Adult> ListOfAdults;
private ObservableCollection<Child> ListOfChildren;
private ObservableCollection<Human> CurrentList; // Will point to one of the above list
public void InitiateLists()
{
// Populate above lists with data
}
public Human CurrentHuman;
public void ManageAdults()
{
CurrentList = new ObservableCollection<Human>(ListOfAdults);
}
public void ManageChildren()
{
CurrentList = new ObservableCollection<Human>(ListOfChildren);
}
public void setOtherHuman()
{
// Sets CurrentHuman as another adult/child according to currently managed list
}
public void SetManager(string newType)
{
switch (newType)
{
case "adult":
ManageAdults();
break;
case "child":
ManageChildren();
break;
}
}
void UpdateInfo()
{
// Set Name and Toy/Job according to currently managed human
}
void PrintInfo()
{
// Print Name and Toy/Job according to currently managed human
}
}
This is the skeleton of my current implementation, with aspects I can't modify due to other constraints. In this class, I want the methods PrintInfo() and UpdateInfo() to behave differently depending if the CurrentHuman is an Adult or a Child.
So far
I managed to make it work with a swich-case in both methods and some cast. Like this:
void UpdateInfo(string currentType)
{
Name = CurrentHuman.getName();
switch (currentType)
{
case: "adult":
Job = ((Adult) CurrentHuman).Job;
break;
case: "child":
Toy = ((Child) CurrentHuman).Toy;
break;
}
}
This is really not ideal though. In my actual design, I have a lot more types, and other methods that behave differently according to the type of the CurrentItem. So I'm now drowning in switch-cases. This makes my code messy, duplicated and very hard to maintain.
Possible solution with interfaces
Since I just discovered them, I thought I could use interfaces. I did my best, but couldn't get a solution to work.
I imagined a simple interface like so:
public interface IUpdater
{
void UpdateData(); // Takes the values from CurrentHuman and store them in the private members Name and Job/Toy depending on current type.
void Print();
}
I also implement my interface in two different ways:
class AdultUpdater : IUpdater
{
public void Print()
{
// Print Adult stuff only
}
public void UpdateData()
{
// Update Adult data only.
}
}
and a similar class ChildUpdater : IUpdater. They both implement the dedicated code for the Child/Adult.
If I declare a private IUpdater Updater as private member of my MasterClass, this allows me to change my methods ManageAdult()and ManageChildren() like this:
public void ManageAdults()
{
CurrentList = new ObservableCollection<Human>(ListOfAdults); // Same as before
Updater = new AdultUpdater(); // Specify implementation to use
}
(similar for ManageChildren()).
I can then brilliantly implement my UpdateInfo() like this:
void UpdateInfo()
{
Updater.UpdateData();
}
and my PrintInfo() method like this:
void PrintInfo()
{
Updater.Print();
}
Interfaces are truly amazing! Oh but wait...
New problem
This seems very promising. My problem is that I don't know how to implement the code of my class AdultUpdater() and class ChildUpdater(). More precisely, these two classes need to access private members of the MasterClass, namely the members Name, Job and Toy. The UpdateData() need to modify them, and the Print() need to display them. I feel so stupidely stuck at this point, so close to a very elegent solution. Does someone have an idea how to finalize this design?
Thank you for reading... I'm sorry if this issue could have been reduced to a more concise question. I had the feeling some details about my current implementation were necessary to get a suitable answer.

As I see it, you are trying to "manage" your humans. Just let them self do the job.
f.e. Don't Print from the manager/masterclass and decide, what to print, but get the printed data (even if only parts, but the parts that are different) from humans and just put it all together in the masterclass.
Use Polymorphism for you. They (your objects/humans) already know, what to print out or update, so let them do the Job. Try to spread the work, instead of pulling it all into one class.

Here is what I advise,
You have a Human class which corresponds to your IHuman, something like this
public class Human : IHuman
{
public Human(string name, string job)
{
Name = name;
Job = job;
}
public string Name { get; set; }
public string Job { get; set; }
public string getName()
{
return Name;
}
}
Your adult and child class would then Inherit the Human class and pass back the constructor values.
public Adult(string name, string job) : base (name, job)
{
}
When you create an instance of adult, you will pass in the name and job, and you can call getName because it will be inherited from the Human class.

Related

How to name these helper functions?

public class Member
{
Team team;
int p;
public void GoToTeam(Team team) // how to name it? MS tells me not to add __
// I want to prevent this be called so easily by mistake
{
this.team = team;
p = team.GetHashCode(); // some setup for team changing, new id, new title, etc
}
}
public class Team
{
List<Member> members = new();
public void AddMember(Member member) // main func.
// Team moves people. How about Street? street don't move people
{
members.Add(member);
// and something more, member maps etc
}
}
Member has a GoToTeam function, which cannot work alone, without being called by functions like AddMember.
How to name these helper function in c#, to prevent it to be called alone by mistake?
A good class design would help. Like always Team do action to lower hierachies.
But member is the basic action unit. Do I need a ugly member.AddTeam_wrapper()?
Is there a more straightforward way to do this?
Like __GoToTeam in other languages.
I'm working on composite patterns.
A lot of classes are hierachically structured.
Methods are used to change their relationship.
It's easy to use a half-function by mistake, without a detailed documentation.
In some languages, you use friend class private, __goto method, to prevent these methods to be used.
Again, I'm not so good at designing these not so tiny modules, as MS expected :(
When geo-layers, bio-layers, political-layers comes, it's to messy to have one prime rule to identify the Main function, which calles other (I call it) half-functions.
I want a good naming convention to identify these public methods and public but not standalone methods.
Thank you!
First of all, if the naming conventions are one of your concerns, you should change AddMember_wrapper to AddMemberWrapper.
Then, you should consider one of your classes as something like a parent and do any of your actions through it. In this case, you can consider Team as a parent and Member will be one of its Children(AggregateRoot Pattern). If you want to set a Team for a Member, you should do it another way around and add the Member to a Team.
public class Team
{
public List<Member> Members { get; private set; }
public Team()
{
Members = new List<Member>();
}
public void ChangeMemberName(int memberId, string newName)
{
Member member = Members.SingleOrDefault(x => x.Id == memberId);
if (member is null)
throw new ArgumentException("Member not found.");
member.ChangeName(newName);
}
public void AddMember(Member member)
{
Members.Add(member);
// and something more, member maps, etc
}
}
public class Member
{
public int Id { get; private set; }
public string Name { get; private set; }
// ...
public Member(string name)
{
Name = name;
}
public void ChangeName(string newName)
{
Name = newName;
}
}

How to force my classes to use as I thought with T

I've made a class with T. It looks like this.
public interface ISendLogic<T> where T : NarcoticsResult
{
ChangeType Change_New();
ChangeType Change_Cancel();
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
private eReportType _type;
private bool Send_Change()
{
// Send to server by xml file
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public ChangeType Change_New()
{
_type = change_new;
Send_Change();
}
public ChangeType Change_Cancel()
{
_type = change_cancel;
Send_Change();
}
public PurchaseType Purchase_New()
{
_type = purchase_new;
Send_Purchase();
}
public PurchaseType Purchase_Cancel()
{
_type = purchase_cancel;
Send_Purchase();
}
}
There are two types, ChangeType and PurchaseType
and these are inherited from NarcoticsResult.
I thought the person who want to use this class would use it like this.
// this class can only be used when someone wants to use change function
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();
Here is a question.
I want to force this class to be used only as I thought.
I mean, I want to prevent it to be used like this.
var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()
I thought I add some code which check type of T in every function.
How do you think the way I thought. I think there are better way to fix it
Please tell me a better way
thank you.
Personally, I don't think you need a generic class in this case. What you need is either an abstract base class or an interface. I personally love the interface approach as below:
public interface ISendLogic {
void New();
void Cancel();
}
So now you've got a contract that will force the consumer of your code to use New or Cancel methods only.
The next step you can implement that send logic interface for your specific implementation:
public class ChangeSendLogic : ISendLogic {
private eReportType _type;
public ChangeSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Change()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Change();
}
public void Cancel()
{
_type = change_cancel;
Send_Change();
}
}
public class PurchaseSendLogic : ISendLogic {
private eReportType _type;
public PurchaseSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Purchase();
}
public void Cancel()
{
_type = change_cancel;
Send_Purchase();
}
}
From here you can see those two classes handle the implementation for each type nicely. You can think this is as an implementation of single responsibility principle. So if you have one more type, you can just add one more implementation of this interface rather than updating the existing classes.
If you want to hide the creation of those objects, in the next part you can introduce a kind of factory or selector as below:
public enum SendLogicType {
Change,
Purchase
}
public static SendLogicSelector {
public static ISendLogic GetSendLogic(SendLogicType type)
{
switch(type)
{
case SendLogicType.Change:
return new ChangeSendLogic();
case SendLogicType.Purchase:
return new PurchaseSendLogic();
}
}
}
This is how the code will be consumed:
ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed
sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed
Hopefully, you can get the idea of my approach. Good luck! :)
Thank you for your comment
I divided it into two parts like below
public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic
And I also divided interface too
public interface IChangeLogic
{
ChangeType Change_New();
ChangeType Change_Cancel();
}
public interface IPurchaseLogic
{
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
And I made SendLogic<T> class to abstract class.
This is because I want to make the person who wants to use this class to use a class that inherits from this class without directly accessing it.
Thank you for your comment. I got a good idea.

Generic object creation method with default data

I'd like to have two simple calls in a class that would be transformed by other classes. Something like:
ObjectCreator.CreateBlank<Human>();
ObjectCreator.CreatePopulated<Human>();
ObjectCreator.CreateBlank<Dog>();
ObjectCreator.CreatePopulated<Dog>();
I currently do this:
public class ObjectCreator
{
public static T CreateBlank<T>()
{
return Activator.CreateInstance<T>();
}
public static T CreatePopulated<T>()
{
//Somehow return new object with populated properties
}
}
I am struggling with the populated part. I'd like it to return a "default" object of that type with defined properties. I've tried a few things involving passing in interfaces, but it gets messy fast (I don't expect this to be particularly clean either)
So If I called ObjectCreator.CreatePopulated(), I'd like it to somehow go to a different class where I create a new Anything, and fill it's properties to specific values. It feels like I'm close but missing a piece of the puzzle here.
My end game here is to have the call be as simple / readable as possible.
Any help is appreciated.
I DO realize it'd probably be easier to simply call a class that creates and populates each object, but this is a learning exercise for me and I'd like to attempt to get this working as generically as possible.
I would recommend doing something like this:
public interface IPopulatable
{
void Populate();
}
public class ObjectCreator
{
public static T CreateBlank<T>() where T : new ()
{
return new T();
}
public static T CreatePopulated<T>() where T : IPopulatable, new()
{
var populatable = new T();
populatable.Populate();
return populatable;
}
}
public class Human : IPopulatable
{
public string Name { get; set; }
public void Populate()
{
Name = "Joe";
}
}

Open Closed Principle and Strategy Pattern Question

I have a couple of ideas but I wanted to see what the SO community would suggest.
I have an abstract class with an abstract Calculate method on it. I have 2 implementations of it that calculate differently. This screams Strategy pattern to me however one of the implementations requires that a selected_type variable be set because it is used inside the Calculate method. I want to follow the OCP so my Calculate method shouldn't take in the dependencies.
This class is retrieved from the DB via NHibernate and the selected_type variable won't be set until after the object has been created. I'm trying to avoid an if statement to set the selected_type only if it is of a specific implementation. What would be the best way?
Here is a code example:
public abstract class TagType
{
public virtual long id { get; protected set; }
public virtual string description { get; protected set; }
protected TagType(){}
protected TagType(string description)
{
this.description = description;
}
public abstract decimal Calculate();
}
public class TagTypeImpl1
{
public virtual int tag_months { get; protected set; }
protected TagType() { }
protected TagType(string description, int tag_months): base(description)
{
this.tag_months = tag_months;
}
public override decimal Calculate()
{
return (12*tag_months);
}
}
public class TagTypeImpl2
{
public virtual int tag_months { get; protected set; }
public virtual TagType selected_tag_type { get; protected set; }
protected TagType() { }
protected TagType(string description, int tag_months, TagType selected_tag_type): base(description)
{
this.tag_months = tag_months;
this.selected_tag_type = selected_tag_type;
}
public override decimal Calculate()
{
return selected_tag_type.Calculate() + (12*tag_months);
}
}
public class ConsumerController
{
private readonly IRepository<TagType> repository;
public ConsumerController(IRepository<TagType> repository)
{
this.repository = repository;
}
public ActionResult Index(long id)
{
var tag_type = repository.get(id);
//If using TagTypeImpl2 then the selected_tag_type variable needs to be set
//I want to avoid if(tag_type.GetType() == typeof(TagTypeImpl2)) set selected_tag_type
var result = tag_type.Calculate();
return Json(new {result});
}
}
I might be trying to do too much with this class adn maybe the persisted entity class is the wrong place to have the Calculate method but it seemed the best place since it knows the most about how to do the calculation.
Would it make sense to create a virtual (overridable) function "Initialize" that one should call on all tag_type objects loaded from repository so they can do what was skipped by the default constructor that the parameterized constructor would have done?
Or can you change the default constructor to initialize selected_type to either the correct value or some value that will instruct the calculate method to correct it before using it?
It's not the responsibility of your class to decide what the strategies need, it's the responsibility of the strategy. The whole idea is that you can call whatever strategy you're using the same way, all the time.
Simply make all strategies implement the same interface -including selected_type-, but one of them ignores the selected_type, the other uses it. It's up to the strategy itself to decide this.
Alternatively, your implementations of strategy can have more properties than are defined in the interface. If you can initialize the strategies from outside of your class, and it's not a problem for the initializing class to know more about the specific implementation you might be able to set the properties for only the specific strategy that needs it. The former solution is cleaner though (always using the same interface).

How do I design classes in my role playing game to allow multi-classing?

I am programming a game as an exercise and I've run into a design problem. My role playing game will have the typical classes like Fighter, Wizard, Theif, Cleric. How do I design my classes so that players can multi-class? For example, one player might start off as a Fighter (and gain the related skills fighters have), then multi-class to a Wizard (at that point they gain wizard spells), and later on multi-class yet again to a rogue (now gaining all abilities rogues have). So this player is now a Fighter-Wizard-Rogue. I don't know to represent this in C#.
At first I tried to use the decorator pattern but I'm unable to multi-class multiple times with this. Any pointers on how to design this?
Only thing I can think of is having an IList<CharacterBaseClass> property for each character and adding Fighter, Wizard, Rogue, etc to this as the player multi-classes. So something like this..
class CharacterBaseClass
{
public IList<CharacterBaseClass> MultiClasses { get; set; }
// constructors, etc
}
and each time they mutli-class I add to the IList
// player starts off as Fighter
Warrior player1 = new Warrior();
// now multi-class to Wizard
player1.MultiClasses.Add(new Wizard());
// now multi-class to Theif
player1.MultiClasses.Add(new Theif());
I'm sure there must be a better way than this?
Just because your characters are wizards and warriors, that doesn't mean you have to create subclasses for them. Instead, ask yourself, "At the code level, what does a character's class do?" Likely, you won't want to have C# subclasses for character classes at all. Instead, figure out what the class actually does, and then determine the right way to model that in code.
For example, if character class restricts the equiment a character can use, then you can define a class for AllowedEquipment:
public class AllowedEquipment
{
public static AllowedEquiment Warrior()
{
return new AllowedEquipment() {
Daggers = true;
Swords = true;
Shields = true;
Armor = true
};
}
public static AllowedEquiment Wizard()
{
return new AllowedEquipment() {
Daggers = true;
Swords = false;
Shields = false;
Armor = true
};
}
public bool Daggers { get; set; }
public bool Swords { get; set; }
public bool Shields { get; set; }
public bool Armor { get; set; }
}
Don't feel you need to use subclasses to model every "is-a" relationship in your game.
Another option is to use the Type Object pattern to model your character classes. If you do that, it'd be easy to give each character a set of those Type Object instances instead of a single one, giving you, in effect, multiple inheritance.
With the decorator pattern, you could possibly do it.
Character person = new Character("Rambo");
person = new Fighter(person); // decorate him with Fighter skills
person = new Thief(person); // also decorate him with Thief skills
Personally I would probably look at attaching classes to the character instead:
Character person = new Character("Rambo");
person.AttachClass(new Fighter());
person.AttachClass(new Thief());
Of course, if you need complex interactions between the classes, so that not only does a Fighter/Thief gets bonuses and skills from each, but he gets something more as well, perhaps the only correct route for that might be to create specific multi-classes for all the combinations:
Character person = new Character("Rambo");
person.AttachClass(new FighterThief());
This would of course just explode with all the combinations.
What about a pure table-driven effort?
Place all applicable skills, spells, bonuses, effects, etc. in a hunking big table, then define the classes by linking a specific class to the specific items in that table. This way it would be much simpler to create hybrid classes by linking across different base classes.
To use a decorator pattern and still get proper access to everything, each class (in the programming sense of the word) needs to be implemented properly as a decorator class.
For instance:
public class BaseClass
{
protected BaseClass(BaseClass underlyingCharacterClass);
public abstract bool CanCastSpells();
public abstract List<Spell> GetAvailableSpells();
protected BaseClass UnderlyingCharacterClass;
}
public class Wizard : BaseClass
{
public override bool CanCastSpells() { return true; }
public override List<Spell> GetAvailableSpells()
{
List<Spell> result = new List<Spell>();
if (UnderlyingCharacterClass != null)
result.AddRange(UnderlyingCharacterClass.GetAvailableSpells());
result.Add(new WizardSpell1());
...
return result;
}
}
public class Thief : BaseClass
{
public override bool CanCastSpells()
{
if (UnderlyingCharacterClass != null)
return UnderlyingCharacterClass.CanCastSpells();
return false;
}
public override List<Spell> GetAvailableSpells()
{
List<Spell> result = new List<Spell>();
if (UnderlyingCharacterClass != null)
result.AddRange(UnderlyingCharacterClass.GetAvailableSpells());
return result;
}
}
If the classes have some common interface or base class, then multiclass is additional class (MultiClass) which also implements this interface or base class, then delegates to its contained instances.
For example:
public class MultiClass : Class {
...
public MultiClass(params Class[] classes) {
this.classes = classes;
}
public IEnumerable<Ability> GetAbilities() {
return this.classes.SelectMany(с => c.GetAbilities());
}
...
}
If you want to add more classes, you can add AddClass method to the base Class, which would create MultiClass from single class, or recreate multiclass with one more contained class for MultiClass.
Not everyone's cup of tea, but you could use state pattern.
public interface Player
{
void Fight();
void CastSpell();
void DoRoguishThings();
}
public class PlayerImpl : Player
{
Player fighter;
Player wizard;
Player rogue;
Player current;
public void Fight(){ current.Fight(); }
public void CastSpell(){ current.CastSpell(); }
public void DoRoguishThings(){ current.DoRoguishThings; }
public void MakeWizard(){ current = wizard; }
public void GoRogue(){ current = rogue; }
}
public class Fighter : Player
{
public void Fight(){ // do fighting }
public void CastSpell()
{
Console.WriteLine("You can't cast a spell, you are but a mere pugilist.");
}
...
}
public class Wizard : Player
{
public void Fight(){ // do wizardly fighting }
public void CastSpell() { // do spell-casting }
public void DoRoguishThings() { // whatever }
}
I think your characters should be able to have multiple Facet/Role implementing "Archetypes".
Then each one having multiple skills or attributes. Let's say...
class Archetype
{
string Name;
Dictionary<string,Type> Properties;
Dictionary<string,Action> Skills;
}
class Character
{
string Name;
string Alias;
Dictionary<Archetype,Dictionary<string,object>> FacetData;
}
class TheGame
{
public static void Main()
{
var Pilot = new Archetype();
Pilot.Name = "Combat-Pilot";
Pilot.Properties.Add("FlightHours", typeof(int));
Pilot.Properties.Add("AmbientTypes", typeof(List<string>));
var Jedi = new Archetype();
Jedi.Name = "Jedi";
Jedi.Properties.Add("ForceLevel", typeof(int));
Jedi.Properties.Add("Title", typeof(string));
Jedi.Properties.Add("IsCombatVeteran", typeof(bool));
Jedi.Skills.Add("LightSaberFight", FightWithLightSaber());
var Anakin = new Character();
Anakin.Id = 100;
Anakin.Name = "Anakin Skywalker";
Anakin.Alias = "Darth Vader";
Anakin.FacetData.Add(Pilot, new Dictionary<string, object>()
{ { "FlightHours", 2500 },
{ "AmbientTypes", new List<string>() {"Atmospheric", "Space", "Hyper-Space"} } };
Anakin.FacetData.Add(Jedi, new Dictionary<string, object>()
{ { "ForceLevel", 7 },
{ "Title", "Padawan" },
{ "IsCombatVeteran", true } };
Anakin.ApplySkill(Jedi, "LightSaberFight", Target);
}
public static void FightWithLightSaber(Character Target)
{
ShowBrightLightSaberPointingTo(Target);
EmitCoolSound();
}
}
If you get the Idea, then you could store properties/data and call skills/tasks with some degree of indirection and flexibility.
Good luck!
You may want to consider composition.
interface IWarrior
{
void Slash();
}
interface IMage
{
void Cast();
}
class Warrior : IWarrior
{
public void Slash() { }
}
class Mage : IMage
{
public void Cast() { }
}
class WarriorMage : IWarrior, IMage
{
private readonly Warrior _Warrior;
private readonly Mage _Mage;
public void Slash()
{
_Warrior.Slash();
}
public void Cast()
{
_Mage.Cast();
}
}
Néstor Sánchez A. provides you with a good solution. Drop your OOP thinking for a while and read this:
http://www.devmaster.net/articles/oo-game-design/
Not every problem can be solved with plain OOP in an elegant way.

Categories

Resources