|
The Strategy Pattern
An Introduction with Examples in Java |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
In UML
In UML
package math;
/**
* A Metric is a function that satisfies the following properties
* for all a, b, c:
*
* distance(a,b) >= 0
* distance(a,b) == 0 iff a == b
* distance(a,b) == distance(b,a)
* distance(a,b) <= distance(a,c) + distance(b,c)
*
* (The last of these properties is called the triangle inequality.)
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public interface Metric
{
/**
* Calculate the distance between two n-dimensional points
*
* @param a One n-dimensional point
* @param b Another n-dimensional point
* @return The distance
*/
public abstract double distance(double[] a, double[] b);
}
package math;
/**
* The Euclidean metric (i.e., the notion of distance that
* most people are familiar with)
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class EuclideanMetric
implements Metric
{
/**
* Calculate the distance between two n-dimensional points
* (required by Metric)
*
* Note: For simplicity, this method does not confirm that the
* two arrays are the same size. It uses the smaller size.
*
* @param a One n-dimensional point
* @param b Another n-dimensional point
* @return The distance
*/
public double distance(double[] a, double[] b)
{
double result;
int n;
result = 0.0;
n = Math.min(a.length, b.length);
for (int i=0; i<n; i++)
{
result += Math.pow(a[i]-b[i], 2.0);
}
return Math.sqrt(result);
}
}
package math;
/**
* The rectilinear metric (i.e., the sum of the absolute values of the
* differences between the elements). This is sometimes also
* called the Manhattan metric (because it is the distance you have to walk
* between two points in a city that is layed out on a grid).
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class RectilinearMetric
implements Metric
{
/**
* Calculate the distance between two n-dimensional points
* (required by Metric)
*
* Note: For simplicity, this method does not confirm that the
* two arrays are the same size. It uses the smaller size.
*
* @param a One n-dimensional point
* @param b Another n-dimensional point
* @return The distance
*/
public double distance(double[] a, double[] b)
{
double result;
int n;
result = 0.0;
n = Math.min(a.length, b.length);
for (int i=0; i<n; i++)
{
result += Math.abs(a[i]-b[i]);
}
return result;
}
}
package math;
/**
* The supremum metric. This is sometimes also
* called the uniform metric and/or the infinity metric.
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class SupremumMetric
implements Metric
{
/**
* Calculate the distance between two n-dimensional points
* (required by Metric)
*
* Note: For simplicity, this method does not confirm that the
* two arrays are the same size. It uses the smaller size.
*
* @param a One n-dimensional point
* @param b Another n-dimensional point
* @return The distance
*/
public double distance(double[] a, double[] b)
{
double result, term;
int n;
result = Math.abs(a[0]-b[0]);
n = Math.min(a.length, b.length);
for (int i=1; i<n; i++)
{
term = Math.abs(a[i]-b[i]);
if (term > result) result = term;
}
return result;
}
}
import java.awt.*;
import java.awt.image.*;
import math.*;
/**
* A Posterizer reduces the number of colors in an image
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class Posterizer
{
private double[] aa, bb;
private Metric metric;
private static final int[] BLACK = { 0, 0, 0};
private static final int[] WHITE = {255,255,255};
/**
* Default Constructor
*/
public Posterizer()
{
aa = new double[3];
bb = new double[3];
}
/**
* Determine the distance between two colors
*
* @param a The RGB values of one color
* @param b The RGB values of the other color
* @return The distance
*/
private double distance(int[] a, int[] b)
{
double result;
for (int i=0; i<3; i++)
{
aa[i] = a[i];
bb[i] = b[i];
}
result = Double.POSITIVE_INFINITY;
if (metric != null) result = metric.distance(aa, bb);
return result;
}
/**
* Set the Metric to use to determine the distance
* between colors
*
* @param metric The Metric to use
*/
public void setMetric(Metric metric)
{
this.metric = metric;
}
/**
* Convert an image to black-and-white (NOT gray scale)
*
* @param image The BufferedImage to convert
*/
public void toBlackAndWhite(BufferedImage image)
{
ColorModel colorModel;
double blackDistance, whiteDistance;
int height, packedPixel, packedBlack, packedWhite, width;
int[] pixel;
pixel = new int[3];
height = image.getHeight();
width = image.getWidth();
colorModel = image.getColorModel();
packedBlack = colorModel.getDataElement(BLACK,0);
packedWhite = colorModel.getDataElement(WHITE,0);
for (int x=0; x<width; x++)
{
for (int y=0; y<height; y++)
{
packedPixel = image.getRGB(x, y);
colorModel.getComponents(packedPixel, pixel, 0);
blackDistance = distance(pixel, BLACK);
whiteDistance = distance(pixel, WHITE);
if (blackDistance < whiteDistance)
image.setRGB(x, y, 0x00000000);
else
image.setRGB(x, y, 0xFFFFFFFF);
}
}
}
}