CS 535 Object-Oriented Programming & Design Spring Semester, 1999 Coupling & Function Pointers |
||
---|---|---|
© 1999, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 15-Feb-99 |
Coupling & Function Pointers
We will look at two situations. First, a class needs to parse a string into name-value pairs. Second, we wish to write a timer class that will execute an object’s method at a given time. In each case notice the coupling involved.
Parsing Name-Value Pairs
The format of the string is:
name=value;name2=value2;...;nameN=valueN;
Notice the coupling of the class Foo to the StringTokenizer class. Even if you know nothing about the StringTokenizer, there is obvious coupling.
import java.util.StringTokenizer; class Foo { public static final String PAIR_TERMINATOR = ";"; public static final String NAME_VALUE_SEPARATOR = "="; String[] names; String[] values; public void bar( String namesValues ) { StringTokenizer parser = new StringTokenizer( namesValues, PAIR_TERMINATOR ); int numberOfPairs = parser.countTokens(); names = new String[ numberOfPairs ]; values = new String[ numberOfPairs ]; for (int k = 0; k < numberOfPairs; k++ ) { names[k] = parser.nextToken(NAME_VALUE_SEPARATOR); if (names[k].startsWith( PAIR_TERMINATOR ) ) names[k] = names[k].substring( 1); values[k] = parser.nextToken( PAIR_TERMINATOR ); if (values[k].startsWith( NAME_VALUE_SEPARATOR ) ) values[k] = values[k].substring( 1); } } }
Scheduling Methods
Solution 1
The class that has a method to be executed later has to implement an interface. This means that the class has to know that it will be used in this manner. It has to have a method that will be called later.
public interface Executable { public void execute(); } public class Scheduler { // code that does scheduling not shown Executable toExecute; public Scheduler( Executable anExcutable ) { toExecute = anExcutable; } public void doIt() { toExecute.execute(); } } public class AClass implements Executable { //lots of methods/field not shown public void execute() { System.out.println( "Done" ); } }
Solution 2 - Use an Adapter
In this solution AClass does not know one of its methods will be scheduled later. A third class, AclassAdapter, is created to adapt the Executable interface and AClass.
public class AClassAdapter implements Executable { AClass myClassObject; public AClassAdapter( AClass anObject ) { myClassObject = anObject; } public void execute() { myClassObject.foo(); } } public class AClass{ //lots of methods/field not shown public void foo(){ System.out.println( "Done" ); } }Sample Use AClass sample = new AClass(); AClassAdapter thirdParty = new AClassAdapter( sample ); Scheduler test = new Scheduler( thirdParty ); test.doIt();
Solution 3 - Use Method Pointers (Java)
In this solution, the Scheduler gets a string containing the name of the method to execute. Using Java’s reflection the method can be executed. Notice how little the Schedule class knows about AClass.
public class Scheduler { Object executee; Method toExecute; public Scheduler( Object anObject, String methodName ) throws NoSuchMethodException, IllegalAccessException { Class objectsClass = anObject.getClass(); Class[] argumentTypes = {}; toExecute = objectsClass.getMethod( methodName, argumentTypes ); executee = anObject; int modifiers = toExecute.getModifiers(); if ( !Modifier.isPublic( modifiers ) ) throw new IllegalAccessException("Method " + methodName + " is not public in class " + objectsClass.getName() ); } public void doIt() throws InvocationTargetException { try { Object[] noArguments = {}; toExecute.invoke( executee, noArguments ); } catch (IllegalAccessException willNotOccur ) { } } }Sample Use Scheduler test = new Scheduler( new AClass(), "foo" ); test.doIt();
Solution 3 - Use Method Pointers (C++)
We can use pointers to do a similar thing in C++. The syntax can be a little complicated, so I will provide a little background.
Function Pointers in C++
In this example simplePointer has one argument. The argument is a pointer to a function, which has an int argument and returns an int. The argument name is functionPointer.
#include <iostream.h> int sampleFunction( int x ){ return x + 1; } void simplePointer( int (*functionPointer)( int ) ) { int result = functionPointer( 5 ); cout << "The result " << result << endl; } int main() { cout << "in main" << endl; simplePointer( &sampleFunction ); };
Function Member Pointer The name of the class is part of type of a pointer to a function member. The function "methodTest" has two arguments. The first is a pointer to an object of type “Foo”. The second is to a function member of class Foo. The function member has no arguments and void return type.
class Foo { public: void test(); }; void Foo::test() { cout << "Hi mom\n"; } void methodTest( Foo *object, void (Foo::*methodPointer) () ){ (object->*methodPointer)(); } int main() { cout << "in main" << endl; Foo *bar = new Foo; bar->test(); methodTest( bar, &Foo::test ); };
Template Function Member Pointer Using templates, we can reduce the coupling on the class of the object (object abstraction decoupling). Note that “ClassType” is a template variable, whose values are types.
template <class ClassType> void better( ClassType *y, void (ClassType::*methodPointer)() ) { (y->*methodPointer)(); }; int main() { cout << "in main" << endl; Foo *bar = new Foo; bar->test(); better( bar, &Foo::test ); };
The Scheduler class Finally the scheduler class in C++
template <class ClassType>
class Scheduler { private: ClassType *executee; void (ClassType::*toExecute) (); public: Scheduler( ClassType *object, void (ClassType::*aMethod) () ); void doIt(); }; template <class ClassType> Scheduler<ClassType>::Scheduler( ClassType *object, void (ClassType::*aMethod) () ) { executee = object; toExecute = aMethod; }; template <class ClassType> void Scheduler<ClassType>::doIt() { (executee->*toExecute)(); } int main() { cout << "in main" << endl; Foo bar; bar.test(); Scheduler<Foo> testIt( &bar, &Foo::test); testIt.doIt(); };
Copyright © 1999 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
All rights reserved.
Previous    visitors since 15-Feb-99    Next