0

Ive seen this pattern in many places, but have never seen it named.

I am more after a suggestion on how to name methods that implement it, as different people seem to use a different naming pattern.

Sorry i cant recall any libraries as examples but if use one as part of your answer, please name them.

public class Produce{

   package private Produce(){};

   Fruit isFruit(){
     return null;
   }
   Veg isVeg(){
     return null;
   } 
}

public class Veg extends Produce {

   package private Veg(){};

   Veg isVeg(){
     return this;
   }
}

public class Fruit extends Produce {

    package private Fruit(){};

   Fruit isFruit(){
     return this;
   }
}

ADDITIONAL

@LouisWasserman

Firstly the number of sub types of Produce is limited by making its ctor package private. By including 2 isXXX methods, im stating a fact there are only 2 sub classes ever, which is nicer than doing instanceof checks. Maybe its just me but, this approach also means there are no casts in other code or the above, which has to be a good thing right ?

Also isnt returning an empty list from a method when a search or query fails kind of the same as returning null to mark that the operation isFruit() failed when attempting to cast a Veg to a Fruit ?

I found a quick example in GWT in JType which is a clone of the Eclipse JDT i believe. Anyway that origin doesnt matter but here we have two very well konwn products doing exactly what im describing...

http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java

There are plenty of other isXXX that try and cast or return null, ive pasted a few below.

/**
* Returns this instance as a {@link JAnnotationType} if it is an annotation
* or <code>null</code> if it is not.
*/
JAnnotationType isAnnotation();

JArrayType isArray();

JClassType isClass();

JClassType isClassOrInterface();

/**
* Returns this instance if it is an enumeration or <code>null</code> if it is
* not.
*/
JEnumType isEnum();

JGenericType isGenericType();
mP.
  • 18,002
  • 10
  • 71
  • 105

1 Answers1

1

First of all I think this is a terrible pattern. The super class should generally not be aware of its subclasses.

What if you add another subclass of Produce? You will need to remember to modify Produce. Error prone.

To answer your question though, I would avoid isFruit, as users might expect it to return a boolean. If forced to use this pattern, I would probably use getFruit() or asFruit().

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • If you _must_ do this sort of thing, `instanceof` is generally the way to go. But there are usually better ways. – Louis Wasserman May 31 '12 at 09:41
  • @aioobe from my experience asXXX is always used to suggest a cast/view that always works and never returns null or throws. This is what has inspired me to ask. – mP. May 31 '12 at 12:39
  • @aioobe i have edit q to show Produce has a limited number of sub classes. Its not a free for all. – mP. May 31 '12 at 12:54
  • 1
    The examples you cite are examples of the dirty awkward hacks GWT has to do to deal internally with Javascript's dynamic typing. Unless you're working on the internals of GWT, this is a really bad example to follow. – Louis Wasserman May 31 '12 at 12:55
  • 1
    Even if your class is package-private, the reason that this is a bad habit is that _you_ might want to add new subclasses later, not that other programmers might subclass your `Produce` class. Thousands upon thousands of programmers have said, "No, I'll never need to add another subclass of this!"...only to be wrong. It's _always_ important to write code that you can extend later if the parameters of the problem change, and your approach above is not practicably extensible. – Louis Wasserman May 31 '12 at 12:59
  • In all cases its true my approach fails. However if its something fixed such as enum but holds state then it does work, eg Option/none/some. I believe your ref to other impls applies more to services my thing is more for value types that hold values not ones that do stuff. – mP. May 31 '12 at 14:02
  • @louiswasserman I wont dispute about js and its internal nasties, however is it fair to say the approach highlighted by me, made the best of what was given? How else could it be done? C sharp does something similar w/ --as--. – mP. May 31 '12 at 14:04
  • `instanceof` represents a reasonable approach used pretty wisely. That said, the best option of all is to refactor your methods into `Produce` so no outside code needs to _care_ what subtype it is. – Louis Wasserman May 31 '12 at 14:09
  • @louiswasserman this is simply not possible many times. Each of the diff sub types of JType has many different properties and methods. – mP. Jun 01 '12 at 07:15