20、狀態模式(State)java
核心思想就是:當對象的狀態改變時,同時改變其行爲,很好理解!就拿QQ來講,有幾種狀態,在線、隱身、忙碌等,每一個狀態對應不一樣的操做,並且你的好友也能看到你的狀態,因此,狀態模式就兩點:一、能夠經過改變狀態來得到不一樣的行爲。二、你的好友能同時看到你的變化。看圖:正則表達式
State類是個狀態類,Context類能夠實現切換,咱們來看看代碼:算法
[java] view plaincopy spring
package com.xtfggef.dp.state; 設計模式
/** 數據結構
* 狀態類的核心類 數據結構和算法
* 2012-12-1 ide
* @author erqing 學習
* 測試
*/
public class State {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void method1(){
System.out.println("execute the first opt!");
}
public void method2(){
System.out.println("execute the second opt!");
}
}
[java] view plaincopy
package com.xtfggef.dp.state;
/**
* 狀態模式的切換類 2012-12-1
* @author erqing
*
*/
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void method() {
if (state.getValue().equals("state1")) {
state.method1();
} else if (state.getValue().equals("state2")) {
state.method2();
}
}
}
測試類:
[java] view plaincopy
public class Test {
public static void main(String[] args) {
State state = new State();
Context context = new Context(state);
//設置第一種狀態
state.setValue("state1");
context.method();
//設置第二種狀態
state.setValue("state2");
context.method();
}
}
輸出:
execute the first opt!
execute the second opt!
根據這個特性,狀態模式在平常開發中用的挺多的,尤爲是作網站的時候,咱們有時但願根據對象的某一屬性,區別開他們的一些功能,好比說簡單的權限控制等。
2一、訪問者模式(Visitor)
訪問者模式把數據結構和做用於結構上的操做解耦合,使得操做集合可相對自由地演化。訪問者模式適用於數據結構相對穩定算法又易變化的系統。由於訪問者模式使得算法操做增長變得容易。若系統數據結構對象易於變化,常常有新的數據對象增長進來,則不適合使用訪問者模式。訪問者模式的優勢是增長操做很容易,由於增長操做意味着增長新的訪問者。訪問者模式將有關行爲集中到一個訪問者對象中,其改變不影響系統數據結構。其缺點就是增長新的數據結構很困難。—— From 百科
簡單來講,訪問者模式就是一種分離對象數據結構與行爲的方法,經過這種分離,可達到爲一個被訪問者動態添加新的操做而無需作其它的修改的效果。簡單關係圖:
來看看原碼:一個Visitor類,存放要訪問的對象,
[java] view plaincopy
public interface Visitor {
public void visit(Subject sub);
}
[java] view plaincopy
public class MyVisitor implements Visitor {
@Override
public void visit(Subject sub) {
System.out.println("visit the subject:"+sub.getSubject());
}
}
Subject類,accept方法,接受將要訪問它的對象,getSubject()獲取將要被訪問的屬性,
[java] view plaincopy
public interface Subject {
public void accept(Visitor visitor);
public String getSubject();
}
[java] view plaincopy
public class MySubject implements Subject {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String getSubject() {
return "love";
}
}
測試:
[java] view plaincopy
public class Test {
public static void main(String[] args) {
Visitor visitor = new MyVisitor();
Subject sub = new MySubject();
sub.accept(visitor);
}
}
輸出:visit the subject:love
該模式適用場景:若是咱們想爲一個現有的類增長新功能,不得不考慮幾個事情:一、新功能會不會與現有功能出現兼容性問題?二、之後會不會再須要添加?三、若是類不容許修改代碼怎麼辦?面對這些問題,最好的解決方法就是使用訪問者模式,訪問者模式適用於數據結構相對穩定的系統,把數據結構和算法解耦,
2二、中介者模式(Mediator)
中介者模式也是用來下降類類之間的耦合的,由於若是類類之間有依賴關係的話,不利於功能的拓展和維護,由於只要修改一個對象,其它關聯的對象都得進行修改。若是使用中介者模式,只需關心和Mediator類的關係,具體類類之間的關係及調度交給Mediator就行,這有點像spring容器的做用。先看看圖:
User類統一接口,User1和User2分別是不一樣的對象,兩者之間有關聯,若是不採用中介者模式,則須要兩者相互持有引用,這樣兩者的耦合度很高,爲了解耦,引入了Mediator類,提供統一接口,MyMediator爲其實現類,裏面持有User1和User2的實例,用來實現對User1和User2的控制。這樣User1和User2兩個對象相互獨立,他們只須要保持好和Mediator之間的關係就行,剩下的全由MyMediator類來維護!基本實現:
[java] view plaincopy
public interface Mediator {
public void createMediator();
public void workAll();
}
[java] view plaincopy
public class MyMediator implements Mediator {
private User user1;
private User user2;
public User getUser1() {
return user1;
}
public User getUser2() {
return user2;
}
@Override
public void createMediator() {
user1 = new User1(this);
user2 = new User2(this);
}
@Override
public void workAll() {
user1.work();
user2.work();
}
}
[java] view plaincopy
public abstract class User {
private Mediator mediator;
public Mediator getMediator(){
return mediator;
}
public User(Mediator mediator) {
this.mediator = mediator;
}
public abstract void work();
}
[java] view plaincopy
public class User1 extends User {
public User1(Mediator mediator){
super(mediator);
}
@Override
public void work() {
System.out.println("user1 exe!");
}
}
[java] view plaincopy
public class User2 extends User {
public User2(Mediator mediator){
super(mediator);
}
@Override
public void work() {
System.out.println("user2 exe!");
}
}
測試類:
[java] view plaincopy
public class Test {
public static void main(String[] args) {
Mediator mediator = new MyMediator();
mediator.createMediator();
mediator.workAll();
}
}
輸出:
user1 exe!
user2 exe!
2三、解釋器模式(Interpreter)
解釋器模式是咱們暫時的最後一講,通常主要應用在OOP開發中的編譯器的開發中,因此適用面比較窄。
Context類是一個上下文環境類,Plus和Minus分別是用來計算的實現,代碼以下:
[java] view plaincopy
public interface Expression {
public int interpret(Context context);
}
[java] view plaincopy
public class Plus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1()+context.getNum2();
}
}
[java] view plaincopy
public class Minus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1()-context.getNum2();
}
}
[java] view plaincopy
public class Context {
private int num1;
private int num2;
public Context(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
}
[java] view plaincopy
public class Test {
public static void main(String[] args) {
// 計算9+2-8的值
int result = new Minus().interpret((new Context(new Plus()
.interpret(new Context(9, 2)), 8)));
System.out.println(result);
}
}
最後輸出正確的結果:3。
基本就這樣,解釋器模式用來作各類各樣的解釋器,如正則表達式等的解釋器等等!
設計模式基本就這麼大概講完了,整體感受有點簡略,的確,這麼點兒篇幅,不足以對整個23種設計模式作全面的闡述,此處讀者可將它做爲一個理論基礎去學習,經過這四篇博文,先基本有個概念,雖然我講的有些簡單,但基本都能說明問題及他們的特色,若是對哪個感興趣,能夠繼續深刻研究!同時我也會不斷更新,儘可能補全遺漏、修正不足,歡迎廣大讀者及時提出好的建議,咱們一塊兒學習!項目中涉及到的代碼,已經放到了個人資源裏:http://download.csdn.net/detail/zhangerqing/4835830(由於我不喜歡坐享其成,因此沒有免積分,只設置了5個,若是有人實在沒積分又急要,那麼聯繫我吧,我給你發過去)。