天天看點

《設計模式之禅》讀書筆記(四)

一.原型模式

原型模式(Prototype Pattern):用原型執行個體指定建立對象的種類,并且通過拷貝這個原型建立新的對象。

其核心是一個 clone方法,通過該方法進行對象拷貝,java提供一個Cloneable接口來辨別這個對象可拷貝。

優點:

1.性能優良,原型模式是在記憶體二進制流中拷貝,要比直接new一個對象性能好很多;

2.逃避構造函數的限制,直接在記憶體中拷貝,構造函數是不回執行的

注意:使用原型模式時,引用的成員變量必須滿足兩個條件才不會拷貝:

1.類的成員變量,而不是方法内的變量;

2.必須是一個可變的引用對象,而不是一個原始類型或不可變對象。

要使用clone方法,類的成員變量上不要增加final關鍵字

上代碼:

public class PrototypePattern {
    /**
     * 基本用法
     */
    public class PrototypeClass implements Cloneable{
        @Override
        public PrototypeClass clone() throws CloneNotSupportedException {
            PrototypeClass prototypeClass =null;
            try{
                prototypeClass =(PrototypeClass)  super.clone();
            }catch (Exception e){
                e.printStackTrace();
            }
            return prototypeClass;
        }
    }
/****************淺拷貝**********************/
    /**
     * 淺拷貝
     */
    public class PrototypeDemo implements Cloneable {
        private ArrayList<String> mArrayList = new ArrayList<>();
        @Override
        public com.sh.lynn.hz.deginpattern.prototype.PrototypeDemo clone() throws CloneNotSupportedException {
            com.sh.lynn.hz.deginpattern.prototype.PrototypeDemo paper =null;
            try{
                paper =(com.sh.lynn.hz.deginpattern.prototype.PrototypeDemo)  super.clone();
            }catch (Exception e){
                e.printStackTrace();
            }
            return paper;
        }
        public void setValue(String text){
            mArrayList.add(text);
        }
        public ArrayList<String> getValue(){
            return   mArrayList;
        }
    }
    /**
     *
     * @return
     */
    public String getCloneText (){
        PrototypeDemo prototypeDemo = new PrototypeDemo();
        prototypeDemo.setValue("Hello!");
        try {
            PrototypeDemo prototypeDemoClone = prototypeDemo.clone();
            prototypeDemoClone.setValue("World!");
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        StringBuffer stringBuffer = new StringBuffer();

        ArrayList<String>  list= prototypeDemo.getValue();
        for (String text:list){
            stringBuffer.append(text+"  ");
        }
        return stringBuffer.toString();
    }
/****************深拷貝**********************/
public class PrototypeDemoDeep implements Cloneable {

    private ArrayList<String> mArrayList = new ArrayList<>();
    @Override
    public com.sh.lynn.hz.deginpattern.prototype.PrototypeDemoDeep clone() throws CloneNotSupportedException {
        com.sh.lynn.hz.deginpattern.prototype.PrototypeDemoDeep paper =null;
        try{
            paper =(com.sh.lynn.hz.deginpattern.prototype.PrototypeDemoDeep)  super.clone();
            paper.mArrayList =(ArrayList<String>)this.mArrayList.clone();
        }catch (Exception e){
            e.printStackTrace();
        }
        return paper;
    }
    public void setValue(String text){
        mArrayList.add(text);
    }
    public ArrayList<String> getValue(){
        return   mArrayList;
    }
}
    /**
     * 深拷貝
     * @return
     */
    public String getCloneTextDeep (){
        PrototypeDemoDeep prototypeDemo = new PrototypeDemoDeep();
        prototypeDemo.setValue("Hello!");
        try {
            PrototypeDemoDeep prototypeDemoClone = prototypeDemo.clone();
            prototypeDemoClone.setValue("World!");
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        StringBuffer stringBuffer = new StringBuffer();

        ArrayList<String>  list= prototypeDemo.getValue();
        for (String text:list){
            stringBuffer.append(text+"  ");
        }
        return stringBuffer.toString();
    }
}
           

二.中介者模式

定義:用一個中介對象封裝一系列的對象互動,中介者使各對象不需要顯示互相作用,

進而使其耦合松散,而且可以獨立地改變它們之間的互動。

中介者模式的組成部分:

1.Mediator 抽象中介者角色 定義統一的接口,用于各同僚角色之間的通信。

2.Concrete Mediator 具體中介者角色 通過協調各同僚角色實作協作行為

3.Colleague 同僚角色

每一個同僚角色都知道中介者角色,而且與其它的同僚角色通信時候,一定通過中介者角色協作。

同僚類行為:

(1).同僚類本身行為,比如改變對象本身的狀态,處理自己的行為等,自有方法

(2).必須依賴中介者才能完成的行為 ,依賴方法

上代碼:

//抽象中介者
public abstract class Mediator {
    //定義同僚類
    protected ConcreteColleague1 mColleague1;
    protected ConcreteColleague2 mColleague2;

    public ConcreteColleague1 getColleague1() {
        return mColleague1;
    }

    public void setColleague1(ConcreteColleague1 colleague1) {
        mColleague1 = colleague1;
    }

    public ConcreteColleague2 getColleague2() {
        return mColleague2;
    }

    public void setColleague2(ConcreteColleague2 colleague2) {
        mColleague2 = colleague2;
    }
    //中介者模式的業務邏輯
    public abstract void doSomething1();
    public abstract void doSomething2();
}
//具體中介者
public class ConcreteMediator extends Mediator {
    @Override
    public void doSomething1() {
        super.mColleague1.selfMethod1();
        super.mColleague2.selfMethod2();
    }

    @Override
    public void doSomething2() {
        super.mColleague1.selfMethod1();
        super.mColleague2.selfMethod2();
    }
}
//抽象同僚類
public abstract class Colleague {
    protected Mediator mMediator;
    public Colleague(Mediator _mediator){
        this.mMediator=_mediator;
    }
}
//同僚類
public class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator _mediator) {
        super(_mediator);
    }
    //自有方法
    public void selfMethod1(){
        //處理自身業務邏輯
    }
    //依賴方法 dep-method
    public void depMethod1(){
        //處理自己的業務邏輯
        //自己不能處理的業務邏輯,委托中介者處理
        super.mMediator.doSomething1();
    }
}
//同僚類
public class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator _mediator) {
        super(_mediator);
    }
    //自有方法
    public void selfMethod2(){
        //處理自身業務邏輯
    }
    //依賴方法 dep-method
    public void depMethod2(){
        //處理自己的業務邏輯
        //自己不能處理的業務邏輯,委托中介者處理
        super.mMediator.doSomething2();
    }
}
           

