Type conversion when iterating over a collection of super-type. Alternatives? - oop

This is quite a common problem I run into. Let's hear your solutions. I'm going to use an Employee-managing application as an example:-
We've got some entity classes, some of which implement a particular interface.
public interface IEmployee { ... }
public interface IRecievesBonus { int Amount { get; } }
public class Manager : IEmployee, IRecievesBonus { ... }
public class Grunt : IEmployee /* This company sucks! */ { ... }
We've got a collection of Employees that we can iterate over. We need to grab all the objects that implement IRecievesBonus and pay the bonus.
The naive implementation goes something along the lines of:-
foreach(Employee employee in employees)
{
IRecievesBonus bonusReciever = employee as IRecievesBonus;
if(bonusReciever != null)
{
PayBonus(bonusReciever);
}
}
or alternately in C#:-
foreach(IRecievesBonus bonusReciever in employees.OfType<IRecievesBonus>())
{
PayBonus(bonusReciever);
}
We cannot modify the IEmployee interface to include details of the child type as we don't want to pollute the super-type with details that only the sub-type cares about.
We do not have an existing collection of only the subtype.
We cannot use the Visitor pattern because the element types are not stable. Also, we might have a type which implements both IRecievesBonus and IDrinksTea. Its Accept method would contain an ambiguous call to visitor.Visit(this).
Often we're forced down this route because we can't modify the super-type, nor the collection e.g. in .NET we may need to find all the Buttons on this Form via the child Controls collection. We may need to do something to the child types that depends on some aspect of the child type (e.g. the bonus amount in the example above).
Strikes me as odd that there isn't an "accepted" way to do this, given how often it comes up.
1) Is the type conversion worth avoiding?
2) Are there any alternatives I haven't thought of?
EDIT
Péter Török suggests composing Employee and pushing the type conversion further down the object tree:-
public interface IEmployee
{
public IList<IEmployeeProperty> Properties { get; }
}
public interface IEmployeeProperty { ... }
public class DrinksTeaProperty : IEmployeeProperty
{
int Sugars { get; set; }
bool Milk { get; set; }
}
foreach (IEmployee employee in employees)
{
foreach (IEmployeeProperty property in employee.Propeties)
{
// Handle duplicate properties if you need to.
// Since this is just an example, we'll just
// let the greedy ones have two cups of tea.
DrinksTeaProperty tea = property as DrinksTeaProperty;
if (tea != null)
{
MakeTea(tea.Sugers, tea.Milk);
}
}
}
In this example it's definitely worth pushing these traits out of the Employee type - particularly because some managers might drink tea and some might not - but we still have the same underlying problem of the type conversion.
Is it the case that it's "ok" so long as we do it at the right level? Or are we just moving the problem around?
The holy grail would be a variant on the Visitor pattern where:-
You can add element members without modifying all the visitors
Visitors should only visit types they're interested in visiting
The visitor can visit the member based on an interface type
Elements might implement multiple interfaces which are visited by different visitors
Doesn't involve casting or reflection
but I appreciate that's probably unrealistic.

I would definitely try to resolve this with composition instead of inheritance, by associating the needed properties/traits to Employee, instead of subclassing it.
I can give an example partly in Java, I think it's close enough to your language (C#) to be useful.
public enum EmployeeProperty {
RECEIVES_BONUS,
DRINKS_TEA,
...
}
public class Employee {
Set<EmployeeProperty> properties;
// methods to add/remove/query properties
...
}
And the modified loop would look like this:
foreach(Employee employee in employees) {
if (employee.getProperties().contains(EmployeeProperty.RECEIVES_BONUS)) {
PayBonus(employee);
}
}
This solution is much more flexible than subclassing:
it can trivially handle any combination of employee properties, while with subclassing you would experience a combinatorial explosion of subclasses as the number of properties grow,
it trivially allows you to change Employee properties runtime, while with subclassing this would require changing the concrete class of your object!
In Java, enums can have properties or (even virtual) methods themselves - I don't know whether this is possible in C#, but in the worst case, if you need more complex properties, you can implement them with a class hierarchy. (Even in this case, you are not back to square one, since you have an extra level of indirection which gives you the flexibility described above.)
Update
You are right that in the most general case (discussed in the last sentence above) the type conversion problem is not resolved, just pushed one level down on the object graph.
In general, I don't know a really satisfying solution to this problem. The typical way to handle it is using polymorphism: pull up the common interface and manipulate the objects via that, thus eliminating the need for downcasts. However, in cases when the objects in question do not have a common interface, what to do? It may help to realize that in these cases the design does not reflect reality well: practically, we created a marker interface solely to enable us to put a bunch of distinct objects into a common collection, but there is no semantical relationship between the objects.
So I believe in these cases the awkwardness of downcasts is a signal that there may be a deeper problem with our design.

