天天看點

java設計模式(一)——擴充卡、橋接、建造者、職責鍊、指令

一、Adapter擴充卡設計模式

當我們要組合兩個不相幹的類時,第一種解決方案是修改各自類的接口。但是如果沒有源碼,或者不願意為了一個應用而修改各自的接口,則需要使用Adapter擴充卡,在兩種接口之間建立一個混合接口。

擴充卡設計模式中有3個重要角色:被适配者Adaptee,擴充卡Adapter和目标對象Target。

其中兩個現存的想要組合到一起的類分别是被适配者Adaptee和目标對象Target角色,我們需要建立一個擴充卡Adapter将其組合在一起。

常用有兩種方法:組合擴充卡模式,繼承擴充卡模式

1、組合擴充卡模式:假設要畫圖形,有圓形和方形兩個類,現在需要一個既可以畫圓形又可以畫方形的類。

//擴充卡
class Adapter extends Circle{
    private Square square;  
    public Adapter(Square square){  
    	this.square = square;  
    }  
    public void drawSquare(){  
    	square.drawSquare();  
    }  
}

// 圓形,目标對象
class Circle {
	public void drawCircle() {
		System.out.println("Draw circle");
	}
}

// 方形,被适配對象
class Square {
	public void drawSquare() {
		System.out.println("Draw square");
	}
}

//既可以畫圓形,又可以畫方形,擴充卡  
public class AdapterCombination{
    public static void main(String[] args) {
        Adapter adapter = new Adapter(new Square());
        adapter.drawCircle();
        adapter.drawSquare();
    }
}
           

輸出結果:

Draw circle

Draw square

2、繼承擴充卡模式

class Adapter2 implements ICircle, ISquare {
	private ISquare square;
	private ICircle circle;

	public Adapter2(Square2 square) {
		this.square = square;
	}

	public Adapter2(Circle2 circle) {
		this.circle = circle;
	}
	
	public Adapter2(Square2 square,Circle2 circle){
		this.square = square;
		this.circle = circle;
	}

	public void drawSquare() {
		square.drawSquare();
	}

	public void drawCircle() {
		circle.drawCircle();
	}
}

interface ICircle {
	public void drawCircle();
}

interface ISquare {
	public void drawSquare();
}

// 圓形
class Circle2 implements ICircle {
	public void drawCircle() {
		System.out.println("Draw circle");
	}
}

// 方形
class Square2 implements ISquare {
	public void drawSquare() {
		System.out.println("Draw square");
	}
}

public class AdapterExtend {
    public static void main(String[] args) {
        Adapter2 adapter2 = new Adapter2(new Square2(),new Circle2());
        adapter2.drawCircle();
        adapter2.drawSquare();
    }
}
           

輸出結果:

Draw circle

Draw square

二、Bridge橋接設計模式

橋接設計模式是将一組功能(實作)與另一組使用該功能的其他對象(行為)分離開來,以便達到單一因素變化,然後使用對象調用的方式将這兩組關聯系起來,将問題的行為和實作分離開來實作,通過用聚合代替繼承來解決子類爆炸性增長的問題。假設我們現在有兩個圖形,有兩種畫法,實作如下:

public class BridgePattern {
    public static void main(String[] args) {
        //畫一個實線的圓
        Drawing draw1 = new SolidDrawing();
        Shape shape1 = new Circle(draw1);
        shape1.doDraw();
        //畫一個虛線的圓
        Drawing draw2 = new DashDrawing();
        Shape shape2 = new Circle(draw2);
        shape2.doDraw();
        //畫一個實線的矩形
        Drawing draw3 = new SolidDrawing();
        Shape shape3 = new Rectangle(draw3);
        shape3.doDraw();
        //畫一個虛線的矩形
        Drawing draw4 = new DashDrawing();
        Shape shape4 = new Rectangle(draw4);
        shape4.doDraw();    
    }
}

// 行為,使用功能的類
interface Shape {
    public void doDraw();
}

class Circle implements Shape {
    private Drawing draw;

    public Circle(Drawing draw) {
        this.draw = draw;
    }

    public void doDraw() {
        System.out.println("I am Circle.");
        draw.draw();
    }
}

class Rectangle implements Shape {
    private Drawing draw;

    public Rectangle(Drawing draw) {
        this.draw = draw;
    }

    public void doDraw() {
        System.out.println("I am Rectangle.");
        draw.draw();
    }
}

// 實作,提供功能的類
interface Drawing {
    public void draw();
}

class SolidDrawing implements Drawing {
    public void draw() {
        System.out.println("Drawing solide line…");
    }
}

class DashDrawing implements Drawing {
    public void draw() {
        System.out.println("Drawing dash line…");
    }
}
           

