模板方法模式(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 類就需要對這些方法空實現。