Difference between revisions of "Template Method"

From CDOT Wiki
Jump to: navigation, search
(Apache Excalibur)
(Apache Excalibur)
Line 78: Line 78:
 
=== Apache Excalibur===
 
=== Apache Excalibur===
  
The following examples shows that class '''CascadingErrorTestCase''' is extending from an abstract class called '''TestCase''', possibly in the '''junit.framework.TestCase''' package. In this case, the '''testConstructor()''' and the '''testGetCause()''' would be the altered for testing purposes.
+
The following are portions of the code found in '''CascadingErrorTestCase.java''' and '''CascadingExceptionTestCase.java''' files.<br/>
 
+
When comparing these two files, we can see that the two files share a common package '''org.apache.avalon.framework.test'''.
 
<pre>
 
<pre>
/*
 
* Licensed to the Apache Software Foundation (ASF) under one or more
 
* contributor license agreements.  See the NOTICE file distributed with
 
* this work for additional information regarding copyright ownership.
 
* The ASF licenses this file to You under the Apache License, Version 2.0
 
* (the "License"); you may not use this file except in compliance with
 
* the License.  You may obtain a copy of the License at
 
*
 
*  http://www.apache.org/licenses/LICENSE-2.0
 
*
 
* Unless required by applicable law or agreed to in writing, software
 
* distributed  under the  License is distributed on an "AS IS" BASIS,
 
* WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 
* implied.
 
*
 
* See the License for the specific language governing permissions and
 
* limitations under the License.
 
*/
 
  
 
package org.apache.avalon.framework.test;
 
package org.apache.avalon.framework.test;
Line 107: Line 89:
 
import junit.framework.TestCase;
 
import junit.framework.TestCase;
  
/**
+
</pre>
* TestCase for {@link CascadingError}.
+
 
*
+
From the following, we can see that the class '''CascadingErrorTestCase''' is extending from an abstract class called '''TestCase'''. This is the same case in the '''CascadingExceptionTestCase.java''' file. Hence, this shows that these two classes are subclasses of the class '''TestCase'''.
* @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+
 
* @version $Id$
+
<pre>
*/
 
 
public class CascadingErrorTestCase extends TestCase
 
public class CascadingErrorTestCase extends TestCase
 
{
 
{
 +
}
 +
</pre>
 +
 +
When looking at the testConstructor() in both files, we can see that it implements different methods, therefore its altering the algorithm operation of the file. The general steps in the constructor is not altered, but the implementation is different.
 +
<pre>
 +
    // From CascadingErrorTestCase.java
 
     public void testConstructor()
 
     public void testConstructor()
 
     {
 
     {
Line 126: Line 113:
 
         //assertNotNull( new CascadingError() );
 
         //assertNotNull( new CascadingError() );
 
     }
 
     }
 
+
</pre>
    public void testGetCause()
+
<pre>
 
     {
 
     {
         RuntimeException re = new RuntimeException();
+
         assertNotNull( new CascadingException( null, null ) );
         CascadingError e = new CascadingError( "msg", re );
+
         assertNotNull( new CascadingException( "msg", null ) );
 
+
         assertNotNull(
         assertEquals( re, e.getCause() );
+
                new CascadingException( "msg", new RuntimeException() ) );
 
+
         assertNotNull( new CascadingException( null, new RuntimeException() ) );
        e = new CascadingError( "msg", null );
 
        assertNull( e.getCause() );
 
 
 
         // default to jdk 1.3 cause (not that it seems to help,
 
        // but it still makes sense)
 
        /*Exception exc = new Exception("blah");
 
        try
 
        {
 
            try
 
            {
 
                throw exc;
 
            }
 
            catch( Exception ex )
 
            {
 
                throw new CascadingError();
 
            }
 
        }
 
        catch( CascadingError ex )
 
        {
 
            ex.getCause();
 
        }*/
 
    }
 
  
    public void testCasts()
+
        assertNotNull( new CascadingException( "msg" ) );
    {
+
         // ambiguous assertNotNull( new CascadingException( null ) );
        CascadingError e = new CascadingError( "msg", null );
+
         //assertNotNull( new CascadingException() );
         assertTrue( e instanceof Error );
 
         assertTrue( e instanceof CascadingThrowable );
 
 
     }
 
     }
 
}
 
 
</pre>
 