You could implement a custom iterator that only iterates over the IRecievesBonus types.

Related

Strategy Pattern and Open-Closed Principle Conflict

I was reading through strategy pattern and was trying to implement it but I have got stuck at deciding the strategy implementation which I feel violates the open-closed principle.
In strategy pattern we code to interface and based on client interaction we will pass in the strategy implementation.
Now if we have bunch of strategies so we need to decide using conditions which strategy the client chooses something like
IStrategy str;
if(stragety1) {
str = new Strategy1()
} else if (stragety2) {
str = new Strategy2()
} and so on..
str.run()
Now as per open-closed principle the above is open to extension but it is not closed to modification
If I need to add another strategy(extension) in future I do need to alter this code.
is there a way where this could be avoided or it is how we need to implement strategy pattern ?
1) You must separate selecting/creating a concrete strategy from its uses. I. e. use function selectStrategy, pass it as (constructor) parameter, etc.
2) There is no way to fully avoid conditional creation, but you can hide it (e. g. using some dictionary for mapping state=>strategy) and/or shift it into another level of the application. The last approach is very powerful and flexible, but depends on the task. In some cases you may put selecting/creating on the same level that uses it. In other cases you may even end up with delegation selecting/creating to the highest/lowest level.
2.1) You can use the Registry pattern and kinda avoid modification of "core" object when adding new strategy's.
This is indeed not closed to modification, but that is due to the way you initialize. You are using a value (enum?) to determine which Strategy subclass should be used. As #bpjoshi points out their comment, this is more of a Factory pattern.
Wikipedia discusses how a Strategy pattern can support the Open/Closed Principle, instead of hampering it.
In that example, they use a Car class with a Brake Strategy. Some cars brake with ABS, some don't. Different Car subclasses and instances can be given different Strategies for braking.
To get your code closed for modification, you need to select the Strategies differently. You want to select the Strategy in the place where new behavior or subclass is defined. You'd have to refactor your code so that the specific Strategy subclass is applied at the point where the code is extended.
I think, there is misunderstanding about Closed for Modifications.
In 1988, Mayer said:
Software that works should when possible not be changed when your application is extended with new functionality.
and Rober C. Matrin said:
This definition is obviously dated.
Think about that very carefully. If the behaviors of all the modules in your system could be extended, without modifying them, then you could add new features to that system without modifying any old code. The features would be added solely by writing new code.
https://8thlight.com/blog/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html
Adding some new codes without modifying old codes do not conflict with Open-Closed Principle.
I think the decision you are referring to should be the responsibility of a factory class. The following is some example code:
public interface ISalary
{
decimal Calculate();
}
public class ManagerSalary : ISalary
{
public decimal Calculate()
{
return 0;
}
}
public class AdminSalary : ISalary
{
public decimal Calculate()
{
return 0;
}
}
public class Employee
{
private ISalary salary;
public Employee(ISalary salary)
{
this.salary = salary;
}
public string Name { get; set; }
public decimal CalculateSalary()
{
return this.salary.Calculate();
}
}
The Employee class uses the Strategy pattern and follows the Open/Closed principle, i.e. it is open to new strategy types (ISalary implementations) through injection via the constructor, but closed to modification.
The piece that is missing is the code that creates the Employee objects, something like:
public enum EmployeeType
{
Manager,
Admin
}
public class EmployeeFactory
{
public Employee CreateEmployee(EmployeeType type)
{
if (type == EmployeeType.Manager)
return new Employee(new ManagerSalary());
else if (type == EmployeeType.Admin)
return new Employee(new AdminSalary());
etc
}
}
This is a very simple factory pattern. There are better ways to do this but this is the simplest way to explain the concept.

NullObject Pattern: How to handle fields?