輸出結果:

I am Circle.

Drawing solide line…

I am Circle.

Drawing dash line…

I am Rectangle.

Drawing solide line…

I am Rectangle.

Drawing dash line…

假設我們需要增加一個三角形,則我們主要多增加一個實作了Shape的接口就好了,如下

class Triangle implements Shape{
	private Drawing draw;
	
	public Triangle(Drawing draw){
		this.draw = draw;
	}
	public void doDraw() {
		System.out.println("I am Triangle.");
		draw.draw();
	}
}
           

然後我們要畫一個是虛線的三角形,則這樣調用

Drawing draw5 = new DashDrawing();
        Shape shape5 = new Triangle(draw5);
        shape5.doDraw();
           

輸出結果:

I am Triangle.

Drawing dash line…

三、Builder建造者模式

Builder建造者模式将一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以建立不同的表示。Builder模式是一步一步建立一個複雜的對象,它允許使用者可以隻通過指定複雜對象的類型和内容就可以建構它們,使用者不需要了解所建構對象的内部具體建構細節,Builder建造設計模式的目的是為了将構造複雜對象的過程和它的部件解耦。

Builder建造者設計模式中有兩個重要角色:Director指導者和Builder建造者。Director指導者相當于設計師或架構師,擁有整個産品各個部件之間關系的建構藍圖。Builder建造者是部件的具體建立者,Builder建造者根據Director指導者的訓示建立産品的各個部件,最終由Director建構出完整産品。要向builder要Product而不是向知道建造過程的Director要。

舉例說明,就好象我要一座房子住,可是我不知道怎麼蓋(簡單的砌牆,層次較低),也不知道怎麼樣設計(建幾個房間,幾個門好看,層次較高),于是我需要找一幫民工,他們會砌牆,還得找個設計師,他知道怎麼設計,我還要確定民工聽設計師的上司,而設計師本身也不幹活,光是下指令,這裡砌一堵牆,這裡砌一扇門,這樣民工開始建設,最後,我可以向民工要房子了。在這個過程中,設計師是什麼也沒有,除了他在腦子裡的設計和指令,是以要房子也是跟民工要!

//建造者:
interface Builder {  
	  public void makeWindow();  
	  
	  public void makeFloor();  
	  
	  public String submitRoom();  
}  
class Mingong implements Builder {  
	  private String window="";  
	  private String floor="";  
	    
	  public void makeWindow() {  
		  window=new String("window");  
	  }  
	  public void makeFloor(){  
		  floor=new String("floor");  
	  }  
	  // 交房子給房主  
	  public String submitRoom() {  
		    if((!window.equals(""))&&(!floor.equals(""))) {  
		    	return "房子已經建好了";  
		    } else{
		    	return null;  
		    }
	  }  
} 
//指揮者:
class Designer{  
	  // 指揮民工進行工作  
	  public void order(Builder builder) {  
		    builder.makeWindow();  
		    builder.makeFloor();  
	  }  
}

public class BuilderPattern {
    public static void main(String[] args) {
        Builder mingong = new Mingong();    
        Designer designer = new Designer();
        designer.order(mingong);
        System.out.println(mingong.submitRoom());
    }
}
           

輸出結果:

房子已經建好了

四、ChainOfResponsibility責任鍊設計模式

責任鍊設計模式是用一系列請求處理器試圖處理一個請求,這些請求處理器之間是一個松散耦合,唯一的共同點是在他們之間傳遞請求。例如用戶端發送一個請求,請求處理器A先處理,如果A沒有處理或者無法處理,就将請求傳遞給請求處理器B,如果B沒有處理或者無法處理,就将請求傳遞到請求處理器C去處理,所有這些請求處理器構成一條請求處理責任鍊。一個處理數字,字母和特殊符号的例子:

// 抽象請求處理器
abstract class Handler {
	private Handler successor;

	public Handler() {
	}

	public Handler(Handler successor) {
		this.successor = successor;
	}

	public Handler getSuccessor() {
		return successor;
	}

	public void setSuccessor(Handler successor) {
		this.successor = successor;
	}

	public abstract void handRequest(Request request);
}

// Request請求類
class Request {
	private String type;

	public Request(String type) {
		this.type = type;
	}

	public String getType() {
		return type;
	}
}

// 數字請求處理器
class NumberHandler extends Handler {
	public NumberHandler() {
	}

	public NumberHandler(Handler successor) {
		super(successor);
	}

	public void handRequest(Request request) {
		if (request.getType().equals("Number")) {
			System.out.println("Number has been handled");
		}
		// 傳遞到下一個請求處理器處理
		else {
			getSuccessor().handRequest(request);
		}
	}
}

