Say I have a class A
class A
{
Z source;
}
Now, the context tells me that 'Z' can be an instance of different classes (say, B and C) which doesn't share any common class in their inheritance tree.
I guess the naive approach is to make 'Z' an Interface class, and make classes B and C implement it.
But something still doesn't convince me because every time an instance of class A is used, I need to know the type of 'source'. So all finishes in multiple 'ifs' making 'is instanceof' which doesn't sound quite nice. Maybe in the future some other class implements Z, and having hardcoded 'ifs' of this type definitely could break something.
The escence of the problem is that I cannot resolve the issue by adding functions to Z, because the work done in each instance type of Z is different.
I hope someone can give me and advice, maybe about some useful design pattern.
Thanks
Edit: The work 'someone' does in some place when get some instance of A is totally different depending of the class behind the interface Z. That's the problem, the entity that does the 'important job' is not Z, is someone else that wants to know who is Z.
Edit2: Maybe a concrete example would help:
class Picture
{
Artist a;
}
interface Artist
{
}
class Human : Artist { }
class Robot : Artist {}
Now somewhere I have an instance of Picture,
Picture p = getPicture();
// Now is the moment that depending if the type of `p.a` different jobs are done
// it doesn't matter any data or logic inside Human or Robot
The point of using an interface is to hide these different implementations; A should just know the intent or high-level purpose of the method(s).
The work done by each implementation of Z may be different, but the method signature used to invoke that work can be the same. Class A can just call method Z.foo(), and depending on whether the implementation of Z is B or C, different code will be executed.
The only time you need to know the real implementation type is when you need to carry out completely unrelated processing on the two different types, and they don't share an interface. But in that case, why are they being processed by the same class A? Now, there are cases where this may make sense, such as when B and C are classes generated from XML Schemas, and you can't modify them - but generally it indicates that the design can be improved.
Updated now that you've added the Picture example. I think this confirms my point - although the implementation of getPicture() is different, the purpose and the return type are the same. In both cases, the Artist returns a Picture.
If the caller wants to treat Robot-created and Human-created pictures in the same way, then they use the Artist interface. They do not need to distinguish between Human or Robot, because they just want a picture! The details of how the picture is created belong in the subclass, and the caller should not see these details. If the caller cares about precisely how a picture is created, then the caller should paint it, not the Robot or Human, and the design would be quite different.
If your subclasses are performing totally unrelated tasks (and this is not what your Artist example shows!) then you might use a very vague interface such as the standard Java Runnable; in this case, the caller really has no idea what the run() method will do - it just knows how to run things that are Runnable.
Links
The following questions/articles suggest some alternatives to instanceof:
Avoiding instanceof in Java
Alternative to instanceof approach in this case
And the following articles also gives example code, using an example that seems similar to yours:
http://www.javapractices.com/topic/TopicAction.do?Id=31
and the following articles discuss the tradeoffs of instanceof versus other approaches such as the Visitor pattern and Acyclic Visitor:
https://sites.google.com/site/steveyegge2/when-polymorphism-fails
http://butunclebob.com/ArticleS.UncleBob.VisitorVersusInstanceOf
I think you need to post more information, because as it stands what I see is a misunderstanding of OOP principles. If you used a common interface type, then by Liskov substitution principle it shouldn't matter which type source is.
I'm gonna call your A, B, and C classes Alpha, Beta, and Gamma.
Perhaps Alpha can be split into two versions, one which uses Betas and one which uses Gammas. This would avoid the instanceof checks in Alpha, which as you've surmised are indeed a code smell.
abstract class Alpha
{
abstract void useSource();
}
class BetaAlpha extends Alpha
{
Beta source;
void useSource() { source.doSomeBetaThing(); }
}
class GammaAlpha extends Alpha
{
Gamma source;
void useSource() { source.doSomeGammaThing(); }
}
In fact this is extremely common. Consider a more concrete example of a Stream class that can use either Files or Sockets. And for the purpose of the example, File and Socket are not derived from any common base class. In fact they may not even be under our control, so we can't change them.
abstract class Stream
{
abstract void open();
abstract void close();
}
class FileStream extends Stream
{
File file;
void open() { file.open(); }
void close() { file.close(); }
}
class SocketStream extends Stream
{
Socket socket;
void open() { socket.connect(); }
void close() { socket.disconnect(); }
}
Related
Let's consider, as an example, the domain of GPS and Geographical (GIS) entities.
We would model the meaningful geographic entities (points, paths, regions) as classes in any desired programming language, and these classes would be a conceptual, "implementation-free" representation of these entities.
On the other hand, there are a lot of file formats that save these features with more or less the same meaning. In the GPS domain the most common file formats are GPX, KML, ShapeFile, WellKnownText, etc.
Supposing, then, I want to create a GpsFeatureCollection class which would contain a Points property, a Paths property, and so on. Also, I would implement classes like GpsReader, KmlReader, ShapeFileReader (and their respective Writers) and so on.
THE QUESTION IS:
Which is the best practice in OOAD:
Have a GpsFeatureCollection to instantiate a FileFormat(Reader/Writer) class?
Have a GpsFeatureCollection to implement Read/WriteFromFormat methods instead of classes?
Have each file format reader to instantiate an empty GpsFeatureCollection, populate it with data read from file, then pass the populated object as a return value?
Have a mediator class to avoid any dependency between FileFormatClass and ObjectModelClass?
None of the above?
"Well, it depends..."
I am really interested in doing "the right thing". My immediate plans are to use Python, but most probably this would matter for other languages too. This is causing some "analysis paralysis" in my pet project currently...
Here is my take wherein I pass reader and writer instances to read() and write() methods, this seems to achieve good level of decoupling and yet provides flexibility to pick various readers and writers.
Code uses Java-like syntax
Declare a Reader interface, we will assuming multiple implementation such KMLReader,
ShapeFileReader, etc
interface Reader {
GpsFeatureCollection read();
}
Declare a Writer interface, we will assuming multiple implementation such KMLWriter, ShapeFileWriter, etc
interface Writer {
void write(GpsFeatureCollection c);
}
Let's declare GpsFeatureCollection class to have read and write methods which accept respective interfaces as parameter to perform the job.
class GpsFeatureCollection {
...
public static GpsFeatureCollection read(Reader r) {
return r.read();
}
public static void write(Writer w) {
w.write(this);
}
}
Some example of usage using different readers and writers.
// Reading data
GpsFeaureCollection data = GpsFeatureCollection.read(new ShapeFileReader("/tmp/shapefile"));
// Writing data
data.write(new KMLWriter("/tmp/kmlfile"));
I refer to it as the "delivery boy". I've seen several variants of it but the issue is that a class has dependency for the sole purpose of passing it on to collaborators and never using the dependency itself.
(I'm using PHP because it's what I'm most familiar with but this is language agnostic)
class Dependency{}
class B {
public function setDependency(Dependency $dependency) {
//...
}
}
class A {
private $b;
private $dependency;
public function __construct(Dependency $dependency, B $b) {
$this->dependency = $dependency;
$this->b = $b;
}
public function foo() {
$this->b->setDependency($this->dependency);
}
}
Probably the most common variant I see in the wild is abusing inheritance for this purpose, having a property in the parent class which exists so that the child classes have access to the dependency even if the parent class never actually uses the dependency itself.
class Dependency{}
class A {
protected $dependency;
public function __construct(Dependency $dependency) {
$this->dependency = $dependency;
}
}
class B extends A {
public function foo() {
$this->dependency->bar();
}
}
I see this in code far more than I'd like and it doesn't make me very happy! I just wondered if there was a name for this so that I can link people to reading materials on why it's a bad idea. As it stands, I don't know what to search for!
I'm not aware of any name, but I kind of like Delivery boy... though I suppose some might consider the name borderline offensive.
Typically this problem is solved with either Dependency Injection or a Service Locator, although way too many people use Singleton for this (inappropriately).
I'm not familiar enough with PHP to know if PHP offers a real DI solution (as opposed to poor man's DI), but I think a service locator would be acceptable if there isn't (even though service locator is often a code smell in itself).
The problem related to inheritance in the second snippet looks like to me "Broken Hierarchy". This smell occurs when the base class and its derived class do not share an IS-A relationship. It is very common to find code that uses inheritance just for convenience (for reuse) and not because it makes sense to have a hierarchy where the participating classes are are related (by IS-A relationship).
(I borrowed the smell terminology (i.e. Broken Hierarchy) from the book "Refactoring for software design smells")
Say I have a Car class:
class Car
{
string GetMake()
string GetModel()
int GetYear()
}
And I have a custom CarService class that holds a list of cars:
class CarService
{
void AddCar(Car car)
void RemoveCar(Car car)
List<Car> GetCars()
... other methods removed for clarity...
}
Now I want to load a list of cars from a file to the CarService class. My old OOP instinct would be to put this as a method like LoadFromFile() on the CarService class. However as I'm learning about SRP and testability now I'm not so sure.
Following the single responsibility principle, what is the correct way to design this? Should I have a CarLoader class?
UPDATE
I think the solution should be the same in a wide variety of languages but I'll be using C++. My question would be identical if I was using C#, Java, or python.
Depending on the language you're going to implement this in, I'd say either a load_carservice function or an equivalent static method would suffice.
The static method solution might be said to violate the SRP, because the serialization format might change while the rest of the class stays the same. This is one of the reasons why I never program in languages that force me to put everything in a class. If your language forces you to do this, and you want to adhere by SRP strictly, then an extra class would be called for.
You probably should not have a CarLoader class. At least based on what you've shown, your CarService class doesn't look very useful either. At least right off, it looks like (if it does anything useful at all) your CarService is basically trying to build a set on top of a List. I think I'd write the code something like this:
class Car {
// ...
friend std::istream &operator>>(std::istream &is, std::Car &c) {
return is >> c.model >> c.year >> c.color;
}
friend std::ostream &operator<<(std::ostream &os, std::Car const &c) {
return os << c.model << "\t" << c.year << "\t" << c.color;
};
std::set<Car> cars;
std::ifstream car_file("cars.txt");
// read data from the file:
std::copy(std::istream_iterator<Car>(car_file),
std::istream_iterator<Car>(),
std::inserter(cars));
std::set already knows how to add and remove items...
Suppose we have the following pseudo code. I am talking about OO languages.
class A{
foo(){...}
}
class B extends A{
foo(){...}
}
class C extends B{
foo(){...}
}
static void f(A a)
{
A a=new A();
a=new B();
a.foo();
}
It's easy for us to recognize that a.foo() is calling function foo overridden in class B. So why it's hard for compilers to get this truth by static analysis? The fundamental question here is why statically determine the type of A is hard for a compiler?
The example you posted is extremely simplistic and does not show anything that requires a virtual method call. With your same classes, examine this function;
void bar(A* a) {
a->foo();
}
There is no way the compiler can tell at compile-time if a is an instance of B, or C, or a plain A. That can only be decided at runtime in the general case.
The compiler can't even know if there will be new classes derived from A at some future point that will be linked with this code.
Just imagine:
A a = createInstanceFromString("B");
Now you're screwed.
On a serious note, your example is way too simplistic. Imagine if a right-hand side of an assignment is a call to a function defined in some other "module" (whatever this means). This means that the compiler has to inspect all execution paths in order to determine the exact type of a return value, but that's prohibitively expensive and sometimes downright impossible.
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.