Suppose we have Book class which contains year_published public field. If I want to implement NullObject design pattern, I will need to define NullBook class which behaves same as Book but does not do anything.
Question is, what should be the behavior of NullBook when it's fields are being assigned?
Book book = find_book(id_value); //this method returns a NullBook instance because it cannot find the book
book.year_published = 2016; //What should we do here?!
The first thing you should do is to make your properties private.
class NullBook {
private year_published;
// OR solution2 private year_published = null;
public setYearPublished(year_published) {
this.year_published = null;
// OR solution2 do nothing!
}
}
You can also define the field private in the parent class, so the children will have to implement the setter to acces the field
class Book {
private year_published;
public setYearPublished(year_published) {
this.year_published = year_published;
}
}
class NullBook extends Book {
public setYearPublished(year_published) {
parent::setYearPublished(null);
}
}
Why use getters and setters?
https://stackoverflow.com/a/1568230/2377164
Thing is: patterns are about balancing. Yes, it is in general good practice to not return null, but to having else to return; but well: what is returned should still make sense!
And to a certain degree, I don't see how having a "NullBook" really helps with the design of your application. Especially as you allow access to various internal fields. You exactly asked the correct question: what should be the published year, or author, or ... of such a "NullBook"?!
What happens for example when some piece of code does a "lookup" on books from different "sources"; and then tries to sort those books on the published year. You sure don't want your NullBook to ever be part of such data.
Thus I fail to see the value in having this class, to the contrary: I see it creating a potential for "interesting" bugs; thus my answer is: step back and re-consider if you really need that class.
There are alternatives to null-replacing objects: maybe your language allows for Optionals; or, you rework those methods that could return null ... to return a collection/array of books; and in doubt: that list/array is simply empty.
Long story short: allowing other classes direct access to private fields is a much more of an import design smell; so you shouldn't be too focused on NullObjects, while giving up on such essential things as Information Hiding so easily on the other hand.

Propagating changes in one child object to another

I have came across several cases where I have a parent object with multiple objects, and where changes to information in one child object affects others.
For example, consider the following case:
interface IUniverse
{
IStorage ShirtStorage;
IList<IHuman> Humans;
}
Interface IStorage:
{
string Location;
int Capacity;
IList<IShirt> Items;
}
Interface IHuman
{
string Name;
int Age;
IList<IShirt> Shirts;
}
I would like to remove a particular shirt from ShirtStorage in my universe, but at the same time, since the shirt is removed from existence, it should be removed from all humans as well.
I have thought of 3 ways to do this:
Firstly, we can introduce Add(IClothing) and Remove(IClothing) methods to IStorage<T> and IHuman.
interface IUniverse
{
IStorage ShirtStorage;
IList<IHuman> Humans;
}
Interface IStorage
{
string Location;
int Capacity;
IList<IShirt> Items;
**void Add(IShirt);**
**void Remove(IShirt);**
}
Interface IHuman
{
string Name;
int Age;
IList<IShirt> Shirts;
**void AddShirts(IShirt);**
**void RemoveShirts(IShirts);**
}
Afterwards, the implementations of above interfaces will not have anything under the hood which removes a particular shirt from all humans when it is removed from ShirtStorage.
The disadvantage of this design is that each time a programmer removes a shirt from the universe, he will have to manually remove every single reference from each human.
That is to say, the programmer has to know the exact structure of the universe in order to remove a single shirt. In the event where the structure of the universe becomes highly complex, such that references to a particular shirt may appear more than just in IHuman, this may prove to be erroneous and tedious.
Secondly, we similarly introduce Add(IShirt) and Remove(IShirt) methods to the interfaces IStorage and IHuman:
interface IUniverse
{
IStorage<IShirt> ShirtStorage;
IList<IHuman> Humans;
}
Interface IStorage
{
string Location;
int Capacity;
IList<IShirt> Items;
**void Add(IShirt);**
**void Remove(IShirt);**
}
Interface IHuman
{
string Name;
int Age;
IList<ICShirt> Shirts;
**void AddShirt(IShirt);**
**void RemoveShirt(IShirt);**
}
.. however this time round, we use an implementation of the above interfaces such that there is some notification going on under the hood. That is to say,
class Storage : IStorage
{
IUniverse parentUniverse;
string Location;
int Capacity;
IList<IShirt> Items;
// ... Implementation for Add(IShirt item) is trivial
void Remove(IShirt item)
{
this.Items.Add(item);
foreach (IHuman human in this.parentUniverse)
foreach(IClothing clothing in human.Clothings)
if (clothing == item)
human.RemoveClothing(clothing);
}
}
Indeed, by placing all the notification in the implementation of the interface, consumers of the interface will not have to go through every single possible reference to a particular IShirt when he wants to remove it from existence, thus making it better in this sense as compared to the previous solution.
However, the disadvantage is that such a design inherently leads to pathological lying, and violates the Single Responsibility Principle as well. If the programmer calls Remove(IShirt) on ShirtStorage, he wouldn't be aware of what reference is being removed from where.
If said programmer wishes to write a GUI using the Mediator pattern for example, he would be unsure of which notification message to send out.
Which humans exactly have shirts removed from them, thereby requiring an update on the GUI for some component which reflects the list of shirts belonging to a particular human? What if I have a Catalog class with names of all the shirts - wouldn't the entry corresponding to removed shirt be removed as well (under the hood)? Would I also have to update the corresponding GUI component for my catalogs?
Thirdly, we introduce the Add(IShirt) and Remove(IShirt) methods to IUniverse instead:
interface IUniverse
{
IStorage ShirtStorage;
IList<IHuman> Humans;
void Add(IShirt);
void Remove(IShirt);
}
Interface IStorage:
{
string Location;
int Capacity;
IList<IShirt> Items;
}
Interface IHuman
{
string Name;
int Age;
IList<IShirt> Shirts;
}
By doing so, we force consumers of the interface to accept that removing a shirt affects not just the shirt storage, but other members of IUniverse as well.
However, the disadvantages are like those in the second solution. On top of that, IUniverse instances eventually become somewhat of a God Object. Every place where I need to remove a shirt from a universe, I have to have a reference to the universe.
If a particular GUI component simply wants to display information for a ShirtStorage and to allow for interaction with the storage (i.e. adding and removing of shirts), wouldn't this introduce some coupling between the GUI component and the Universe, when the only coupling that should exists is that of the GUI component and IStorage?
I have wrote several applications which have used a mix of all three solutions. Indeed some solutions seem better than others in different cases, but the inconsistencies are a pain because I almost always forgot to do certain things when switching from one design to another.
Every time I hear the phrase "Propagating Changes" in the context of oop, I immediately think Observer pattern. So instead of giving the responsibility to your domain objects to "synchronize" adding and removing shirts, I would introduce another class that takes over this responsibility, and have your domain objects raise relevant events. And you also keep adhering to the Single Responsibility Principle.
HTH

