Why not use instanceof operator in OOP design? - oop

It has been repeatedly said that the instanceof operator should not be used except in the equals() method, otherwise it's a bad OOP design.
Some wrote that this is a heavy operation, but it seems that, at least java, handles it pretty well (even more efficiently than Object.toString() comparison).
Can someone please explain, or direct me to some article which explains why is it a bad design?
Consider this:
Class Man{
doThingsWithAnimals(List<Animal> animals){
for(Animal animal : animals){
if(animal instanceOf Fish){
eatIt(animal);
}
else if(animal instanceof Dog){
playWithIt(animal);
}
}
}
...
}
The decision of what to do with the Animal, is up to the Man. Man's desires can also change occasionally, deciding to eat the Dog, and play with the Fish, while the Animals don't change.
If you think the instanceof operator is not the correct OOP design here, please tell how would you do it without the instanceof, and why?

instanceof simply breaks the Open/Close principle. and/or Liskov substitution principle
If we are not enough abstract because of instanceof usage, each time a new subclass makes an entrance, the main code gathering the logic of the application might be updated.
This is clearly not what we want, since it could potentially break the existing code and reduce its reusability.
Therefore, a good usage of polymorphism should be preferred over the basic use of conditional.

There's a good blog post called When Polymorphism Fails which is about this kind of scenario. Basically, you're right that it should be up to the Man to decide what to do with each kind of Animal. Otherwise, the code becomes fragmented and you end up violating principles such as Single Responsibility and Law of Demeter.
It wouldn't make sense to have code such as e.g. the following:
abstract class Animal {
abstract void interactWith(Man man);
}
class Fish extends Animal {
#Override
void interactWith(Man man) {
man.eat(this);
}
}
class Dog extends Animal {
#Override
void interactWith(Man man) {
man.playWith(this);
}
}
In that example, we're putting Man's logic outside of the Man class.
The problem with instanceof is that if you have a large amount of Animals, you'll end up with a long if-else-if for every one of them. It's hard to maintain and prone to errors where e.g. a new type of Animal is added, but you forget to add it to the if-else-if chain. (The visitor pattern is partly a solution to the latter problem, because when you add a new type to the visitor class, all of the implementations stop compiling and you're forced to go update them all.)
However, we can still use polymorphism to make the code simpler and avoid instanceof.
For example, if we had a feeding routine such as:
if (animal instanceof Cat) {
animal.eat(catFood);
} else if (animal instanceof Dog) {
animal.eat(dogFood);
} else if (...) {
...
}
We could eliminate the if-else-if by having methods such as Animal.eat(Food) and Animal.getPreferredFood():
animal.eat(animal.getPreferredFood());
With methods such as Animal.isFood() and Animal.isPet(), the example in the question could be written without instanceof as:
if (animal.isFood()) {
eatIt(animal);
} else if (animal.isPet()) {
playWithIt(animal);
}

instanceof is a type system escape hatch. It can be used to do really evil things, like make generics not really generic, or extend a class hierarchy with ad-hoc virtual methods that never appear in the visible interface of those classes. Both of these things are bad for long-term maintainability.
More often than not, if you find yourself wanting to use instanceof, it means that there is something wrong with your design. Breaking the type system should always be a last resort, not something to be taken lightly.
I do not think your particular example warrants using instanceof. The object-oriented way to do this is to use the visitor pattern:
abstract class Animal {
def accept(v: AnimalVisitor)
}
trait Edible extends Animal {
def taste : String
def accept(v: AnimalVisitor) = v.visit(this)
}
trait Pet extends Animal {
def growl : String
def accept(v: AnimalVisitor) = v.visit(this)
}
abstract class AnimalVisitor {
def visit(e: Edible)
def visit(p: Pet)
}
class EatOrPlayVisitor {
def visit(e: Edible) = println("it tastes " + e.taste)
def visit(p: Pet) = println("it says: " + p.growl)
}
class Chicken extends Animal with Edible {
def taste = "plain"
}
class Lobster extends Animal with Edible {
def taste = "exotic"
}
class Cat extends Animal with Pet {
def growl = "meow"
}
class Dog extends Animal with Pet {
def growl = "woof"
}
object Main extends App {
val v = new EatOrPlayVisitor()
val as = List(new Chicken(), new Lobster(), new Cat(), new Dog())
for (a <- as) a.accept(v)
}
NOTE: I am aware that Scala has case classes, but I wanted to provide a general object-oriented solution.

using instance of is a bad practise because in the OOP there is no need to check what the class is,
if the method is compatible you should to be able to call it with such arguments, otherwise design is spoiled, flawed,
but it exist the same way as goto in C and C++,
I think sometimes it might be easier to integrate a bad code using instance of but if you make your own proper code avoid it
so basically this is about of programming style what is good and what is bad,
when and why
in some curcumstances bad style is used, because sometimes the code quality is secondary, perhaps
sometimes the goal is to make the code not easy to understand by others so that would be the way to do it

Related

Why does `BUILD` not see attribute from parent class?

class A { has $.name; };
class B is A { submethod BUILD { $!name = 'foo' } };
This code looks natural but throws error.
Attribute $!name not declared in class B
Yes, it is not declared in class B, but we are in the partially constructed object during B::BUILD and documentation says that bless creates the new object, and then walks all subclasses in reverse method resolution order. So $!name attribute should be known for class B in this phase, right?
Is there any way to set parent class attributes during object construction without using new method? I know that new will do the trick here, but BUILD has a lot of syntactic sugar and BUILD / TWEAK feel more DWIMy and straightforward than resolving to low-level blessing in new.
Private attribute syntax ($!foo) is only available for attributes that are lexically visible. That's why they're private :-)
If class A would want other classes be able to change, it would need to provide a mutator method explicitely or implicitely (with is rw).
Or you could let class A trust class B as described at https://docs.raku.org/routine/trusts#(Type_system)_trait_trusts .
Still it feels you would do better using roles:
role A {
has $.name is rw;
}
class B does A {
submethod BUILD { $!name = 'foo' }
}
The other option is to use the is built trait on attributes that you would like the default constructor to initialize.
Consider the following:
class A {
has $.name is built
}
class B is A { }
B.new(name => "Foo").gist.say; # B.new(name => "Foo")
This allows descendend classes to use the named parameter matching the attribute in .new to initialize the value at object creation time. Please note that this will work whether the attribute is public "$." or private "$!".
Hope that helps!
TL;DR All attributes are technically private. This design is a good one. You could just call a method in A from B. There are, of course, other options too.
Why doesn't BUILD see parent class attributes?
Quoting Wikipedia Fragile base class page problem:
One possible solution is to make instance variables private to their defining class and force subclasses to use accessors to modify superclass states.¹
Hence, per Raku Attributes doc:
In Raku, all attributes are private, which means they can be accessed directly only by the class instance itself.
B can call a method in A
This code looks natural:
class A { has $.name }
class B is A { submethod BUILD { $!name = 'foo' } }
Quoting again from Raku doc section linked above:
While there is no such thing as a public (or even protected) attribute, there is a way to have accessor methods generated automatically: replace the ! twigil with the . twigil (the . should remind you of a method call).
Your code generates a $!name attribute (private to A) plus a public .name method. Any code that uses the A class can call its public methods.
Your code hasn't used the autogenerated accessor method. But it could have done so with a couple small changes:
class A { has $.name is rw } # Add `is rw`
class B is A { submethod BUILD { self.name = 'foo' } } # s/$!name/self.name/²
say B.new # B.new(name => "foo")
is rw makes the public .name accessor method a read/write one instead of the default read only one.
Not using is rw
As I now understand from your first comment below, an is rw accessor is disallowed given your requirements. You can achieve any effect that a class supports via its public interface.
Let's first consider a silly example so it's clear you can do anything that any methods can do. Using, say, self.name, in A or B, might actually run one or more methods in A that make a cup of tea and return 'oolong' rather than doing anything with A's $!name:
class A {
has $.name = 'fred'; # Autogenerates a `method name` unless it's defined.
method name { 'oolong' } # Defines a `method name` (so it isn't generated).
}
my \a = A.new;
say a; # A.new(name => "fred")
say a.name; # oolong
Conversely, if an A object changes its $!name, doing so might have no effect whatsoever on the name of the next cup of tea:
class A {
has $.name = 'fred';
method name { 'rooibos' } # ignores `$!name`
method rename { $!name = 'jane' }
}
my \a = A.new;
say a; # A.new(name => "fred")
a.rename;
say a.name; # rooibos
To recap, you can (albeit indirectly) do anything with private state of a class that that class allows via its public API.
For your scenario, perhaps the following would work?:
class A {
has $.name;
multi method name { $!name }
multi method name (\val) { once $!name = val }
}
class B is A {
submethod BUILD { self.name: 42 }
}
my \a = B.new;
say a; # B.new(name => 42)
say a.name; # 42
a.name: 99; # Does nothing
say a.name; # 42
Footnotes
¹ Continuing to quote solutions listed by Wikipedia:
A language could also make it so that subclasses can control which inherited methods are exposed publicly.
Raku allows this.
Another alternative solution could be to have an interface instead of superclass.
Raku also supports this (via roles).
² self.name works where $!name does not. $.name throws a different compiler error with an LTA error message. See Using %.foo in places throws, but changing it to self.foo works.
Sorry that my answer is late in the day, but I feel that your original question is very well pitched and would like to add my variation.
class A {
has $!name;
submethod BUILD( :$!name ) {}
multi method name { $!name }
multi method name(\v) { $!name := v }
method gist(::T:) { "{::T.^name}.new( name => $!name )" }
}
class B is A {
submethod BUILD( :$name ) { self.name: $name // 'foo' }
}
say B.new; #B.new( name => foo )
say A.new(name => 'bar'); #A.new( name => bar )
say B.new(name => 'baz'); #B.new( name => baz )
Raku OO tries to do two mutually incompatible things:
provide a deep OO (similar to C++ / Java)
provide a lightweight OO (similar to Python / Ruby)
This is done by having a core that does #1 and then adding some sugar to it to do #2. The core gives you stuff like encapsulation, multiple inheritance, delegation, trust relationships, role based composition, delegation, MOP, etc. The sugar is all the boilerplate that Raku gives you when you write $. instead of $! so that you can just throw together classes to be lightweight datatypes for loosely structured data.
Many of the answers here bring suggestions from mode #2, but I think that your needs are slightly too specific for that and so my answer tilts towards mode #1.
Some notes to elaborate why I think this is a good solution:
you state that you cannot use is rw - this avoids traits
with proper method accessors, you have control over initialization
BUILD() is not constrained by the public accessor phasing
no need to go to roles here (that's orthogonal)
And some drawbacks:
you have to write your own accessors
you have to write your own .gist method [used by say()]
It is attributed to Larry that "everyone wants the colon(:)". Well, he had the last say, and that the Raku method call syntax self.name: 'foo' echos assignment self.name= 'foo' is, in my view, no accident and meant to ease the mental switch from mode #2 to #1. ;-)
Does Raku succeed to reconcile the irreconcilable? - I think so ... but it does still leave an awkward gear shift.
EDITED to add submethod BUILD to class A
Thanks everyone for great discussion and solution suggestions. Unfortunately there is no simple solution and it became obvious once I understood how Raku constructs object instances.
class A {
has $.name is rw;
};
class B is A {
submethod BUILD {
self.A::name = 123; # accessor method is already here
}
};
B.new.name.say; # will print 123
So if inheritance is used Raku works from parent class to child class fully constructing each class along the way. A is constructed first, $.name param is initialized, public attribute accessor methods are installed. This A instance become available for B construction, but we are not in A build phase anymore. That initialization is finished. My code example shows what is happening with syntactic sugar removed.
The fact that
submethod BUILD {
self.name = 123;
}
is available in class B during BUILD phase does not mean that we (as class B) have this attribute still available for construction. We are only calling write method on already constructed class A. So self.name = 123 really means self.A::name = 123.
TL;DR: Attributes are not collected from parent classes and presented to BUILD in child class to be set at the same time. Parent classes are constructed sequentially and only their method interfaces are available in child BUILD submethod.
Therefore
class A {
has $.name; # no rw
};
class B is A {
submethod BUILD {
$!name = 123;
}
};
will not work because once we reach submethod BUILD in B class attribute $.name is already constructed and it is read only.
Solution for shallow inheritance:
Roles are the way to go.
role A {
has $.name;
};
class B does A {
submethod BUILD {
$!name = 123;
}
};
Roles are copied to class composing them, so class B sees this $.name param as their own and can initialize it. At the same time roles autopun to classes in Raku and standalone my $a = A.new( name => 123 ) can be used as a class.
However roles overdose can lead to orthogonal pattern issues.
Solution for deep inheritance:
There is none. You cannot have secure parent classes with read-only attribute behavior and initialize this attribute in child class builder, because at this moment parent class portion of self will be already constructed and attribute will be already read-only. Best you can do is to wrap attribute of parent class in private method (may be Proxy) and make it write-once this way.
Sad conclusion:
Raku needs improvement in this area. It is not convenient to use it for deep inheritance projects. Maybe new phaser is needed that will mash every attribute from parent classes in role-style and present them to BUILD at the same time. Or some auto-trust mechanism during BUILD. Or anything that will save user from introducing role inheritance and orthogonal role layout (this is doing stuff like class Cro::CompositeConnector does Cro::Connector when class Cro::Connector::Composite is Cro::Connector is really needed) to deep OO code because roles are not golden hammer that is suitable for every data domain.

Get Kotlin class from string a call a method in it

I have 2 simple classes in kotlin
package com.sample.repo
class SampleClassA() {
fun test(): String {
return "Do things A way"
}
}
package com.sample.repo
class SampleClassB() {
fun test(): String {
return "Do things B way"
}
}
Now i have a configuration file that tells me which class to use.
Let's say i have a string
val className = "SampleClassA" // assuming all classes are in same package
I want obtain this class and invoke the test function in it
I was able to do below
fun `some random test`() {
val className = "SampleClassA"
val packageName = "com.sample.repo"
val kClass = Class.forName("$packageName.$className").kotlin
val method = kClass.members.find { it.name == "test" }
// How do i call this method ??
}
}
You should create an object of the class and then call method on it.
Example:
//...code from your example
val method = kClass.members.find { it.name == "test" }!!
val obj = kClass.primaryConstructor?.call()
val result = method.call(obj)
println(result)
I wouldn't do it that way. Instead, I'd require that the classes you're choosing between implement some common interface, which you can then refer to directly. For example:
interface Testable {
fun test(): String
}
 
package com.sample.repo
class SampleClassA() : Testable {
override fun test() = "Do things A way"
}
 
package com.sample.repo
class SampleClassB() : Testable {
override fun test() = "Do things B way"
}
 
fun `some random test`() {
val className = "SampleClassA"
val packageName = "com.sample.repo"
val testable = Class.forName("$packageName.$className").kotlin
.createInstance() as Testable
testable.test()
}
I don't know if this applies to OP, but judging from some of the questions asked here on StackOverflow, many people are coming to Kotlin from weakly-typed languages where it's common to use ‘string typing’ to fudge the lines between types, to assume that developers can always be trusted, and that it's fine to discover problems only at runtime. Of course, it's only natural to try to apply the patterns and techniques you're familiar with when learning a new language.
But while that style of programming is possible in Kotlin (using reflection), it's rarely a good fit. If you'll excuse one of my standard rants, reflection is slow, ugly, fragile, insecure, and hard to maintain; it's easy to get wrong, and forces you to handle most errors at runtime. Don't get me wrong: reflection is a very valuable tool, and there are situations where it's vital, such as writing frameworks, plug-ins, some forms of dependency injection, build tools, and similar. But reflection should be a tool of last resort — for general application coding, there's almost always a better approach, usually one that's more concise, easier to read, performs better, spots more problems at compile-time, can be autocompleted in your IDE, and works with the language and its type system, not against it.
Kotlin is a strongly-typed language; it has a fairly sophisticated type system (and type inference, so you don't need to keep repeating yourself), which is safer and smarter, turns many errors into compile-time errors, allows many optimisations, and is effectively self-documenting (making more explicit the contract between called code and its callers). It's better to try to work with the type system when you can, rather than subvert if (which is what reflection does).
The example above uses reflection to create an instance of a class which is assumed to implement the Testable interface (and will give ugly errors at runtime if the class isn't available, doesn't implement that interface, or doesn't have a public constructor with no required params), but after that uses normal, typed code which is much safer.
(In fact, depending how your test code is structured, you might find a way to configure it with Testable instances rather than String classnames, and avoid reflection altogether. That would be simpler and safer still.)

OOP: Inheriting from immutable objects

Background
Suppose I have some set of fields which are related to each other I therefore make a class to gather them. Let us call this class Base. There are certain methods as well, which operate on these fields which will be common to all derived classes. Additionally, let us suppose we want Base and all its derived classes to be immutable.
In different contexts, these fields support additional operations, so I have different derived classes which inherit the fields and provide additional methods, depending on their context. Let us call these Derived1, Derived2, etc.
In certain scenarios, the program needs instances of a derived class, but the state of the fields must satisfy some condition. So I made a class RestrictedDerived1 which makes sure that the condition is satisfied (or changes the parameters to conform if it can) in the constructor before calling its base constructor, or throws an error otherwise.
Further, there are situations where I need even more conditions to be met, so I have SuperRestrictedDerived1. (Side note: given that some conditions are met, this class can more efficiently compute certain things, so it overrides some methods of Derived1.)
Problem
So far so good. The problem is that most of the methods of all these classes involve making another instance of some class in this hierarchy (not always the same as the one that the method was called on, but usually the same one) based on itself, but with some modifications which may involve somewhat complex computation (i.e. not just changing one field). For example one of the methods of Derived1 might look like:
public Derived1 foo(Base b) {
TypeA fieldA = // calculations using this and b
TypeB fieldB = // more calculations
// ... calculate all fields in this way
return new Derived1(fieldA, fieldB, /* ... */);
}
But then down the hierarchy RestrictedDerived1 needs this same function to return an instance of itself (obviously throwing an error if it can't be instantiated), so I'd need to override it like so:
#Override
public ResrictedDerived1 foo(Base b) {
return new RestrictedDerived1(super.foo(b));
}
This requires a copy constructor, and unnecessarily allocating an intermediate object which will immediately destroyed.
Possible solution
An alternative solution I thought of was to pass a function to each of these methods which constructs some type of Base, and then the functions would look like this:
// In Derived1
public Derived1 foo(Base b, BaseCreator creator) {
TypeA fieldA = // calculations using this and b
TypeB fieldB = // more calculations
// ... calculate all fields in this way
return creator.create(fieldA, fieldB, /* ... */);
}
public Derived1 foo(Base b) {
return foo(b, Derived1::create);
}
public static Derived1 create(TypeA fieldA, TypeB fieldB, /* ... */) {
return new Derived1(fieldA, fieldB, /* ... */);
}
// In RestrictedDerived1
#Override
public ResrictedDerived1 foo(Base b) {
return (RestrictedDerived1) foo(b, RestrictedDerived1::create);
}
public static RestrictedDerived1 create(TypeA fieldA, TypeB fieldB, /* ... */) {
return new RestrictedDerived1(fieldA, fieldB, /* ... */);
}
My question
This works, however it feels "clunky" to me. My question is, is there some design pattern or concept or alternative design that would facilitate my situation?
I tried do use generics, but that got messy quick, and didn't work well for more than one level of inheritance.
By the way, the actual classes that these refer to is 3D points and vectors. I have a base called Triple with doubles x, y, and z (and some functions which take a lambda and apply them to each coordinate and construct a new Triple with the result). Then I have a derived class Point with some point related functions, and another derived class Vector with its functions. Then I have NonZeroVector (extends Vector) which is a vector that cannot be the zero vector (since other objects that need a vector sometimes need to be guaranteed that it's not the zero vector, and I don't want to have to check that everywhere). Further, I have NormalizedVector (extends NonZeroVector) which is guaranteed to have a length of 1, and will normalize itself upon construction.
MyType
This can be solved using a concept variously known as MyType, this type, or self type. The basic idea is that the MyType is the most-derived type at runtime. You can think of it as the dynamic type of this, but referred to statically (at "compile time").
Unfortunately, not many mainstream programming languages have MyTypes, but e.g. TypeScript does, and I was told Raku does as well.
In TypeScript, you could solve your problem by making the return type of foo the MyType (spelled this in TypeScript). It would look something like this:
class Base {
constructor(public readonly fieldA: number, public readonly fieldB: string) {}
foo(b: Base): this {
return new this.constructor(this.fieldA + b.fieldA, this.fieldB + b.fieldB);
}
}
class Derived1 extends Base {
constructor(fieldA: number, fieldB: string, protected readonly repeat: number) {
super(fieldA * repeat, fieldB.repeat(repeat));
}
override foo(b: Base): this {
return new this.constructor(
this.fieldA + b.fieldA, this.fieldB + b.fieldB, this.repeat
);
}
}
class RestrictedDerived1 extends Derived1 {
constructor(fieldA: number, fieldB: string, repeat: number) {
super(fieldA * repeat, fieldB.repeat(repeat), repeat);
if (repeat >= 3) {
throw new RangeError(`repeat must be less than 3 but is ${repeat}`)
}
}
}
const a = new RestrictedDerived1(23, 'Hello', 2);
const b = new Base(42, ' World');
const restrictedDerived = a.foo(b); // Inferred type is RestrictedDerived1
Slightly b0rken Playground link
Implicit factories
In a language with type classes or implicits (like Scala), you could solve your problem with implicit Factory objects. This would be similar to your second example with the Creators, but without the need to explicitly pass the creators around everywhere. Instead, they would be implicitly summoned by the language.
In fact, your requirement is very similar to one of the core requirements of the Scala Collections Framework, namely that you want operations like map, filter, and reduce to only be implemented once, but still preserve the type of the collection.
Most other Collections Frameworks are only able to achieve one of those goals: Java, C#, and Ruby, for example, only have one implementation for each operation, but they always return the same, most-generic type (Stream in Java, IEnumerable in C#, Array in Ruby). Smalltalk's Collections Framework is type-preserving, but has duplicated implementations for every operation. A non-duplicated type-preserving Collections Framework is one of the holy grails of abstractions designers / language designers. (It's no coincidence that so many papers that present novel approaches to OO uses a refactoring of the Smalltalk Collection Framework as their working example.)
F-bounded Polymorphism
If you have neither MyType nor implicit builders available, you can use F-bounded Polymorphism.
The classic example is how Java's clone method should have been designed:
interface Cloneable<T extends Cloneable<T>> {
public T clone();
}
class Foo implements Cloneable<Foo> {
#Override
public Foo clone() {
return new Foo();
}
}
JDoodle example
However, this gets tedious very quickly for deeply-nested inheritance hierarchies. I tried to model it in Scala, but I gave up.

Best practice for enforcing type safety in polymorphic inheritance hierarchies [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I seem to run into this situation quite a lot and have yet to find a solution that I find acceptable.
Quite often I will have parallel inheritance hierarchies where a method in one hierarchy gets passed the matching class from the other hierarchy as a parameter.
Here is an example that probably explains this better.
abstract class Animal
{
public virtual void Eat(Food f)
{
}
}
abstract class Food
{
}
class LionFood : Food
{
}
class ElephantFood : Food
{
}
class Lion : Animal
{
public override void Eat(Food f)
{
// It is only ever valid to pass LionFood here as the parameter.
// passing any other type of Food is invalid and should be prevented
// or at least throw an exception if it does happen.
}
}
In the past, I have usually made the base class generic to allow the implementing concrete class to define the type as follows..
abstract class Animal<T> where T : Food
{
public abstract void Eat(T f);
}
class Lion : Animal<LionFood>
{
public override void Eat(LionFood f)
{
}
}
At first this seems like a very good solution because it provides compile-time type safety. But the more I use it, the more I am starting to think that using generics in this way is infact an anti-pattern. The problem is that the Animal base class cannot be used in a polymorphic way. You cannot, for example, easily write a method that will process any type of Animal regardless of its actual concrete type.
Every time I use this generics solution, I always seem to end up with covariant and contravariant interfaces all over the place just to try and provide the polymorphic behaviour I want. This gets out of hand pretty quickly and some functionality is not possible simply because the correct interface cannot be provided.
Of course another option is to not use generics and perform runtime type checking in the Eat method like this:
public override void Eat(Food f)
{
if (f.GetType() != typeof(LionFood))
{
throw new Exception();
}
}
This is better than nothing I suppose but I'm not a huge fan of it simply because of the lack of compile-time type safety.
So after all that.. My question is.. What is the best practice to provide polymorphic behaviour while at the same time ensuring some type safety?
Is there some OO design trick or pattern that I am missing that will allow me to avoid the parallel inheritance hierarchies all together?
I appreciate that this question is somewhat subjective, but there are points available for everyone who contributes and I'll choose the best response as the answer.
Thanks for looking.
Edit:
Having thought about this I realise that my example given doesn't really make sense. Of course it is not possible to use Animal in a polymorphic way because the type passed to Eat will always depend on the actual underlying type of Animal (which the initiator of a polymorphic call will not know)! I need to think of a better example that illustrates my actual situation.
I think common sense and the requirements of the domain will dictate the proper approach. Working with this example, I'd do like this
public class Lion:Animal
{
public override void Eat(Food f)
{
Eat(f as LionFood);
}
public void Eat(LionFood food)
{
//check for null food
//actually consume it
}
}
Edit
I think using generics is not suited in this case, because what if an Animal can play with a Toy, hunt a specific Animal and so on. You can have a number of methods with arugments that implement an abstraction, it's awkward to use generics every time there is a method with an argument that uses polymorhpism.
Ok, could that be what you want? Sometimes, when you can't articulate what you want to do, what you want is actually a mixin.
template<typename base>
class Eater: public base {
template<typename T>
Eat(T (extends Food) food) { // you can do that extends thing in C++ but I won't bother
// register what's eaten, or do whatever
base::Eat(food);
}
}
class Lion {
Eat(LionFood food) {
cout<<"Hmm delicious!";
}
}
int main() {
Eater<Lion> lion;
lion.eat(LionFood());
return 0;
}
This'll give you a nice compiler error if you try to feed grass to the lion.

How to avoid to "fill" a generic class with attributes?

I am trying to translate a poker game to a correct OOP model.
The basics :
class Hand
{
Card cards[];
}
class Game
{
Hand hands[];
}
I get games and hands from a text file. I parse the text file several times, for several reasons:
get somes infos (reason 1)
compute some stats (reason 2)
...
For reason 1 I need some attributes (a1, b1) in class Hand. For reason 2, I need some other attributes (a2, b2). I think the dirty way would be :
class Hand
{
Card cards[];
Int a1,b1;
Int a2,b2;
}
I would mean that some attributes are useless most of the time.
So, to be cleaner, we could do:
class Hand
{
Card cards[];
}
class HandForReason1 extends Hand
{
Int a1,b1;
}
But I feel like using a hammer...
My question is : is there an intermediate way ? Or the hammer solution is the good one ? (in that case, what would be a correct semantic ?)
PS : design patterns welcome :-)
PS2 : strategy pattern is the hammer, isn't it?
* EDIT *
Here is an application :
// Parse the file, read game infos (reason 1)
// Hand.a2 is not needed here !
class Parser_Infos
{
Game game;
function Parse()
{
game.hands[0].a1 = ...
}
}
// Later, parse the file and get some statistics (reason 2)
// Hand.a1 is not needed here !
class Parser_Stats
{
Game game;
function Parse()
{
game.hand[0].a2 = ...
}
}
Using a chain of responsibility to recognize a poker hand is what I would do. Since each hand has it's own characteristics, you can't just have a generic hand.
Something like
abstract class Hand {
protected Hand next;
abstract protected boolean recognizeImpl(Card cards[]);
public Hand setNext(Hand next) {
this.next = next;
return next;
}
public boolean Hand recognize(Card cards[]) {
boolean result = ;
if (recognizeImpl(cards)) {
return this;
} else if (next != null) {
return next.recognize(cards);
} else {
return null;
}
}
}
And then have your implementation
class FullHouse extends Hand {
protected boolean recognizeImpl(Card cards[]) {
//...
}
}
class Triplet extends Hand {
protected boolean recognizeImpl(Card cards[]) {
//...
}
}
Then build your chain
// chain start with "best" hand first, we want the best hand
// to be treated first, least hand last
Hand handChain = new FullHouse();
handChain
.setNext(new Triplet())
//.setNext(...) /* chain method */
;
//...
Hand bestHand = handChain.recognize(cards);
if (bestHand != null) {
// The given cards correspond best to bestHand
}
Also, with each hand it's own class, you can initialize and have then hold and compute very specific things. But since you should manipulate Hand classes as much as you can (to stay as much OO as possible), you should avoid having to cast your hands to a specific hand class.
** UPDATE **
Alright, so to answer your original question (sig) the class Hand is for manipulating and treating "hands". If you need to calculate other statistics or other needs, wrapping your Hand class might not be a good idea as you'll end up with a compound class, which is not desirable (for maintainability's sake and OOP paradigm).
For the reason 1, it is alright to have different kinds of hands, as the chain of responsibility illustrate; you can read your file, create different kinds of hands with the many parameters as is required.
For reason 2, you might look at other solutions. One would be to have your Hand classes fire events (ex: when it is recognized) and your application could register those hands into some other class to listen for events. That other class should also be responsible to collect the necessary data from the files you are reading. Since a hand is not (or should not be) responsible to collect statistical data, the bottom line is that you need to have something else handle that.
One package = coherent API and functionalities
One class = coherent functionalities (a hand is a hand, not a statistical container)
One method = a (single) functionality (if a method needs to handle more than one functionality, break those functionalities into separate private methods, and call them from the public method)
I'm giving you a generic answer here because reason 1 and reason 2 are not specific.