## CS 696: Advanced OO Spring Semester, 1997 Doc 15, Functors, Command, Template Mehod

To Lecture Notes Index
San Diego State University -- This page last updated Apr 15, 1997

### Contents of Doc 15, Functors, Command, Template Mehod

 Functor slide # 1 Command slide # 6 Template Method slide # 10

References

Design Patterns: Elements of Resuable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1995

`Doc 15, Functors, Command, Template Mehod Slide # 1`

# Functor

Functions as Objects

Functors are functions that behave like objects

They serve the role of a function, but can be created, passed as parameters, and manipulated like objects

A functor is a class with a single member function

Example - Sorting

```class SortedList
{
private Object[] listElements;

private void sortTheList()
{
// use fancy sort method like quicksort
blah
blah

if ( listElement[k] > listElement[k+j] )
{
swap or something
}
}
}```

`Doc 15, Functors, Command, Template Mehod Slide # 2`
How do we compare Elements?

We don't know the type?

We may wish to sort the same objects in different ways

by name
by id
In C++ we could use function pointers, but not in Java

Functor Solution

```abstract class Compare
{
private static final int LESS_THAN = -1;
private static final int GREATER_THAN = 1;
private static final int EQUAL_TO = 0;

public boolean greaterThan( Object a, Object b )
{
int result = compareTo( a, b );
if ( result == GREATER_THAN ) return true;
else return false;

public boolean lessThan( Object a, Object b )
{
int result = compareTo( a, b );
if ( result == LESS_THAN ) return true;
else return false;
}
```

`Doc 15, Functors, Command, Template Mehod Slide # 3`

```public boolean equals( Object a, Object b )
{
int result = compareTo(a,  b );
if ( result == EQUAL_TO ) return true;
else return false;
}

abstract public int compareTo( Object a, Object b );
}

class CompareInt extends Compare
{
public int compareTo( Object a, Object b )
{
if ( (int) a < (int) b )
return LESS_THAN;
else if  ( (int) a > (int) b )
return GREATER_THAN;
else
return EQUAL_TO;
}
}
```

```class CompareString extends Compare
{ blah }
```

```class CompareStudentRecordByID extends Compare
```
```     { blah }
```

```class CompareStudentRecordByAddress extends Compare
```
```     { blah }
```

`Doc 15, Functors, Command, Template Mehod Slide # 4`
```class SortedList
{
private Object[] listElements;
private Compare comparer;

public SortedList( Compare function )
{
comparer = function;
}

private void sortTheList()
{
// use fancy sort method like quicksort
blah
blah

if ( comparer.lessThan(listElement[k], listElement[k+j] ) )
{
swap or something
}
}
}
```

`Doc 15, Functors, Command, Template Mehod Slide # 5`
How Does a Functor Compare to Function Pointers?

Using inheritance we can factor common code to a base class

Same run-time flexibility as function pointer

Lends it self to poor abstractions

Other?

`Doc 15, Functors, Command, Template Mehod Slide # 6`

# Command

Maintains a binding between a receiver and a function

Give much more power than functor

```abstract class Command
{
abstract public void execute();
}

class OpenCommand extends Command
{
private Application opener;

public OpenCommand( Application theOpener )
{
opener = theOpener;
}

public void execute()
{

if ( name != null )
{
Document toOpen = new Document( documentName );
opener.open();
}
}
}
```

`Doc 15, Functors, Command, Template Mehod Slide # 7`
Using Command

```class Menu
{
private Hashtable menuActions = new Hashtable();

Command itemAction )
{
}

public void handleEvent( String itemSelected )
{
Command runMe;
runMe = (Command) menuActions.get( itemSelected );
runMe.execute();
}

// lots of stuff missing
}
```

`Doc 15, Functors, Command, Template Mehod Slide # 8`
MacroCommand

```class MacroCommand extends Command
{
private Vector commands = new Vector();

{
}

public void remove( Command toRemove )
{
}

public void execute()
{
Enumeration commandList = commands.elements();

while ( commandList.hasMoreElements() )
{
Command nextCommand;
nextCommand = (Command) commandList.nextElement();
nextCommand.execute();
}
}
}

```

`Doc 15, Functors, Command, Template Mehod Slide # 9`
When to Use the Command Pattern

When you need an action as a parameter

When you need to specify, queue, and execute requests at different times

When you need to support undo

When you need to support logging changes

When you structure a system around high-level operations built on primitive operations

A Transactions encapsulates a set of changes to data

Systems that use transaction often can use the command pattern

`Doc 15, Functors, Command, Template Mehod Slide # 10`

# Template Method

Polymorphism

```class Account {
public:
void virtual Transaction(float amount)
{ balance += amount;}
Account(char* customerName, float InitialDeposit = 0);
protected:
char* name;
float balance;
}

class JuniorAccount : public Account {
public:     void Transaction(float amount) {//  put code here}
}

class SavingsAccount : public Account {
public:     void Transaction(float amount) {//  put code here}
}

Account* createNewAccount()
{
// code to query customer and determine what type of
// account to create
};

main()
{
Account*  customer;
customer = createNewAccount();
customer->Transaction(amount);```

}
`Doc 15, Functors, Command, Template Mehod Slide # 11`
Deferred Methods

```class Account {
public:
void virtual Transaction() = 0;
}

class JuniorAccount : public Account {
public
void Transaction() { put code here}
}
```

`Doc 15, Functors, Command, Template Mehod Slide # 12`
Template Methods

```class Account {
public:
void Transaction(float amount);
void virtual TransactionSubpartA();
void virtual TransactionSubpartB();
void virtual TransactionSubpartC();
}

void Account::Transaction(float amount)  {
TransactionSubpartA();          TransactionSubpartB();
TransactionSubpartC();          // EvenMoreCode;
}

class JuniorAccount : public Account {
public:          void virtual TransactionSubpartA(); }

class SavingsAccount : public Account {
public:          void virtual TransactionSubpartC(); }

Account*  customer;
customer = createNewAccount();
customer->Transaction(amount);```

`Doc 15, Functors, Command, Template Mehod Slide # 13`
Polymorphism
The Good

Making modifications to program require:

Changing code that creates objects

```Account*  customer;
customer = createNewAccount();
customer->Transaction(amount);
```

`Doc 15, Functors, Command, Template Mehod Slide # 14`
Polymorphism