Business Entity - should lists be exposed only as ReadOnlyCollections?

In trying to centralize how items are added, or removed from my business entity classes, I have moved to the model where all lists are only exposed as ReadOnlyCollections and I provide Add and Remove methods to manipulate the objects in the list.
Here is an example:
public class Course
{
public string Name{get; set;}
}
public class Student
{
private List<Course>_courses = new List<Course>();
public string Name{get; set;}
public ReadOnlyCollection<Course> Courses {
get{ return _courses.AsReadOnly();}
}
public void Add(Course course)
{
if (course != null && _courses.Count <= 3)
{
_courses.Add(course);
}
}
public bool Remove(Course course)
{
bool removed = false;
if (course != null && _courses.Count <= 3)
{
removed = _courses.Remove(course);
}
return removed;
}
}
Part of my objective in doing the above is to not end up with an Anemic data-model (an anti-pattern) and also avoid having the logic that adds and removes courses all over the place.
Some background: the application I am working with is an Asp.net application, where the lists used to be exposed as a list previously, which resulted in all kinds of ways in which Courses were added to the Student (some places a check was made and others the check was not made).
But my question is: is the above a good idea?
Yes, this is a good approach, in my opinion you're not doing anything than decorating your list, and its better than implementing your own IList (as you save many lines of code, even though you lose the more elegant way to iterate through your Course objects).
You may consider receiving a validation strategy object, as in the future you might have a new requirement, for ex: a new kind of student that can have more than 3 courses, etc
I'd say this is a good idea when adding/removing needs to be controlled in the manner you suggest, such as for business rule validation. Otherwise, as you know from previous code, there's really no way to ensure that the validation is performed.
The balance that you'll probably want to reach, however, is when to do this and when not to. Doing this for every collection of every kind seems like overkill. However, if you don't do this and then later need to add this kind of gate-keeping code then it would be a breaking change for the class, which may or may not be a headache at the time.
I suppose another approach could be to have a custom descendant of IList<T> which has generic gate-keeping code for its Add() and Remove() methods which notifies the system of what's happening. Something like exposing an event which is raised before the internal logic of those methods is called. Then the Student class would supply a delegate or something (sorry for being vague, I'm very coded-out today) when instantiating _courses to apply business logic to the event and cancel the operation (throw an exception, I imagine) if the business validation fails.
That could be overkill as well, depending on the developer's disposition. But at least with something a little more engineered like this you get a single generic implementation for everything with the option to add/remove business validation as needed over time without breaking changes.
I've done that in the past and regretted it: a better option is to use different classes to read domain objects than the ones you use to modify them.
For example, use a behavior-rich Student domain class that jealously guards its ownership of courses - it shouldn't expose them at all if student is responsible for them - and a StudentDataTransferObject (or ViewModel) that provides a simple list of strings of courses (or a dictionary when you need IDs) for populating interfaces.