三.指令模式

指令模式:将一個請求封裝成一個對象,進而讓你使用不同的請求把用戶端參數化,

對請求排隊或者記錄請求日志,可以提供指令的撤銷和恢複功能。

指令模式三個角色:

Receive 接收者角色

Command 指令角色

Invoker 調用者角色

上代碼:

public class CommandPattern {


    public String doSomething(){
        //聲明調用者Invoker
        Invoker invoker  = new Invoker();
        //定義接收者
        Receiver receiver1 = new ConcreteReceiver1();
        //定義一個發送給接收者的指令
        Command command1 = new ConcreteCommand1(receiver1);
        invoker.setCommand(command1);
        String result1 = invoker.action();
        //定義接收者
        Receiver receiver2 = new ConcreteReceiver2();
        //定義一個發送給接收者的指令
        Command command2 = new ConcreteCommand2(receiver2);
        invoker.setCommand(command2);
        String result2 =  invoker.action();
        return result1+"\n"+result2;
    }
}

public abstract class Receiver {
    //抽象接收者,定義每個接收者都必須完成的業務
    public abstract String doSomething();
}
public class ConcreteReceiver1 extends Receiver {
    @Override
    public String doSomething() {
        return "ConcreteReceiver1 doSomething ";
    }
}
public class ConcreteReceiver2 extends Receiver {
    @Override
    public String doSomething() {
        return "ConcreteReceiver2 doSomething ";
    }
}
public abstract class Command {
    //每個指令類都必須有個執行指令的方法
    public abstract String execute();
}
public class ConcreteCommand1 extends Command {
    //對哪個Receiver類進行指令處理
    private Receiver receiver;

