<pre name="code" class="cpp">package org.rui.pattern;
import junit.framework.TestCase;
/**
* 分解共同性(Factoring Commonality )
* 应用“一次且只能有一次” 原则产生最基本的模式,将变化的那部分代码放到方 法里。 这可以用两种方法来表达: 策略模式(Strategy
* ):运行时刻选择算法 另外,Strategy 模式还可以添加一个“上下文(context)”,这个 context 可以 是一个代理类(surrogate
* class),用来控制对某个特定 strategy 对象的选择和使 用。
*
* @author Administrator
*
*/
public class StrategyPattern extends TestCase
{
MinimaSolver solver = new MinimaSolver(new LeastSquares());
double[] line = { 1.0, 2.0, 1.0, 2.0, -1.0, 3.0, 4.0, 5.0, 4.0 };
public void test()
{
System.out.println(solver.minima(line));
solver.changeAlgorithm(new Bisection());
System.out.println(solver.minima(line));
// System.out.println(Arrays2.toString(solver.minima(line)));
}
public static void main(String args[])
{
junit.textui.TestRunner.run(StrategyPattern.class);
}
} // /:~
/**
* 请注意模板方法(template method)和 strategy 模式的相似性——template method
* 最显著的特征是它有多个方法需要调用,它是分段的实现某个功能。但是,这 并不是说 strategy 对象就不能有多个方法调用;考虑 Shalloway
* 给出的的订单处理系 统的例子,每一个 strategy 包含不同的国别信息。 JDK 里 Strategy 模式的例子:comparator
* objects.
*/
package org.rui.pattern;
import java.util.*;
/**
* 如果 Java 有模板(template)机制,上面这种(类型安全的)迭代器很容易就可 以返回某一特定类型的对象。但是没有模板机制,就必须得返回
* generic Objects,或 者为每一种需要遍历的对象都手工添加代码。这里我会使用前一种方法。
* 另外一个需要在设计时决定的问题是什么时候判定对象的类型。一种方法是以迭 代器遍历的第一个对象的类型(作为迭代器的类型),但是这种方法当容器类根据它
* 自己的内部算法(比如 hash 表)重新为对象排序时就会有问题,这样同一迭代器的两
* 次遍历就可能得到不同的结果。安全的做法是在构造迭代器的时候让用户指定迭代器 的类型。 最后的问题是如何构建迭代器。我们不可能重写现有的 Java
* 类库,它已经包含了 枚举器和迭代器。但是,我们可以用 Decorator 模式简单的创建一个枚举器或者迭代
* 器的外覆类,产生一个具有我们想要的迭代行为(本例中,指在类型不正确的时候抛 出 RuntimeException
* 异常)的新对象,而这个新对象跟原来的枚举器或者迭代器有相 同的接口,这样一来,它就可以用在相同的场合(或许你会争论说这实际上是 Proxy
* 模式,但是从它的目的(intent)来说它更像 Decorator 模式)。
*
* @author Administrator
*
*/
public class TypedIterator implements Iterator
{
private Iterator imp;
private Class type;
public TypedIterator(Iterator it, Class type)
{
imp = it;
this.type = type;
}
public boolean hasNext()
{
return imp.hasNext();
}
public void remove()
{
imp.remove();
}
public Object next()
{
Object obj = imp.next();
if (!type.isInstance(obj))
throw new ClassCastException("TypedIterator for type " + type
+ " encountered type: " + obj.getClass());
return obj;
}
} // /:~
package org.rui.pattern;
import junit.framework.*;
/**
* 应用程序框架使你可以从一个或者一系列类继承下来,进而创建一个新的应用程 序,你可以重用既有类的大多数代码并且按照你自己的需要覆写其中的某些方法,从
* 而实现应用程序的定制。Template Method 是应用程序框架的一个基本概念,它通常隐
* 藏在(框架)背后,通过调用基类的一组方法(有些方法你可能已经覆写 (overridden)过了)来驱动应用程序。
*
* Template Method 的一个重要特征是:它是在基类里定义的,而且不能够被(派生 类)更改。有时候它是私有方法(private
* method),但实际上它经常被声明为 final。它通过调用其它的基类方法(覆写过的)来工作,但它经常是作为初始化过程
* 的一部分被调用的,这样就没必要让客户端程序员能够直接调用它了。
*
* @author Administrator
*
*/
abstract class ApplicationFramework
{
public ApplicationFramework()
{
templateMethod(); // 危险的
}
abstract void customize1();
abstract void customize2();
final void templateMethod()
{
for (int i = 0; i < 5; i++)
{
customize1();
customize2();
}
}
}
// Create a new "application":
class MyApp extends ApplicationFramework
{
void customize1()
{
System.out.print("Hello ");
}
void customize2()
{
System.out.println("World!");
}
}
public class TemplateMethod extends TestCase
{
MyApp app = new MyApp();
public void test()
{// The MyApp constructor does all the work.
// This just makes sure it will complete
// without throwing an exception.
}
public static void main(String args[])
{
junit.textui.TestRunner.run(TemplateMethod.class);
}
} // /:~