Every time I want to make something like a "static override" (which is not possible in C#) I find questions that say this is caused by a poor design. How would you design your code to avoid this?
Example: some game with lots of units, each has a different cost (an int or something like that), but each of the subclassses has the same cost. It would make sense here(IMHO) using an "abstract static", but that is not possible. Which is the best way to model this cases?
I usually end up creating an abstract method that returns a static variable that I have to create (and remember!) in each subclass, but then I always depend on having an instance of each class, any other ideas?
No need to use statics here at all. Simply define a base class for all concrete units, that takes the cost as initialization argument:
public abstract class UnitBase
{
public int Cost { get; private set; }
public UnitBase(int cost)
{
this.Cost = cost;
}
}
Taking this as the base for your inheritance tree, you would then go along these lines:
public abstract class Unit1Base : UnitBase
{
public Unit1() : base(<actual_cost>) { }
}
public class ConcreteUnit1 : Unit1Base {}
public class ConcreteUnit2 : Unit1Base {}
This way, each concrete unit will have the desired cost value...
but each of the subclassses has the same cost.
That seems like a good candidate for a base class containing a Cost property that the others will inherit:
public virtual decimal Cost
{
get { return 20m; }
}
Then if anywhere down the chain you have some other price, you could override the Cost property.
You are correct in that you cannot have a static virtual/override property. This can be annoying for the case you describe, which I too have struggled with in the past.
However, you can use static properties... and the new keyword to hide the base implementation.
For example, let's define some units here:
public abstract class BaseUnit
{
public static int UnitCost { get { return 10; } }
}
public class CheapUnit : BaseUnit
{
new public static int UnitCost { get { return 5; } }
}
public class ExpensiveUnit : BaseUnit
{
new public static int UnitCost { get { return 20; } }
}
public class MultipleUnit : BaseUnit
{
new public static int UnitCost { get { return BaseUnit.UnitCost * 4; } }
}
Then a little test program to output their values:
public void Run()
{
Console.WriteLine("Base unit cost:\t\t{0}", BaseUnit.UnitCost);
Console.WriteLine("Cheap unit cost:\t{0}", CheapUnit.UnitCost);
Console.WriteLine("Expensive unit cost:\t{0}", ExpensiveUnit.UnitCost);
Console.WriteLine("Multiple unit cost:\t{0}", MultipleUnit.UnitCost);
}
And we get...
Base unit cost: 10
Cheap unit cost: 5
Expensive unit cost: 20
Multiple unit cost: 40
Ah ha! Exactly what we want. I'm not 100% happy with this solution but I don't know a better way without having to create an instance which I think it silly to access a polymorphic class constant. So I just do it this way.
EDIT: In cases where I found myself doing this, I often opted to move this kind of 'lookup' logic into a manager (singleton) class. For example, UnitManager or similar, where I could pass in a type name ("CheapUnit") and it would look up the cost in a Dictionary.
Just a quick mockup idea:
sealed class UnitManager
{
static readonly UnitManager instance = new UnitManager();
public static UnitManager Instance { get { return instance; } }
Dictionary<string, int> unitCostDictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); // Ignore Case of Keys
public int LookupUnitCost(string unitType)
{
int unitCost = 0;
unitCostDictionary.TryGetValue(unitType, out unitCost);
return unitCost;
}
}
This also allows dynamic unit cost and centralized notifications when a unit cost may change.
Create a Factory class (static) that returns the instance you want but have the declaration of the factory method return the abstract type?
While I sometimes miss the ability to override a static method in .net, it wouldn't be for this scenario.
Aside from simply using inheritance which you seem to be dead against for some reason I can't fathom, another way to do it might be, to delegate cost to one static class which took unit type as an argument.
Another would be to make cost an attribute of the class and look it up via reflection.
Related
So I am trying to understand this sample code from Lynda.com without explanation.
IScore.cs
internal interface IScore
{
float Score { get; set; }
float MaximumScore { get; set; }
}
ScoreEntity.cs
internal class ScoreEntity : IScore
{
public float Score { get; set; }
public float MaximumScore { get;set;}
}
ScoreUtility.cs
internal class ScoreUtility
{
public static IScore BestOfTwo(IScore as1, IScore as2)
{
var score1 = as1.Score / as1.MaximumScore;
var score2 = as2.Score / as2.MaximumScore;
if (score1 > score2)
return as1;
else
return as2;
}
}
Calling code:
var ret = ScoreUtility.BestOfTwo(new ScoreEntity() { Score = 10, MaximumScore= 4},
new ScoreEntity() {Score = 10, MaximumScore = 6});
return;
My question is, in the ScoreUtility, what's really the benefit of using the interface type as return type in the method and argument type in the parameters, vs. just using ScoreEntity for the return and parameters, since the method itself returns a concrete object? Is this just to make the code looked 'smart'?
Any class that implements the IScore interface can be passed into the ScoreUtility method.
Perhaps there's a reason to implement another ScoreEntity class, like wanting to add a name seen in NamedScoreEntity :
internal class NamedScoreEntity: IScore
{
public string Name { get; set; }
public float Score { get; set; }
public float MaximumScore { get;set;}
}
If that's the case, then you can still use your utility methods on the new classes because of the contract the IScore interface enforces.
In this case, you could now compare the score between an un-named score object to a score object that also has a name.
Similarly, returning IScore allows the method to remain flexible enough to be used on multiple object types, and you can easily cast the returned type when you need to.
Given this declaration
public static IScore BestOfTwo(IScore as1, IScore as2)
The method does not know (or care) about the concrete types of as1 and as2. They may be ScoreEntity, or may be something entirely different. All it knows is that they implement IScore.
So if the method was to return a concrete type, then you have effectively limited the as1 and as2 parameters to being ScoreEntity, and have reduced its flexibility.
The only way you could guarantee that the method wouldn't fail would be to rewrite it as
public static ScoreEntity BestOfTwo(ScoreEntity as1, ScoreEntity as2)
In the posted code there is very little benefit, and I would argue that the interface should be removed. I would also argue that the comparison logic probably should be part of the object, or possibly an implementation of IComparer<T>.
Interfaces are most useful when there is a good reason for having multiple implementations. IComparer<T> is a great example, you might want to compare scores by the absolute score value, or the relative. So providing an abstraction is really useful.
Just applying interfaces to all classes is not a good idea, it will just make your code more complicated without any benefit. You might also discover that it can be difficult to provide a second implementation if the interface is not designed at the right abstraction level. This may result in adding properties or methods to objects that does not do anything or throws, just because they are required by a implemented interface. See for example IList<T> where many of the implementer throw exceptions for some of the methods.
In the specific case of IScore, it may be useful if you have some need for additional score-classes. But in many cases I would argue that composition might be more useful, i.e.
public class MyNamedScore{
public string Name {get;}
public ScoreEntity Score {get;}
}
I mentioned that I haven't worked a lot with DTO's. Im playing around with polimophism on DataTransfereObjects. I could not figure out a nice Solution, so i have made this codesample to master polimorphism with DataTransfereObjects and different logic implementation, Uses Polimorphism, generics, interfaces, abstract and so on.
Please check the code. HINT me whats bad, could be done better or easier. Check accessmodifier, Also check against SOLID (think I haven't understood it correctly). At the end it seems to be too complex, is it common to solve it in that way?
Actually, I try to call some (de)serialize programlogic which uses baseDto for derived dtos without loosing their specific information. This Code should be a clean abstraction sandbox for problems of that kind.
void Main()
{
var twoIngrDto = new TwoIngredientsDto();
var threeIngrDto = new ThreeIngredientsDto();
var twoIngrMulAnswerChecker = new TwoIngredientsMultiplicationAnswerChecker();
var threeIngrAddAnswerChecker = new ThreeIngredientsAdditionAnswerChecker();
twoIngrMulAnswerChecker.IsTheAnswerCheckImplementationTheAnswer(twoIngrDto); //TRUE .Dump();
threeIngrAddAnswerChecker.IsTheAnswerCheckImplementationTheAnswer(threeIngrDto); //TRUE .Dump();
twoIngrMulAnswerChecker.IsTheAnswerCheckImplementationTheAnswer(threeIngrDto); //FALSE .Dump();
IAnswerCheck answerchecker = new IngredientsAnswerChecker();
answerchecker.CheckAnswer(twoIngrMulAnswerChecker, twoIngrDto); //TRUE .Dump();
answerchecker.CheckAnswer(threeIngrAddAnswerChecker, threeIngrDto); //TRUE .Dump();
/// QUESTION: How can I use the answerchecker 'twoIngrMulAnswerChecker' with the derived DTO 'threeIngrDto'
/// It failes with following error:
/// The type 'UserQuery.TwoIngredientsMultiplicationAnswerChecker' cannot be used as
/// type parameter 'T' in the generic type or method 'UserQuery.IngredientsAnswerChecker.CheckAnswer<T,DTO>(T, DTO)'.
/// There is no implicit reference conversion from 'UserQuery.TwoIngredientsMultiplicationAnswerChecker'
/// to 'UserQuery.TheAnswerChecker<UserQuery.ThreeIngredientsDto>'.
//answerchecker.CheckAnswer(twoIngrMulAnswerChecker, threeIngrDto).Dump();
answerchecker.CheckAnswer(twoIngrMulAnswerChecker, (TwoIngredientsDto)threeIngrDto).Dump(); // is casting the solution?
}
interface IAnswerCheck
{
bool CheckAnswer<T, DTO>(T answerCkecker, DTO ingredientsDto)
where T : TheAnswerChecker<DTO>
where DTO : IngredientDto;
}
public abstract class TheAnswerChecker<T> where T : IngredientDto
{
internal abstract int TheAnswerCheckImplementation(T answerIngredietsDto);
private int TheAnswer {get { return 42;} }
public bool IsTheAnswerCheckImplementationTheAnswer(T answerIngredietsDto)
{
return TheAnswer == TheAnswerCheckImplementation(answerIngredietsDto);
}
}
//generate a base class
public class IngredientsAnswerChecker : IAnswerCheck //: TheAnswerChecker<IngredientDto>
{
public bool CheckAnswer<T, DTO>(T answerCkecker, DTO ingredientsDto)
where T : TheAnswerChecker<DTO>
where DTO : IngredientDto
{
return answerCkecker.IsTheAnswerCheckImplementationTheAnswer(ingredientsDto);
}
}
public class TwoIngredientsMultiplicationAnswerChecker : TheAnswerChecker<TwoIngredientsDto>
{
internal override int TheAnswerCheckImplementation(TwoIngredientsDto answerIngredietsDto) //where T : TwoIngredientsDto
{
return answerIngredietsDto.A * answerIngredietsDto.B;
}
}
public class ThreeIngredientsAdditionAnswerChecker : TheAnswerChecker<ThreeIngredientsDto>
{
internal override int TheAnswerCheckImplementation(ThreeIngredientsDto answerIngredietsDto)
{
return answerIngredietsDto.A + answerIngredietsDto.B + answerIngredietsDto.C;
}
}
public class IngredientDto
{
public IngredientDto()
{
Id = Guid.NewGuid();
}
public Guid Id { get; private set; }
}
public class TwoIngredientsDto : IngredientDto
{
public virtual int A {get {return 6;}}
public virtual int B {get {return 7;}}
}
public class ThreeIngredientsDto : TwoIngredientsDto
{
public override int B {get {return 24;}}
public int C {get {return 12;}}
}
The idea behind DTOs is to use dummy/plain objects for data transfer, therefore you should avoid adding complexity, for example through inheritance, to this kind of objects, otherwise DTOs will loose their main purpose of being simple and serialization friendly.
Regarding your "cast question", the answer is yes, a cast will permit to use ThreeIngredientsDto instead of TwoIngredientsDto.
For the private property "TheAnswer" I would suggest to use a const.
Overall your example respects SOLID principles, but beware not always we have to split our code in atomic pieces for achieving Single Responsibility Principle. For example instead of having TwoIngredientsMultiplicationAnswerChecker, ThreeIngredientsAdditionAnswerChecker and TheAnswerChecker classes, I would use a single class TheAnswerChecker which would have an overload method for each type of DTO, in this way your code will be more readable and more understandable and after all, your class responsibility will be only to check the answer. Of course, if the logic for checking the answer for each type of DTO will be very complex and will require a large amount of code, then probably it will make sense to split in different classes. The point is that SOLID should represent a set of principles to keep in mind when you structure your code, but sometimes breaking some of the rules can bring many benefits, in which case you should do this compromise.
I am making a game in which I have many kinds of soldiers, each kind with their own attributes (speed, attackPower...). Obviously, all of them can Walk, Attack... so I thought that creating an abstract class Soldier with those methods, and subclasses with each unit attributes would be the appropiate. The problem is that I can't use the attributes of derived classes in the base one.
The easy way would probably be implementing the methods in the derived classes, but that would mean lots of duplicated code, and I want to avoid it. In fact, this would make the base class unneccesary.
I have tried several things. As I understand, the closest solution I tried was using abstract/virtual properties, but again I would be duplicating the "get" code for each unit type. Maybe this can't be avoided, but I'd like to, if possible.
There surely exist a simple solution I haven't thought about. ¿Any ideas?
I think about somethink like this:
public abstract class Soldier {
public int AttackPower {
get { return this.power; }
}
public Attack {
Console.WriteLine("Attacked with "+AttackPower+" attack power");
}
}
public class Lancer:Soldier {
int power=5;
}
public class Archer:Soldier {
int power=10;
}
Of course, this is not a correct solution, because the Soldier class doesn't know about the "power" variable, but if I declare the "power" variable in the Soldier class, I get an error because the field name is duplicated.
Any help will be appreciated.
You need an abstract property:
public int AttackPower {
get { return this.power; }
}
protected abstract int Power { get; }
public class Lancer:Soldier {
protected override int Power { get { return 5; } }
}
You could also do a "GetPower" method if you really don't like properties. As you've discovered, if a base class method needs access to the data, you have to declare that data in the base class.
Its not code duplication, its type safety!
Why not just put a Power property in the base class?
public abstract class Soldier {
public int Power {get; set;}
public int AttackPower {
get { return this.Power; }
}
public Attack {
Console.WriteLine("Attacked with "+AttackPower+" attack power");
}
}
public class Lancer:Soldier {
public Lancer()
{
Power = 5
}
}
public class Archer:Soldier {
public Archer()
{
Power=10;
}
}
Some design comments:
Do you need different classes for Archer and Lancer, or can they just be Soldiers that are configured differently?
It would be better to pull property values like this from a data source rather than hard-coding them in the source code. You can embed an XML file or something so it's not easily editable.
I have 2 cases wheter a method can be considered a Factory Design Pattern, this example is in C#, altought, can apply to other programming languages:
enum NinjaTypes {
Generic,
Katanna,
StarThrower,
Invisible,
Flyer
}
public class Ninja {
public string Name { get; set; }
public void jump() { ... }
public void kickAss() { ... }
}
public class KatannaNinja: Ninja {
public void useKatanna() { ... }
}
public class StarNinja: Ninja {
public void throwStar() { ... }
}
public class InvisibleNinja: Ninja {
public void becomeInvisible() {...}
public void becomeVisible() {...}
}
public class FlyNinja: Ninja {
public void fly() {...}
public void land() {...}
}
public class NinjaSchool {
// always return generic type
public Ninja StandardStudent() {...}
// may return other types
public Ninja SpecialityStudent(NinjaTypes WhichType) {...}
}
The method StandardStudent() always return a new object of the same type, the SpecialityStudent(...), may return new objects from different classes that share the same superclass / base type. Both methods are intentionally not virtual.
The question is, are both methods "Factory Design Pattern" ?
My guess is that SpecialityStudent(...) is, but StandardStudent() is not. If the second is not, can be considered another design pattern ?
I don't think that nor a FactoryMethod`nor AbstractFactory patterns forbid the user to use a parameter to specify a type to the creator method. Anyway you should consider at least 2 things in your design:
Factory methods are useful to keep the client unaware of the concrete type of the created object. From my point of view isn't wrong to specify explicitly the type of object to be created, but pay attention to not put too much knowledge on the client classes to be able to construct objects through the factory.
Both your factory methods return a Ninja object, but some of your ninjas extended class declare additional methods, which client is unaware of. If your client need to use those methods explicitly then maybe you have to make some consideration on your design.
I think this actually looks like an Anti-Pattern. There's really nothing to stop a consumer of this code to just instantiate the specialty ninjas directly. What benefit is there to using the Ninja School? I think the whole point of the Factory pattern is to encapsulate the process of instantiating an object so that you can hide the details from the consumer. Any time you make a change to the "creation" logic, it doesn't break anyone's code.
And it just looks like a bad idea to have all the types in an enum. I don't have a concrete reason to back up this claim other than, "it feels wrong".
After reviewing the Abstract Factory pattern, I can see how you could go about turning this into an Abstract Factory, but I don't see the benefit given the semantics of your objects. I think that if you want to have a Ninja factory, you'd have to make the individual constructors protected or internal, so they can't be called directly by consumer code
Both your methods can be seen as factories. But the second one is a little awkward to use:
var school = new NinjaSchool();
var ninja = school.SpecialtyStudent(NinjaTypes.Flyer);
// to fly you must cast
((FlyingNinja)ninja).Fly();
You've already asked for a flyer, so you shouldn't need to cast. A better option might be to eliminate the enum and ask for the exact ninja that you want:
var flyingNinja = school.FlyingStudent(); // you get a FlyingNinja
flyingNinja.Fly();
Another thing to consider in your design is this: what if you want an invisible ninja that can fly? Or a katana ninja that also throws stars? That will shake up your hierarchy and challenge your belief in inheritance.
It's almost a factory method. I would do something like:
enum NinjaTypes {
Generic, Katanna, StarThrower, Invisible, Flyer
}
class Ninja {
String Name;
void jump() {
}
void kickAss() {
}
void useKatanna() {
System.out.println("nothing happens");
}
void throwStar() {
System.out.println("nothing happens");
}
void becomeInvisible() {
System.out.println("nothing happens");
}
void becomeVisible() {
System.out.println("nothing happens");
}
void fly() {
System.out.println("nothing happens");
}
void land() {
System.out.println("nothing happens");
}
}
class StarThrowerNinja extends Ninja {
void throwStar() {
System.out.println("throwing star");
}
}
class NinjaSchool {
static Ninja create(NinjaTypes WhichType) {
switch (WhichType) {
case Generic:
return new Ninja();
case StarThrower:
return new StarThrowerNinja();
default:
return null;
}
}
}
public class Main {
public static void main(String[] args) {
Ninja generic=NinjaSchool.create(NinjaTypes.Generic);
generic.throwStar();
Ninja starThrower=NinjaSchool.create(NinjaTypes.StarThrower);
starThrower.throwStar();
}
}
I have 3 classes, two inherit from 1:
public class Employee {
private virtual double getBonus() { ... }
private virtual double getSalary() { ... }
}
public class Nepotism : Employee {
private double getBonus() { ... }
}
public class Volunteer : Employee {
private double getSalary() { ... }
}
So the question is sometimes there will be a Volunteer who gets the Nepotism bonus - is there some way to write the constructors to allow overriding/nesting the base class like this:
Employee Bill = new Volunteer(new Nepotism());
I'm thinking something like:
public class Volunteer : Employee {
private Employee _nest;
public Volunteer(Employee nest)
: base() {
_nest = nest;
// now what?
}
}
Basically I want some objects to have the overrides from both classes.
I would like to avoid writing the override methods to check for nested classes.
getSalary() {
return (nest != null) ? nest.salary : salary; // I want to avoid this if I can
}
How can I do this? Am I on the right track? Am I off the rails?
Instead of subclassing, you might want to consider using the Decorator Pattern.
It provides an alternative to subclassing, and it useful when you may need to add "multiple" pieces of additional functionality to a single instance of a class, which is exactly the scenario.
I think you are trying to use inheritance in an ill-advised way. This approach creates a mess of dependences and oddball business rules, which results in a rigid architecture that is hard to use and maintain.
If calculating an employees salary is dependent upon the Employee as well as "bonus traits", then it would be better to separate all three things from each other:
interface IBonusTrait
{
decimal ApplyBonus(Employee employee, decimal currentTotal);
}
class Employee
{
// ...
public decimal BaseSalary { get; set; }
public IList<IBonusTrait> BonusTraits { get; set; }
}
class SalaryCalculator
{
public decimal CalculateSalary(Employee employee)
{
decimal totalSalary = employee.BaseSalary;
foreach (IBonusTrait bonusTrait in employee.BonusTraits)
{
totalSalary = bonusTrait.ApplyBonus(employee, totalSalary);
}
return totalSalary;
}
}
If an object can be both classes at once, then you may need to rethink how you're doing your inheritance.
It seems to me that if a Volunteer can sometimes get a Nepotism bonus, then really, your Volunteer class should have a getBonus() method, and this method really belongs in the base class. It would return zero for most volunteers, but occasionally it wouldn't - there's nothing wrong with that.
Reed Copsey already said, that Decorator Pattern is something to consider.
There is also this youtube video which is very similar to your case (John Skeet is presenting it).