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).
Related
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.
Every time I talk to experienced programmers, they talk about having global variables being a bad practice because of debugging or security exploits. I have a simple List of strings I want to load from a a textfile and access across different methods in my form. Before, I would simply initialize said variable at the top, inside of my form class and use it across methods. I always try to reduce that practice when I can and only initialize those variables when I really need them. Is it a bad practice to do this or do more experienced programmers do this too? Is there a standard design pattern method of doing this so you don't have to use "global variables" at the top of your form?
As you're talking about C# and it's a fully-object-oriented programming language, there's no way to declare global variables.
In an OOP language like C#, a bad practice can be simulating global variables using static classes:
public static class Global
{
public static string Value1 { get; set; }
public static int Value2 { get; set; }
}
...to later get or set these values from other classes. Definitely, this a bad practice because state should be held by specific and meaningful objects.
Usually, in a perfect/ideal OOP solution, you should pass such values from class to class using constructors:
public class X
{
public int Value1 { get; set; }
public void DoStuff()
{
Y y = new Y(this);
y.DoChildStuff();
}
}
public class Y
{
public class Y(X parent)
{
Parent = parent;
}
public X Parent { get; }
public void DoChildStuff()
{
// Do some stuff with Parent
}
}
Or also, you might pass states providing arguments to some method:
public class Y
{
public void DoChildStuff(X parent)
{
// Do some stuff with "parent"
}
}
Since you're passing states with reference types, if any of the methods in the chain decide to change Parent.Value1 with another value, all objects holding a reference to the same X object will get the new X.Value1.
Some fellows might argue that we usually build configuration objects which own a lot of properties accessed by other arbitrary objects, right? BTW, configuration is a concept per se, isn't it? And we usually categorize configuration values using composition:
public class ApplicationConfiguration
{
public DatabaseConfiguration Database { get; } = new DatabaseConfiguration();
public StorageConfiguration Storage { get; } = new StorageConfiguration();
}
public class DatabaseConfiguration
{
public string ConnectionString { get; set; }
}
public class StorageConfiguration
{
public string TemporalFileDirectoryPath { get; set; }
public string BinaryDirectoryPath { get; set; }
}
So later we inject the application configuration wherever we need it:
// Please note that it's a VERY hypothetical example, don't take
// it as an actual advise on how to implement a data mapper!!
public class DataMapper
{
public DataMapper(ApplicationConfiguration appConfig)
{
AppConfig = appConfig;
}
public ApplicationConfiguration AppConfig { get; }
private IDbConnection Connection { get; }
public void Connect()
{
// We access the configured connection string
// from the application configuration object
Connection = new SqlConnection(AppConfig.Database.ConnectionString);
Connection.Open();
}
}
In summary, and since I love comparing real-world and programming use cases, imagine that you never clean your room and you would use a single box to store every tool you might need some day. One day you need a screwdriver from the whole box, and you know that's inside it... But you need to throw everything in the box to the ground and work out the mess prior to find the priceless screwdriver to complete some home task.
Or imagine that you've bought a toolbox to store your tools in order, and once you need a screwdriver, you know that's in the toolbox and in the section where you store your screwdrivers.
You know that the second approach is the most mind-friendly. That is, when you develop software, you need to design mind-friendly architectures rather than a big mess of unrelated data and behaviors working together.
Given the following scenario with a base class like this:
internal class ResolveVariableStrategyBase
{
...
protected static EntityFieldVariable EntityFieldVariable { get; private set; }
protected static EntityPropertyLoader EntityPropertyLoader { get; private set; }
protected static FunctionInvoker FunctionInvoker { get; private set; }
protected static string Variable { get; private set; }
protected static object EntityValue { get; private set; }
protected static object VariableValue { get; set; }
...
protected ResolveVariableStrategyBase() { }
internal ResolveVariableStrategyBase(
EntityFieldVariable entityFieldVariable,
EntityPropertyLoader propertyLoader,
FunctionInvoker functionInvoker,
string variable,
object entityValue,
object variableValue)
{ ... }
internal virtual object Execute() { ... }
}
And several derived classes like this:
internal sealed class RelationStrategy : ResolveVariableStrategyBase
{
internal override object Execute()
{
var result = resolveRelation();
base.VariableValue = result;
return resolveRelation();
}
...
}
is it really a good idea to
have static properties in base class to spare writing the same (internal) constructor we have for the base class for all the derived classes with all the parameters setting the fields of the base class like so:
internal RelationStrategy(
EntityFieldVariable entityFieldVariable,
EntityPropertyLoader propertyLoader,
FunctionInvoker functionInvoker,
string variable,
object entityValue,
object variableValue) : base (entityFieldVariable,propertyLoader,functionInvoker,variable,entityValue,variableValue)
or is this just laziness prioritized over well designed code?
What is an optimal solution?
The problem with this is that static variables are shared across instances and across threads. This is very error prone because you have to ensure the global invariant that no two such classes may be instantiated at the same time. Also, recursive instantiations are no longer possible (arguably a more contrived scenario).
Upholding global invariants like that in a big codebase is tedious and error prone.
I usually generate the constructor delegating to the base constructor with Resharper. Alt+Ins, Up, Space, Enter is, I think, the key sequence to fully generate all of that code.
Maybe you can pack all those values into a DTO class so that they are easier to pass around. Resharper has great support for managing DTO classes. It can generate the constructor and initialize properties with existing constructors.
In any case I would fail that code in a code review.
I want my site to support different subscription types, free, premium and etc.
So far I made an abstract class that is like this
public abstract class Limits
{
public int PostLimit { get; protected set; }
protected Limits(int postLimit)
{
PostLimit = postLimit;
}
public bool IsLimitReached(int postCount)
{
return postCount > PostLimit
}
}
public class FreeLimit : Limits
{
private const int postLimit = 1;
public FreeLimit()
: base(postLimit)
{
}
}
So now I did this for all my account types. Now the problem is I don't know how to actually use this class.
For instance I have a service layer call PostService and in this class I have
public void CreatePost(Post post)
{
// do stuff here
}
Now in this method I don't know how to check if they reached the limit. I don't know how to check because I am unsure how to find out if I should be using the FreeLimit or PremiumLimit or what account they have.
I am thinking that I first have to figure out their Role and then somehow use that information to create the right class.
I guess I could have something like
public void CreatePost(Post post, PlanType planType)
{
Limits limit;
switch(planType)
{
case planType.Free:
limit = new FreeLmit()
break;
}
if(limit.IsLimitReached())
{
// do stuff
}
}
I don't like this way as now for every method that needs to check a limit will have to do this. I will have a few methods that require this check in my service layer.
So I was thinking of putting it in my constructor but I don't know if it is good to have a switch statement in a constructor.
You could use an interface ILimit
interface ILimit
{
int PostLimit { get; protected set; }
bool IsLimitReached(int postCount);
}
Now you can have several other classes (Free, Premium, Super) that implement this interface. In your service method CreatePost you can just pass any instance of a class that implements the interface and use it - there's no need to distinguish them anymore since they all support the same interface.
public void CreatePost(Post post, ILimit limit)
{
if(limit.IsLimitReached())
{
// do stuff
}
}
Well, the Limit property is tied to what entity? I suppose it's tied to the Blog (or maybe a Forum) and it is persisted on a DB or something else.
If so, you can do something like this:
public void CreatePost(Post post)
{
if(post.Blog.IsLimitReached())
{
// do stuff
}
}
The Blog.IsPostLimitReached() should call this.Limit.IsLimitReached from itself.
I hope you can understand what I said :)
If you have different types of user, you can tie their accounts (once they've logged in) to different RoleTypes. Then you can use HttpContext.Current.User.IsInRole("RoleName") to see if they are in a specific role, and use that as your basis for showing/hiding functionality.
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).