Function calls...

Discussion in 'Java' started by Raymond Martineau, Dec 26, 2004.

  1. In C, it's possible to create an array of the following data structure to
    associate a function call with a specific key or identifier:

    struct {
    char *key;
    void (*function)();
    } a[] = { { "Function1", Function1} ,
    { "Function2", Function2}};

    (Or some other varient that you are comfortable with.)

    I would like to know the appropriate procedure on how to implement the same
    in Java. I would prefer to use the above system, as it can be much quicker
    to call a function by looking up the associated token in a hashtable as
    opposed to writing many lines of an if/else ladder.

    The first thought that appeared in my mind would involve reflecting
    classes. Checking with the API spec indicated that it should work, but I'm
    not sure that placing a large number of methods in one class is the best
    solution.

    In case you're wondering, I'm using this system to interpret a language
    that uses a large number of keywords (with each keyword executing its own
    function.)
     
    Raymond Martineau, Dec 26, 2004
    #1
    1. Advertising

  2. Raymond Martineau

    Nicky Guest

    Hi

    Reflection is not very fast.
    Another solution is to create an abstract class with a single method:

    public abstract class AbstractFunction {
    public abstract void execute();
    }

    and to extend and implement that class for each function:

    public class Function1 extends AbstractFunction {
    public void execute() {
    // Code for function1
    }
    }

    Hope it helps
    Nicky

    "Raymond Martineau" <> wrote in message
    news:...
    > In C, it's possible to create an array of the following data structure to
    > associate a function call with a specific key or identifier:
    >
    > struct {
    > char *key;
    > void (*function)();
    > } a[] = { { "Function1", Function1} ,
    > { "Function2", Function2}};
    >
    > (Or some other varient that you are comfortable with.)
    >
    > I would like to know the appropriate procedure on how to implement the
    > same
    > in Java. I would prefer to use the above system, as it can be much
    > quicker
    > to call a function by looking up the associated token in a hashtable as
    > opposed to writing many lines of an if/else ladder.
    >
    > The first thought that appeared in my mind would involve reflecting
    > classes. Checking with the API spec indicated that it should work, but
    > I'm
    > not sure that placing a large number of methods in one class is the best
    > solution.
    >
    > In case you're wondering, I'm using this system to interpret a language
    > that uses a large number of keywords (with each keyword executing its own
    > function.)
    >
     
    Nicky, Dec 26, 2004
    #2
    1. Advertising

  3. Raymond Martineau

    Tony Morris Guest

    "Nicky" <> wrote in message
    news:...
    > Hi
    >
    > Reflection is not very fast.
    > Another solution is to create an abstract class with a single method:
    >
    > public abstract class AbstractFunction {
    > public abstract void execute();
    > }
    >


    Abstract classes should never be used as a pure virtual type (with only
    abstract methods), or a concrete type (with no abstract methods).
    It is arguable that abstract classes should be used at all (inheritance from
    anything but an interface is pure evil, but that's another story for another
    camp fire).

    In the case of an attempt to use an abstract class as a pure virtual type as
    has been suggested, an interface is always more suited.

    --
    Tony Morris
    http://xdweb.net/~dibblego/
     
    Tony Morris, Dec 26, 2004
    #3
  4. Raymond Martineau

    Tony Morris Guest

    "Tony Morris" <> wrote in message
    news:Xbvzd.88751$...
    > "Nicky" <> wrote in message
    > news:...
    > > Hi
    > >
    > > Reflection is not very fast.
    > > Another solution is to create an abstract class with a single method:
    > >
    > > public abstract class AbstractFunction {
    > > public abstract void execute();
    > > }
    > >

    >
    > Abstract classes should never be used as a pure virtual type (with only
    > abstract methods), or a concrete type (with no abstract methods).
    > It is arguable that abstract classes should be used at all (inheritance

    from
    > anything but an interface is pure evil, but that's another story for

    another
    > camp fire).
    >
    > In the case of an attempt to use an abstract class as a pure virtual type

    as
    > has been suggested, an interface is always more suited.
    >
    > --
    > Tony Morris
    > http://xdweb.net/~dibblego/
    >
    >
    >


    It's worth nothing that a common web application framework, known as Struts
    (struts.apache.org last I checked), makes use of this antipattern.
    Struts is reknowned for its 'crustiness' for this, and many other, reasons.

    --
    Tony Morris
    http://xdweb.net/~dibblego/
     
    Tony Morris, Dec 26, 2004
    #4
  5. Raymond Martineau wrote:
    >
    > In C, it's possible to create an array of the following data structure to
    > associate a function call with a specific key or identifier:
    >
    > struct {
    > char *key;
    > void (*function)();
    > } a[] = { { "Function1", Function1} ,
    > { "Function2", Function2}};
    >
    > (Or some other varient that you are comfortable with.)
    >
    > I would like to know the appropriate procedure on how to implement the same
    > in Java. I would prefer to use the above system, as it can be much quicker
    > to call a function by looking up the associated token in a hashtable as
    > opposed to writing many lines of an if/else ladder.
    >
    > The first thought that appeared in my mind would involve reflecting
    > classes. Checking with the API spec indicated that it should work, but I'm
    > not sure that placing a large number of methods in one class is the best
    > solution.
    >
    > In case you're wondering, I'm using this system to interpret a language
    > that uses a large number of keywords (with each keyword executing its own
    > function.)


    Reflection will work but is not the best choice here. In Java, you would normally use an
    object reference instead of a function pointer. The object's class would implement an
    interface containing the common method signature. This is quite efficient as opposed to
    reflection and provides additional OO capabilities vs. a function pointer.

    --
    Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
    ==============================================================
    * The Ultimate DBMS is here!
    * FirstSQL/J Object/Relational DBMS (http://www.firstsql.com)
     
    Lee Fesperman, Dec 26, 2004
    #5
  6. Raymond Martineau

    Chris Uppal Guest

    Raymond Martineau wrote:

    > In case you're wondering, I'm using this system to interpret a language
    > that uses a large number of keywords (with each keyword executing its own
    > function.)


    For such an application, I think that the best way to go would be to use lots
    of little objects that all have different implementations of the same generic
    method.

    E.g (non-compliable stripped down pseudo-Java):

    =====
    abstract class Action { void doIt(); }
    class Action1 extends Action { void doIt() { /* something */} }
    class Action2 extends Action { void doIt() { /* something */} }
    ....

    Map actions = new HashMap();

    actions.add("Action1", new Action1());
    actions.add("Action2", new Action2());
    .....
    =====

    In practise I would probably use anonymous inner classes rather than explicitly
    naming each subclass. The effect is identical, but it would help keep the
    source looking somewhat tighter. (But also make it harder to see what's going
    on, which is why I used explicit classes in the above example).

    -- chris
     
    Chris Uppal, Dec 26, 2004
    #6
  7. (Raymond Martineau) writes:

    > In C, it's possible to create an array of the following data structure to
    > associate a function call with a specific key or identifier:
    >
    > struct {
    > char *key;
    > void (*function)();
    > } a[] = { { "Function1", Function1} ,
    > { "Function2", Function2}};
    >
    > (Or some other varient that you are comfortable with.)
    >
    > I would like to know the appropriate procedure on how to implement the same
    > in Java. I would prefer to use the above system, as it can be much quicker
    > to call a function by looking up the associated token in a hashtable as
    > opposed to writing many lines of an if/else ladder.


    public interface Fun {
    void call();
    }
    public Pair {
    public final String key;
    public final Fun fun;
    public Fun(String key, Fun fun) {
    this.key = key; this.fun = fun;
    }
    }

    Pair[] a =
    { new Pair("Function1",
    new Fun() {
    public void call() { ... body of Function1 ... }
    }),
    new Pair("Function2",
    new Fun() {
    public void call() { ... body of Function2 ... }
    }),
    ...
    }

    If you build a hash map the array like this:

    Map<String,Fun> action = new HashMap<String,Fun>();
    for (Pair p : a)
    action.put(p.key, p.fun);

    you get very fast execution of each instruction:

    action.get(keyword).invoke();

    Peter
     
    Peter Sestoft, Dec 26, 2004
    #7
  8. Nicky wrote:
    > Hi
    >
    > Reflection is not very fast.
    > Another solution is to create an abstract class with a single method:
    >
    > public abstract class AbstractFunction {
    > public abstract void execute();
    > }
    >
    > and to extend and implement that class for each function:
    >
    > public class Function1 extends AbstractFunction {
    > public void execute() {
    > // Code for function1
    > }
    > }
    >
    > Hope it helps
    > Nicky
    >
    > "Raymond Martineau" <> wrote in message
    > news:...
    >



    Sipped

    The usual name for this is 'Command pattern', however, like Tony said,
    the AbstractFunction class should always be an interface.

    So.

    public interface Command {

    void execute();

    }

    public class KeywordCommandTwo implements Command {


    public void execute() {
    ...
    }

    }

    public class KeywordCommandOne implements Command {


    public void execute() {
    ...
    }

    }


    And this code can be used like this....

    public class Foo {

    private Map keywordCommands = new HashMap();

    public int main(String[] args) {


    keywordCommands.put(keywordOne, new KeywordCommandOne());
    keywordCommands.put(keywordTwo, new KeywordCommandTwo());


    // load each keyword from file and execute its command.
    for each keyword in file {
    KeywordCommand command = (KeywordCommand)
    keywordCOmmands.get(keyword);

    command.execute();
    }

    }

    }
     
    Andrew McDonagh, Dec 26, 2004
    #8
  9. Raymond Martineau

    Ryan Stewart Guest

    "Tony Morris" <> wrote in message
    news:Xbvzd.88751$...
    > Abstract classes should never be used as a pure virtual type (with only
    > abstract methods), or a concrete type (with no abstract methods).
    > It is arguable that abstract classes should be used at all (inheritance
    > from
    > anything but an interface is pure evil, but that's another story for
    > another
    > camp fire).
    >

    I'll bite. Why never use abstract classes?
     
    Ryan Stewart, Dec 26, 2004
    #9
  10. Ryan Stewart wrote:
    > "Tony Morris" <> wrote in message
    > news:Xbvzd.88751$...
    >
    >>Abstract classes should never be used as a pure virtual type (with only
    >>abstract methods), or a concrete type (with no abstract methods).
    >>It is arguable that abstract classes should be used at all (inheritance
    >>from
    >>anything but an interface is pure evil, but that's another story for
    >>another
    >>camp fire).
    >>

    >
    > I'll bite. Why never use abstract classes?
    >
    >


    in Java, they are the 'same' as in they tell you that a given any
    derived/implementing class has those particular methods and also can be
    substituted when the interface/abstract class type is used as the
    referencing type.

    However, in java a class can only have one base class, but can implement
    many different interfaces at the same time.

    It comes down to cohesion and coupling.

    In C++ pure virtual abstract classes are just about the same...(ignoring
    the differences ;- )
     
    Andrew McDonagh, Dec 26, 2004
    #10
  11. Raymond Martineau

    Ulf Nordlund Guest

    Andrew McDonagh skrev:
    > Ryan Stewart wrote:
    >
    >> "Tony Morris" <> wrote in message
    >> news:Xbvzd.88751$...
    >>
    >>> Abstract classes should never be used as a pure virtual type (with only
    >>> abstract methods), or a concrete type (with no abstract methods).
    >>> It is arguable that abstract classes should be used at all
    >>> (inheritance from
    >>> anything but an interface is pure evil, but that's another story for
    >>> another
    >>> camp fire).
    >>>

    >>
    >> I'll bite. Why never use abstract classes?
    >>

    >
    > in Java, they are the 'same' as in they tell you that a given any
    > derived/implementing class has those particular methods and also can be
    > substituted when the interface/abstract class type is used as the
    > referencing type.
    >
    > However, in java a class can only have one base class, but can implement
    > many different interfaces at the same time.
    >
    > It comes down to cohesion and coupling.
    >
    > In C++ pure virtual abstract classes are just about the same...(ignoring
    > the differences ;- )
    >


    I don't understand Andrew's explanation on why abstract classes
    shouldn't be used... Are there any *practical* reasons why they should
    be avoided? (An example?)
    /ulf
     
    Ulf Nordlund, Dec 26, 2004
    #11
  12. Take for example the JTable swing component.

    It displays the data contained within a TableModel. However, TableModel
    is an interface - not a class.

    This allows us to implement the same TableModel interface in any way we
    like, and then give our own specialized model to the Jtable. JTable
    does not need to know about or even guess how the tableModel is actually
    implemented.

    If JTable only ever knew about the abstract classes, then it would be
    assuming that ALL tableModels were of the same base type, having the
    same base implementation.

    However, most tableModels do NOT have the same base type or are
    implemented in the same way. Because JTable uses a generic TableModel
    interface, we can implement it however we like. For example, we may have
    a ODBC class that Implements the TableModel interface. Or a class that
    gets its data from XML and implements the TableModel interface so that
    JTable can 'see' the data.

    Now for convenience, Java provides a range of off-the-shelf classes
    which do most of the grunt work :

    public abstract class AbstractTableModel implements TableModel {
    ....
    }


    public class DefaultTableModel extends AbstracttableModel {
    ....
    }

    etc.

    But these 'assume' how most tableModels would work, but they may not be
    appropriate for ours.

    Its all about having a flexible design - anyone can implement an one or
    more interfaces at the same time, but all Java objects can only ever
    have one base class.

    HTH

    Andrew



    Ulf Nordlund wrote:
    > Andrew McDonagh skrev:
    >
    >> Ryan Stewart wrote:
    >>
    >>> "Tony Morris" <> wrote in message
    >>> news:Xbvzd.88751$...
    >>>
    >>>> Abstract classes should never be used as a pure virtual type (with only
    >>>> abstract methods), or a concrete type (with no abstract methods).
    >>>> It is arguable that abstract classes should be used at all
    >>>> (inheritance from
    >>>> anything but an interface is pure evil, but that's another story for
    >>>> another
    >>>> camp fire).
    >>>>
    >>>
    >>> I'll bite. Why never use abstract classes?
    >>>

    >>
    >> in Java, they are the 'same' as in they tell you that a given any
    >> derived/implementing class has those particular methods and also can
    >> be substituted when the interface/abstract class type is used as the
    >> referencing type.
    >>
    >> However, in java a class can only have one base class, but can
    >> implement many different interfaces at the same time.
    >>
    >> It comes down to cohesion and coupling.
    >>
    >> In C++ pure virtual abstract classes are just about the
    >> same...(ignoring the differences ;- )
    >>

    >
    > I don't understand Andrew's explanation on why abstract classes
    > shouldn't be used... Are there any *practical* reasons why they should
    > be avoided? (An example?)
    > /ulf
     
    Andrew McDonagh, Dec 26, 2004
    #12
  13. Raymond Martineau

    Sudsy Guest

    Andrew McDonagh wrote:
    > Ryan Stewart wrote:

    <snip>
    >> I'll bite. Why never use abstract classes?
    >>

    >
    > in Java, they are the 'same' as in they tell you that a given any
    > derived/implementing class has those particular methods and also can be
    > substituted when the interface/abstract class type is used as the
    > referencing type.
    >
    > However, in java a class can only have one base class, but can implement
    > many different interfaces at the same time.


    So Sun obviously made a huge mistake with the java.awt.event.XXXAdapter
    classes! Sorry, but I don't buy into "absolutes". The example I provided
    actually serves an important role in GUI development. It's a lot easier
    (and cleaner) to write something like this:

    addWindowListener( new WindowAdapter() {
    public void windowClosing( WindowEvent e ) {
    System.exit( 12 );
    }
    } );

    than have the class implement the WindowListener and have 6 out of the
    7 methods be empty. YMMV
     
    Sudsy, Dec 26, 2004
    #13
  14. I don't quite understand the problem you (seem) to have, maybe I'm
    mis-reading your words...but


    Sun, myself and others have no problem with adapter classes. Sun made
    these adapter classes available because lots of people only need to
    implement specific parts of the interface, not all of them.

    By having a single WindowListener interface it saved having to have
    multiple specific event listener interfaces.

    The adapter pattern is great for this.

    However, the Sun code isn't designed to reference objects by the
    xxxAdapter type, it references via the Interface the adapters (stub)
    implement.

    Andrew



    Sudsy wrote:
    > Andrew McDonagh wrote:
    >
    >> Ryan Stewart wrote:

    >
    > <snip>
    >
    >>> I'll bite. Why never use abstract classes?
    >>>

    >>
    >> in Java, they are the 'same' as in they tell you that a given any
    >> derived/implementing class has those particular methods and also can
    >> be substituted when the interface/abstract class type is used as the
    >> referencing type.
    >>
    >> However, in java a class can only have one base class, but can
    >> implement many different interfaces at the same time.

    >
    >
    > So Sun obviously made a huge mistake with the java.awt.event.XXXAdapter
    > classes! Sorry, but I don't buy into "absolutes". The example I provided
    > actually serves an important role in GUI development. It's a lot easier
    > (and cleaner) to write something like this:
    >
    > addWindowListener( new WindowAdapter() {
    > public void windowClosing( WindowEvent e ) {
    > System.exit( 12 );
    > }
    > } );
    >
    > than have the class implement the WindowListener and have 6 out of the
    > 7 methods be empty. YMMV
     
    Andrew McDonagh, Dec 26, 2004
    #14
  15. Raymond Martineau

    Chris Smith Guest

    Andrew McDonagh <2s.com> wrote:
    > Take for example the JTable swing component.
    >
    > It displays the data contained within a TableModel. However, TableModel
    > is an interface - not a class.


    This example, of course, quickly reaches ad absurdum, as do most
    examples of this pseudo-truth. Where this leaves the practical world is
    when you start looking at specific examples:

    > However, most tableModels do NOT have the same base type or are
    > implemented in the same way. Because JTable uses a generic TableModel
    > interface, we can implement it however we like. For example, we may have
    > a ODBC class that Implements the TableModel interface. Or a class that
    > gets its data from XML and implements the TableModel interface so that
    > JTable can 'see' the data.


    Except, of course, that you'd never want your database access code or
    XML parsing code to be aware of Swing. Here's where it *does* come down
    to coupling. It's better for thise data-access and parsing code to
    provide a generic interface that's usable by anyone, rather than
    something specific to the Swing GUI API. As a result, you get the
    frequent pattern of a model adapter; that is something like:

    public class XMLTableModel implements TableModel
    {
    public XMLTableModel(org.w3c.dom.Document doc) { ... }
    ...
    }

    And, since that class has no purpose other than to adapt data to Swing's
    TableModel, it wouldn't naturally extend any other class and suddenly
    ceases to make a good example of why something might want to extend some
    other class and also implement TableModel. In fact, it turns out that
    any linking of an underlying data source with an Swing model interface
    is best accomplished by composition rather than inheritance.

    The example also extends to many other uses of interfaces. The only
    time it doesn't apply, in fact, is when an interface exists in the core
    part of the standard API (for example, java.lang) and is therefore
    automatically a dependent concept for any class -- an example is
    Comparable or Cloneable.

    In the end, interfaces are generally preferable for this kind of work;
    but the reason is more an abstract design issue than a practical need to
    avoid multiple inheritance.

    This is all considerably short of Tony's "never use abstract classes,
    ever", but I'm ignoring that because Tony's obviously having a bad week.

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Dec 26, 2004
    #15
  16. Chris Smith wrote:

    snipped..

    >
    > Except, of course, that you'd never want your database access code or
    > XML parsing code to be aware of Swing.



    snipped...

    Absolutely, but coming up with a 'real world example' during the xmas
    holidays is hard for me, as I don't (thank god) have access to my work
    source code. Even if I did, it would be a very domain explicit example
    which most people here wouldn't understand, as they wouldn't have worked
    in that domain.

    So this leaves this 'real world' example of why Sun have choosen this
    particular idiom, albiet in a very simplified way.
     
    Andrew McDonagh, Dec 26, 2004
    #16
  17. Raymond Martineau

    Ryan Stewart Guest

    "Andrew McDonagh" <2s.com> wrote in message
    news:cqmpg3$ie1$2surf.net...
    > Absolutely, but coming up with a 'real world example' during the xmas
    > holidays is hard for me, as I don't (thank god) have access to my work
    > source code. Even if I did, it would be a very domain explicit example
    > which most people here wouldn't understand, as they wouldn't have worked
    > in that domain.
    >
    > So this leaves this 'real world' example of why Sun have choosen this
    > particular idiom, albiet in a very simplified way.


    I remain unconvinced. Interfaces and abstract classes are two different
    animals intended for two different purposes. Maybe in your work, interfaces
    predominant, but should java.lang.Number be an interface? What about
    java.util.AbstractCollection, java.io_OutputStream, or java.text.DateFormat?
    If your answer is yes, you are at the least promoting heavy-duty code
    duplication.
     
    Ryan Stewart, Dec 26, 2004
    #17
  18. Raymond Martineau

    Chris Smith Guest

    Andrew McDonagh <2s.com> wrote:
    > Absolutely, but coming up with a 'real world example' during the xmas
    > holidays is hard for me, as I don't (thank god) have access to my work
    > source code.


    I think it's deeper than that. In fact, I don't think that a "real
    world" example along the lines you're suggesting exists. Almost by
    definition, it would introduce improper dependencies between modules.

    Not that I disagree with using interfaces for this kind of thing. An
    interface, in fact, is quite appropriate since it suggests something
    different at an abstract level; that there is a way of interacting with
    something that doesn't say anything about the implementation; versus an
    abstract class, which suggests a partial implementation that can be
    modified by overloading. So interfaces are great. Nevertheless, I
    don't think the practical multiple inheritance problem really exists
    with this kind of situation.

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Dec 26, 2004
    #18
  19. Raymond Martineau

    Chris Smith Guest

    Andrew McDonagh <2s.com> wrote:
    > Sun, myself and others have no problem with adapter classes.


    Sudsy was responding to Tony Morris, who said:

    "It is arguable that abstract classes should be used at all
    (inheritance from anything but an interface is pure evil, but
    that's another story for another camp fire)."

    That cause Ryan Stewart to ask why, and hence this subthread. Your
    position obviously isn't as extreme as Tony's, so Sudsy's response
    doesn't apply to you.

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Dec 26, 2004
    #19
  20. Raymond Martineau

    Chris Smith Guest

    Chris Smith <> wrote:
    > something that doesn't say anything about the implementation; versus an
    > abstract class, which suggests a partial implementation that can be
    > modified by overloading.


    Meant to say overriding. Sorry for the confusion.

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Dec 26, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Honne Gowda A
    Replies:
    2
    Views:
    881
    Karl Heinz Buchegger
    Oct 31, 2003
  2. andy6
    Replies:
    2
    Views:
    764
    andy6 via DotNetMonster.com
    Jun 9, 2006
  3. Replies:
    2
    Views:
    933
    Bengt Richter
    Aug 1, 2005
  4. Richard Tobin
    Replies:
    24
    Views:
    795
  5. Bob
    Replies:
    5
    Views:
    262
Loading...

Share This Page