</pre>
  

Revision as of 17:41, 19 March 2007

Template Method

Template Method, a class behavioral pattern, provides the general steps of a method while deferring the implementation to its subclasses. Used to encapsulate algorithms, it can help reduce code duplication and maximizes the reuse of subclasses. Generally, an abstract base class is created, defining a template method of an algorithm. Later on, the subclasses can alter and implement the behavior.

UML Diagram

TemplateMethod.JPG

Source from GoF's Design Patterns - Elements of Reusable Object -Oriented Software (pg. 325)

Code Examples

Java

//Coercion Polymorphism
abstract class Add {
   public abstract double add(double d1, double d2);//template
}
class AddAnyTypeNumber extends Add{
    public double add(double d1, double d2) {
        return d1 + d2;
    }
}
class Test {
   public static void main(String[] args) {
       double d1 = 10.5, d2 = 9.5;
       float f1 = 11.5f, f2 = 12.5f;
       long l1 = 1, l2 = 2;
       int i1 = 3, i2 = 4;
       short s1 = 7, s2 = 8;
       byte b1 = 5, b2 = 6;
       
       AddAnyTypeNumber addNumber = new AddAnyTypeNumber();
       
       System.out.println(addNumber.add(d1,d2));
       System.out.println((float)addNumber.add(f1,f2));
       System.out.println((long)addNumber.add(l1,l2));
       System.out.println((int)addNumber.add(i1,i2));
       System.out.println((short)addNumber.add(s1,s2));
       System.out.println((byte)addNumber.add(b1,b2));
   }
}

Source from Javacamp, http://www.javacamp.org/designPattern/template.html/

PHP 5.0

abstract class AbstractClass {
    public final function templateMethod() {
        print "AbstractClass::templateMethod() called.\n";
        
        $this->mandatoryOperation();
        $this->optionalOperation();
    }

    protected abstract function mandatoryOperation();

    protected function optionalOperation() {
    }
}
class ConcreteClass extends AbstractClass {
    protected function mandatoryOperation() {
        print "ConcreteClass::mandatoryOperation() called.\n";
    }

    protected function optionalOperation() {
        print "ConcreteClass::optionalOperation() called.\n";
    }
}

Source from Zend Technologies, http://www.zend.com/zend/php5/php5-OOP.php?article=php5-OOP&kind=ph&id=3204&open=1&anc=0&view=1

Real-life Application

Apache Excalibur

The following are portions of the code found in CascadingErrorTestCase.java and CascadingExceptionTestCase.java files.
When comparing these two files, we can see that the two files share a common package org.apache.avalon.framework.test.


package org.apache.avalon.framework.test;

import org.apache.avalon.framework.CascadingError;
import org.apache.avalon.framework.CascadingThrowable;

import junit.framework.TestCase;

From the following, we can see that the class CascadingErrorTestCase is extending from an abstract class called TestCase. This is the same case in the CascadingExceptionTestCase.java file. Hence, this shows that these two classes are subclasses of the class TestCase.

public class CascadingErrorTestCase extends TestCase
{
}

When looking at the testConstructor() in both files, we can see that it implements different methods, therefore its altering the algorithm operation of the file. The general steps in the constructor is not altered, but the implementation is different.

    // From CascadingErrorTestCase.java
    public void testConstructor()
    {
        assertNotNull( new CascadingError( null, null ) );
        assertNotNull( new CascadingError( "msg", null ) );
        assertNotNull( new CascadingError( "msg", new RuntimeException() ) );
        assertNotNull( new CascadingError( null, new RuntimeException() ) );

        //assertNotNull( new CascadingError( "msg" ) );
        //ambiguous assertNotNull( new CascadingError( null ) );
        //assertNotNull( new CascadingError() );
    }
    {
        assertNotNull( new CascadingException( null, null ) );
        assertNotNull( new CascadingException( "msg", null ) );
        assertNotNull(
                new CascadingException( "msg", new RuntimeException() ) );
        assertNotNull( new CascadingException( null, new RuntimeException() ) );

        assertNotNull( new CascadingException( "msg" ) );
        // ambiguous assertNotNull( new CascadingException( null ) );
        //assertNotNull( new CascadingException() );
    }

References

BTP600 Wiki Page
Template Method on Wikipedia