    public ConcreteCommand1(Receiver _receiver){
        receiver = _receiver;
    }

    @Override
    public String execute() {
        return this.receiver.doSomething();
    }
}
public class ConcreteCommand2 extends com.sh.lynn.hz.deginpattern.commandpattern.Command {
    //對哪個Receiver類進行指令處理
    private com.sh.lynn.hz.deginpattern.commandpattern.Receiver receiver;

    public ConcreteCommand2(com.sh.lynn.hz.deginpattern.commandpattern.Receiver _receiver){
        receiver = _receiver;
    }

    @Override
    public String execute() {
        return  this.receiver.doSomething();
    }
}

public class Invoker {
    private Command mCommand;
    //接收指令
    public void setCommand(Command _command){
        this.mCommand=_command;
    }

    public String action(){
        return this.mCommand.execute();
    }
}
           

四.責任鍊模式

責任鍊模式:使多個對象都有機會處理請求,進而避免了請求的發送者和接收者之間的耦合關系。

将這些對象連成一條鍊,并沿着這條鍊傳遞該請求,直到有對象處理它為止。

public class ChainPattern {

    public String doSomething(){
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        Handler handler3 = new ConcreteHandler3();
        handler1.setNextHandler(handler2);
        handler2.setNextHandler(handler3);
//注意這裡的調用 都是handle1
        Response response1 = handler1.handleMessage(new Request(Level.HIGHT,"hight request"));
        Response response2 = handler1.handleMessage(new Request(Level.LOW,"low request"));
        Response response3 = handler1.handleMessage(new Request(Level.MID,"mid request"));
        return response1.getResult()+"\n"+response2.getResult()+"\n"+response3.getResult();
    }
}

public class Request {
    private Level mLevel;
    private String msg ;
    public Request(Level _level,String _msg){
        mLevel=_level;
        msg=_msg;
    }
    public Level getRequestLevel(){
        return mLevel;
    }

    public String getMsg(){
        return  msg;
    }
}

public enum  Level {
    LOW ,MID,HIGHT
}
public class Response {
    private String result;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}

public abstract class Handler {
    private Handler nextHandler;
    //每個處理者都必須對請求做出處理
    public final Response handleMessage(Request request) {
        Response response = null;
        //判斷是否是自己的處理級别
        if (getHandlerLevel().equals(request.getRequestLevel())) {
            response = echo(request);
        } else {
            //下一個處理者
            if (this.nextHandler != null) {
                response = this.nextHandler.handleMessage(request);
            } else {

            }
        }
        return response;
    }
    //設定下一個處理者是誰
    public void setNextHandler(Handler _handler) {
        this.nextHandler = _handler;
    }
    //每個處理者都有一個處理級别
    protected abstract Level getHandlerLevel();
    //每個處理者都必須實作處理任務
    protected abstract Response echo(Request request);
}

public class ConcreteHandler1 extends Handler {
    @Override
    protected Level getHandlerLevel() {
        return Level.LOW;
    }

    @Override
    protected Response echo(Request request) {
        Response response = new Response();
        response.setResult(request.getMsg());
        return response;
    }
}

public class ConcreteHandler2 extends Handler {
    @Override
    protected Level getHandlerLevel() {
        return Level.MID;
    }

    @Override
    protected Response echo(Request request) {
        Response response = new Response();
        response.setResult(request.getMsg());
        return response;
    }
}

public class ConcreteHandler3 extends Handler {
    @Override
    protected Level getHandlerLevel() {
        return Level.HIGH;
    }

    @Override
    protected Response echo(Request request) {
        Response response = new Response();
        response.setResult(request.getMsg());
        return response;
    }
}
           

繼續閱讀