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.
Related
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 a company entity
public class Company : Entity<Company>
{
public CompanyIdentifier Id { get; private set; }
public string Name { get; private set; }
..............
..........
}
A company can be a agent or supplier or both or none. (There are more types) Its behaviour should be change based on types. Agent can get commission and supplier is able to invoice.
What will be the best way to design the entity or entities or value objects? I have an option to add some boolean types and check those values inside methods,
public class Company : Entity<Company>
{
public CompanyIdentifier Id { get; private set; }
public string Name { get; private set; }
public bool IsAgent { get; private set; }
public bool IsSupplier { get; private set; }
..........
public void Invoice()
{
if(!IsSupplier)
{
throw exception.....;
}
//do something
}
public void GetCommission(int month)
{
if(!IsAgent)
{
throw exception.....;
}
//do something
}
..........
}
To be honest, I do not like this. Is there any design pattern which might help to overcome this scenerio? What will you do and why to design this scenerio?
Implement interfaces explicitly, then override the cast operator to only cast to that interface when valid.
public class Company : ...., IAgentCompany, ISupplierCompany ... {
public double IAgentCompany.GetCommission(int month) {
/*do stuff */
}
public static explicit operator IAgentCompany(Company c) {
if(!c.IsAgent)
throw new InvalidOperationException();
return this;
}
}
Explicit implementations of interfaces must be called through their interface, not the concrete type:
// Will not compile
new Company().GetCommission(5);
// Will compile
((IAgentCompany)new Company()).GetCommission(5)
But, now we've overloaded the explicit cast operator. So what does that mean? We can't call GetCommission without casting to IAgentCompany, and now we have a guard to prevent that cast for a company that isn't marked as an agent.
Good things about this approach:
1) You have interfaces that define the aspects of different types of companies and what they can do. Interface segregation is a good thing, and makes the abilities/responsibilities of each type of company clear.
2) You've eliminated a check for every function you want to call that is not "global" to all companies. You do one check when you cast, and then as long as you have it in a variable typed as the interface, you can happily interact with it without any further checking. This means less places to introduce bugs, and less useless checks.
3) You are leveraging the languages features, and exploiting the type system to help make the code more bullet-proof.
4) You don't have to write tons of subclasses that implement the various combinations of interfaces (possibly 2^n subclasses!) with NotImplementedExceptions or InvalidOperationException everywhere in your code.
5) You don't have to use an enum or a "Type" field, especially when you are asking to mix and match these sets of abilities (you'd don't just need an enum, but a flag enum). Use the type system to represent different types and behaviors, not an enum.
6) It's DRY.
Bad things about this approach:
1) Explicit interface implementations and overriding explicit cast operators aren't exactly bread and butter C# coding knowledge, and may be confusing to those who come after you.
Edit:
Well, I answered too quickly without testing the idea, and this doesn't work for interfaces. However, see my other answer for another idea.
I would look into separating the implementation for all those types in different classes. You could start doing this by using an enum to represent the company type.
public enum CompanyType
{
Agent = 0,
Supplier
}
public abstract class Company : Entity<Company>
{
public CompanyIdentifier Id { get; private set; }
public string Name { get; private set; }
public CompanyType EntityType { get; private set; }
public abstract void Invoice();
public abstract void GetCommission(int month);
...
This way you get less public properties.
Next, I'd implement specialized classes for supplier and agent (and then for both and none). You can make Company abstract and any specialized methods abstract as well.
This will allow you to separate the distinct behaviors of each type of entity. Comes in handy when you get back to it for maintenance. It also makes the code easier read/understand.
public class SupplierCompany : Company
{
public SupplierCompany()
{
EntityType = CompanyType.Supplier;
}
public override void Invoice()
{...}
public override void GetComission(int month)
{...}
}
public class AgentCompany : Company
{
public AgentCompany()
{
EntityType = EntityType.Agent;
}
public override void Invoice()
{...}
public override void GetComission(int month)
{...}
}
With this you can eliminate testing for various types in methods like Invoice and GetComission.
As with most DDD questions, it usually boils down to Bounded Contexts. I'd guess you're dealing with some distinct bounded contexts here (this is most obvious from your statement "A company can be a agent or supplier or both or none."). In at least one context you need to consider all Company entities equally, regardless of whether they are Agents or Suppliers. However I think you need to think about whether or not your Invoice or GetCommission operations are applicable in this broader context? I'd say those will apply in more specialized contexts, where the distinction between an Agent and a Supplier is much more crucial.
You may be running into trouble because you're trying to create an all encompassing Company entity which is applicable in all contexts... this is almost impossible to achieve without weird code constructs & fighting against the type system (as is being suggested in your other answers).
Please read http://martinfowler.com/bliki/BoundedContext.html
As a rough idea of how your contexts might look:
Broad "Company" Context
{
Entity Company
{
ID : CompanyIdentifier
Name : String
}
}
Specialized "Procurement" Context
{
Entity Supplier
{
ID : CompanyIdentifier
Name : String
Invoice()
}
}
Specialized "Sales" Context
{
Entity Agent
{
ID : CompanyIdentifier
Name : String
GetComission()
}
}
Does it make sense to try and use the same object in both Procurement and Sales contexts? These contexts have very different requirements after all. One of the lessons of DDD is that we split the domain into these bounded contexts, and do no try to make "God" objects which can do everything.
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.
I have a set of DataContracts that are serialzed through WCF.
Please note this is a very simplified example.
[DataContract]
public class MyData
{
[DataMember]
public List<int> MyList
{
get;
set;
}
}
I would like to use object oriented design so that the server and client aren't creating any unnecessary dependencies. For example, I would like to encapsulate a list so that the user can't directly modify it.
Ideally, I would like the class to look like this if it wasn't a DTO.
public class MyData
{
private List<int> _list = new List<int>();
public IEnumerable<int> MyList
{
get
{
return _list;
}
}
public void AddItem( int value )
{
_list.Add( value );
}
}
I am using the same C# assembly from both the service and the client. So I can add non-DataMember methods, but I'm not sure if that is a good approach. It doesn't smell quite right to me.
Does anybody have a clever way of treating DTO classes more like objects instead of simple serializable structures?
How about having DTO versions of your logic class which are used solely for the purpose of message passing?
That way, you can put all the methods and properties on your logic class as necessary without having to worry about what the user has access to when it's passed over the wire. There are many ways you can go about this, for instance:
you can implement some method on your logic class to return the DTO
public class Player
{
// methods that do interesting things here
...
public string Name { get; set; }
public PlayerDTO ToTransport()
{
return new PlayerDTO { Name = Name, ... };
}
}
[DataContract]
public class PlayerDTO
{
[DataMember]
public string Name { get; set; }
...
}
Or you can implement an explicit/implicit conversion
public class Player
{
// methods that do interesting things here
...
public string Name { get; set; }
}
[DataContract]
public class PlayerDTO
{
[DataMember]
public string Name { get; set; }
...
public static explicit operator PlayerDTO(Player player)
{
return new PlayerDTO { Name = player.Name, ... };
}
}
this lets you cast a Player object to PlayerDTO:
var player = new Player { Name = .... };
var dto = (PlayerDTO) player;
Personally, I do think having DataContract on objects which are for more than service operations is a bit of a smell, just as it would be for ORM column mappings. One somewhat limited way to make these DTOs more like true OO is to have your methods be extension methods of the DTO. You might need to do something creative if the OO version has state that needs to be captured between calls that is not inherent in the DTO object itself, though.
I do not think having methods unadorned by attributes in your DataContract's class necessarily smells. You have your service-oriented concerns on one hand (the operation and data contracts) and your object-oriented concerns on the other. What the client does with the provided data is of no concern to the service. The object-oriented issue you describe really only exists for the client.
If a client obtained Ball data from your service and it wants to Draw() it to the screen, whether or not the Ball class has a Draw() method has nothing to do with the contract between service and client. It is a contract between the api your assembly provides and those that use it. So I say, why not have a method in the assembly that is not an operation/data contract?
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).