// 字母請求處理器
class CharacterHandler extends Handler {
	public CharacterHandler() {
	}

	public CharacterHandler(Handler successor) {
		super(successor);
	}

	public void handRequest(Request request) {
		if (request.getType().equals("Character")) {
			System.out.println("Character has been handled");
		}
		// 傳遞到下一個請求處理器處理
		else {
			getSuccessor().handRequest(request);
		}
	}
}

// 特殊符号請求處理器
class SymbolHandler extends Handler {
	public SymbolHandler() {
	}

	public SymbolHandler(Handler successor) {
		super(successor);
	}

	public void handRequest(Request request) {
		if (request.getType().equals("Symbol")) {
			System.out.println("Symbol has been handled");
		}
		// 傳遞到下一個請求處理器處理
		else {
			getSuccessor().handRequest(request);
		}
	}
}

public class ChainOfResponsibilityPattern {
    public static void main(String[] args) {
        Handler numberHandler = new NumberHandler();
        Handler characterHandler = new CharacterHandler();
        Handler symbolHandler = new SymbolHandler();

        numberHandler.setSuccessor(characterHandler);
        characterHandler.setSuccessor(symbolHandler);
        Request request1 = new Request("Number");
        Request request2 = new Request("Character");
        Request request3 = new Request("Symbol");

        numberHandler.handRequest(request1);
        numberHandler.handRequest(request2);
        numberHandler.handRequest(request3);
    }
}
           

輸出結果:

Number has been handled

Character has been handled

Symbol has been handled

五、Command指令設計模式

Command指令設計模式将一個請求封裝成一個對象,進而使你可用不同的請求對客戶進行操作。Command指令設計模式是對指令的封裝。指令模式把發出指令的責任和執行指令的責任分割開,委派給不同的對象。每一個指令都是一個操作,指令請求送出請求要求執行一個操作;指令接受方收到請求,并執行操作。指令模式允許指令請求方和指令接收方獨立開來,使得指令請求方不必 知道指令接收方的接口,更不必知道請求是怎麼被接收,以及操作是否被執行,何時被執行,以及是怎麼被執行的。

Command指令設計模式中5個角色:

(1).抽象指令角色:聲明了一個給所有具體指令類的抽象接口。這是一個抽象角色,通常由一個java接口或java抽象類實作。

(2).請求者(Invoke)角色:負責調用指令對象執行請求,相關的方法叫做行動方法。

(3).接收者(Receiver)角色:負責具體實施和執行一個請求。任何一個類都可以成為接收者,實施和執行請求的方法叫做行動方法。

(4).具體指令角色:定義一個接受者和行為之間的弱耦合;實作execute方法,負責調用接收者的相應操作。execute方法通常叫做 執行方法。

(5).客戶角色:建立了一個具體指令對象并确定其接收者。

模拟對電視機的操作開機、關機指令

//抽象指令角色
interface Command {
	public void execute();
}

//請求者角色,遙控器
class InvokerControl {
	private Command command;
	public InvokerControl(Command command) {
		this.command = command;
	}
	public void action() {
		command.execute();
	}
}

//接收者角色,TV
class ReceiverTv{
	public void turnOn() {
		System.out.println("The televisino is on.");
	}
	public void turnOff() {
		System.out.println("The television is off.");
	}
}

//具體指令類,開電視
class TurnOnCommand implements Command {
	private ReceiverTv receiver;
	public TurnOnCommand(ReceiverTv receiver) {
		this.receiver = receiver;
	}
	public void execute() {
		receiver.turnOn();
	}
}

//具體指令類,關電視
class TurnOffCommand implements Command {
	private ReceiverTv receiver;
	public TurnOffCommand(ReceiverTv receiver) {
		this.receiver = receiver;
	}
	public void execute() {
		receiver.turnOff();
	}
}

public class CommandPattern {
    public static void main(String[] args) {
        // 用戶端建立指令接受者
        ReceiverTv tv = new ReceiverTv();
        // 用戶端建立具體指令,并指定指令接受者
        Command command = new TurnOnCommand(tv);
        // 用戶端建立請求者,并給請求者指定具體指令
        InvokerControl invoker = new InvokerControl(command);
        // 指令請求者發出指令請求
        invoker.action();
        
        Command command2 = new TurnOffCommand(tv);
        InvokerControl invoker2 = new InvokerControl(command2);
        invoker2.action();
        
    }
}
           

輸出結果:

The televisino is on.

The television is off.

備注:java設計模式的學習主要是參考一位牛人http://blog.csdn.net/chjttony和從網上查找到的學習資料,裝載請注明出處。

繼續閱讀