模板方法模式(Template Method)
·概念
定义一个操作中的算法骨架,而将一些步骤延伸到子类中去,使得子类可以不改变一个算法的结构,即可重新定义该算法的某些特定步骤。这里需要复用的是算法的结构,也就是步骤,而步骤的实现可以在子类中完成。
·使用场合
1)一次性实现一个算法的不变部分,并且将可变的行为留给子类来完成。
2)各子类公共的行为应该被提取出来并集中到一个公共的父类中,避免代码的重复。首先识别现有代码的不同之处,并且把不同部分分离为新的操作,最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3)控制子类的扩展。
·模板方法模式的组成
父类角色:提供模板。
子类角色:为模板提供实现。
范例:
package com.bob.pattern.templatemethod;
/**
* 父类角色:提供模板
*
*/
public abstract class AbstractClass {
//规定步骤。定义一个操作中的算法骨架
public void template(){
this.method1();
this.method2();
this.method3();
}
//如何做由子类自己实现。而将一些步骤延伸到子类中去
public abstract void method1();
public abstract void method2();
public abstract void method3();
}
package com.bob.pattern.templatemethod;
/**
* 子类角色:为模板提供实现
*
*/
public class ConcreteClass extends AbstractClass {
@Override
public void method1() {
System.out.println("step 1");
}
@Override
public void method2() {
System.out.println("step 2");
}
@Override
public void method3() {
System.out.println("step 3");
}
}
package com.bob.pattern.templatemethod;
public class Client {
public static void main(String[] args) {
AbstractClass ac = new ConcreteClass();
ac.template();
}
}
Juint3 在 TestCase 类中应用了模板方法模式:
适配器(Adapter)模式
意图:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能在一起的那些类可以在一起工作。
构成:
目标抽象角色(Target) —— 定义客户要使用的特定领域的接口
适配器(Adapter)—— 调用另一个接口,作为一个转换器
适配器(Adaptee)—— 定义一个接口,Adapter 需要接入
适配器的分类:
类适配器(采取继承的方式)
对象适配器(采取对象组合的方式) 推荐
缺省适配器模式
范例:基于类的继承方式
package com.bob.pattern.adapter;
public interface Target {
public void method1();
}
package com.bob.pattern.adapter;
public class Adaptee {
public void method2(){
System.out.println("目标方法");
}
}
package com.bob.pattern.adapter;
public class Adapter extends Adaptee implements Target {
@Override
public void method1() {
this.method2();
}
}
package com.bob.pattern.adapter;
public class Client {
public static void main(String[] args) {
Target target = new Adapter();
target.method1();
}
}
Junit3也使用了适配器模式,体现在:runBare 方法中,通过 runTest 方法将我们自己编写的testXXX 方法进行了适配,使得 JUnit 可以执行我们自己编写的 TestCase,runTest方法实现如下:
在runTest 方法中,首先获得我们自己编写的testXXX方法所对应的Method 对象(不带参数),然后检查该 Mehod 对象所对应的方法是否是 public 的,如果是则调用 Method 对象的 invoke 方法来执行我们自己编写的 testXXX 方法。
范例:对象适配器
package com.bob.pattern.adapter2;
public interface Target {
public void method1(); //客户能使用的
}
package com.bob.pattern.adapter2;
public class Adaptee {
public void method2(){
System.out.println("执行方法"); //需要调用的方法
}
}
package com.bob.pattern.adapter2;
//适配器
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
@Override
public void method1() {
adaptee.method2();
}
}
package com.bob.pattern.adapter2;
public class Client {
public static void main(String[] args) {
Target target = new Adapter(new Adaptee());
target.method1();
}
}
范例:缺省的适配器模式(AWT,Swing事件模型所采用的模式)
package com.bob.pattern.defaultadapter;
public interface AbstractService {
public void service1();
public void service2();
public void service3();
}
package com.bob.pattern.defaultadapter;
public class ServiceAdapter implements AbstractService {
@Override
public void service1() {
}
@Override
public void service2() {
}
@Override
public void service3() {
}
}
package com.bob.pattern.defaultadapter;
//将方法都继承过来后可以对我们自己感兴趣的方法去重写
public class ConcreteService extends ServiceAdapter {
@Override
public void service1() {
System.out.println("执行业务方法");
}
}
Command(命令模式)
意图: 将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
组成:
1. 客户角色:创建一个具体命令对象,并确定其接收者
2. 命令角色: 声明一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个接口或抽象类实现
3. 具体命令角色: 定义一个接收者和行为之间的弱耦合,实现execute 方法,负责调用接收者的相应操作
4. 请求者角色: 负责调用命令对象执行请求
5. 接收者角色: 负责具体实施的执行一个请求
package com.bob.pattern.command;
//抽象命令角色
public interface Command {
public void execute();
}
package com.bob.pattern.command;
//接收者
public class Receiver {
public void doAction(){
System.out.println("执行操作");
}
}
package com.bob.pattern.command;
//具体命令角色
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
receiver.doAction();
}
}
package com.bob.pattern.command;
//请求者
public class Invoker {
private Command command;
public Invoker(Command command){
this.command = command;
}
public void doInvokerAction(){
command.execute();
}
}
package com.bob.pattern.command;
public class Client {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.doInvokerAction();
}
}
组合模式(Composite):组合模式有时候又叫做部分-整体模式,它使我们树形结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
意图: 将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 模式使得用户对单个对象和组合对象的使用具有一致性。
角色:
Component(抽象构件接口)
--- 为组合的对象声明接口
--- 在某些情况下实现从此接口派生出的所有类共有的默认行为
--- 定义一个接口可以访问及管理它的多个子部件
Leaf(叶部件)
--- 在组合中表示叶节点对象,叶节点没有子节点
--- 定义组合中接口对象的行为
Composite(组合类)
--- 定义有子节点(子部件)的部件的行为
--- 存储子节点(子部件)
--- 在Component接口中实现与子部件相关的操作
Client(客户端)
--- 通过Component 接口控制组合部件的对象
package com.bob.pattern.composite;
public interface Component {
public void doSomething();
}
package com.bob.pattern.composite;
public class Leaf implements Component {
@Override
public void doSomething() {
System.out.println("执行方法");
}
}
package com.bob.pattern.composite;
import java.util.ArrayList;
import java.util.List;
public class Composite implements Component {
private List<Component> list = new ArrayList<Component>();
public void add(Component component){
list.add(component);
}
public void remove(Component component){
list.remove(component);
}
public List<Component> getAll(){
return this.list;
}
@Override
public void doSomething() {
for(Component component : list){
component.doSomething();
}
}
}
package com.bob.pattern.composite;
public class Client {
public static void main(String[] args) {
Component leaf1 = new Leaf();
Component leaf2 = new Leaf();
Composite comp1 = new Composite();
comp1.add(leaf1);
comp1.add(leaf2);
Component leaf3 = new Leaf();
Component leaf4 = new Leaf();
Composite comp2 = new Composite();
comp2.add(comp1);
comp2.add(leaf3);
comp2.add(leaf4);
comp2.doSomething();
}
}
组合模式的第二种实现方式:
package com.bob.pattern.composite2;
import java.util.List;
public interface Component {
public void doSomething();
public void add(Component component);
public void remove(Component component);
public List<Component> getAll();
}
package com.bob.pattern.composite2;
import java.util.ArrayList;
import java.util.List;
public class Composite implements Component {
private List<Component> list = new ArrayList<Component>();
@Override
public void doSomething() {
for(Component component : list){
component.doSomething();
}
}
@Override
public void add(Component component) {
list.add(component);
}
@Override
public void remove(Component component) {
list.remove(component);
}
@Override
public List<Component> getAll() {
return this.list;
}
}
package com.bob.pattern.composite2;
import java.util.List;
public class Leaf implements Component {
@Override
public void doSomething() {
System.out.println("执行方法");
}
@Override
public void add(Component component) {
}
@Override
public void remove(Component component) {
}
@Override
public List<Component> getAll() {
return null;
}
}
package com.bob.pattern.composite2;
public class Client {
public static void main(String[] args) {
Component leaf1 = new Leaf();
Component leaf2 = new Leaf();
Component comp1 = new Composite();
comp1.add(leaf1);
comp1.add(leaf2);
Component leaf3 = new Leaf();
Component leaf4 = new Leaf();
Component comp2 = new Composite();
comp2.add(comp1);
comp2.add(leaf3);
comp2.add(leaf4);
comp2.doSomething();
}
}
组合模式有两种实现方式:
1)将管理子元素的方法定义在 Composite 类中
2)将管理子元素的方法定义在 Component 接口中,这样Leaf 类就需要对这些方法空实现。