Is this a ddd anti-pattern?

Is it a violation of the Persistance igorance to inject a repository interface into a Entity object Like this. By not using a interface I clearly see a problem but when using a interface is there really a problem? Is the code below a good or bad pattern and why?
public class Contact
{
private readonly IAddressRepository _addressRepository;
public Contact(IAddressRepository addressRepository)
{
_addressRepository = addressRepository;
}
private IEnumerable<Address> _addressBook;
public IEnumerable<Address> AddressBook
{
get
{
if(_addressBook == null)
{
_addressBook = _addressRepository.GetAddresses(this.Id);
}
return _addressBook;
}
}
}
It's not exactly a good idea, but it may be ok for some limited scenarios. I'm a little confused by your model, as I have a hard time believing that Address is your aggregate root, and therefore it wouldn't be ordinary to have a full-blown address repository. Based on your example, you probably are actually using a table data gateway or dao rather than a respository.
I prefer to use a data mapper to solve this problem (an ORM or similar solution). Basically, I would take advantage of my ORM to treat address-book as a lazy loaded property of the aggregate root, "Contact". This has the advantage that your changes can be saved as long as the entity is bound to a session.
If I weren't using an ORM, I'd still prefer that the concrete Contact repository implementation set the property of the AddressBook backing store (list, or whatever). I might have the repository set that enumeration to a proxy object that does know about the other data store, and loads it on demand.
You can inject the load function from outside. The new Lazy<T> type in .NET 4.0 comes in handy for that:
public Contact(Lazy<IEnumerable<Address>> addressBook)
{
_addressBook = addressBook;
}
private Lazy<IEnumerable<Address>> _addressBook;
public IEnumerable<Address> AddressBook
{
get { return this._addressBook.Value; }
}
Also note that IEnumerable<T>s might be intrinsically lazy anyhow when you get them from a query provider. But for any other type you can use the Lazy<T>.
Normally when you follow DDD you always operate with the whole aggregate. The repository always returns you a fully loaded aggregate root.
It doesn't make much sense (in DDD at least) to write code as in your example. A Contact aggregate will always contain all the addresses (if it needs them for its behavior, which I doubt to be honest).
So typically ContactRepository supposes to construct you the whole Contact aggregate where Address is an entity or, most likely, a value object inside this aggregate.
Because Address is an entity/value object that belongs to (and therefore managed by) Contact aggregate it will not have its own repository as you are not suppose to manage entities that belong to an aggregate outside this aggregate.
Resume: always load the whole Contact and call its behavior method to do something with its state.
Since its been 2 years since I asked the question and the question somewhat misunderstood I will try to answer it myself.
Rephrased question:
"Should Business entity classes be fully persistance ignorant?"
I think entity classes should be fully persistance ignorant, because you will instanciate them many places in your code base so it will quickly become messy to always have to inject the Repository class into the entity constructor, neither does it look very clean. This becomes even more evident if you are in need of injecting several repositories. Therefore I always use a separate handler/service class to do the persistance jobs for the entities. These classes are instanciated far less frequently and you usually have more control over where and when this happens. Entity classes are kept as lightweight as possible.
I now always have 1 Repository pr aggregate root and if I have need for some extra business logic when entities are fetched from repositories I usually create 1 ServiceClass for the aggregate root.
By taking a tweaked example of the code in the question as it was a bad example I would do it like this now:
Instead of:
public class Contact
{
private readonly IContactRepository _contactRepository;
public Contact(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
public void Save()
{
_contactRepository.Save(this);
}
}
I do it like this:
public class Contact
{
}
public class ContactService
{
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
public void Save(Contact contact)
{
_contactRepository.Save(contact);
}
}