行为型设计模式(职责链模式,命令模式,中介者模式,观察者模式,访问者模式)

职责链模式

主要用于使多个对象都有机会处理请求,避免请求的的发送者和接受者之间的耦合关系。在现实生活中我们多数遇到的是不纯的责任链模式即每个对象都处理请求的一部分后再交给下家。而纯的职责链模式则要求对于一个请求,要不处理要不就交给下家。具体理解呢。我们可以想一下“击鼓传花”的游戏。或则是你帮你的同学传一个纸条。如果传给你你就看,否则就传给下一个同学(嘻嘻)。比较容易理解,主要看一下类图:


和相关代码实现:

public abstract class Handler {
    
    /**
     * 持有后继的责任对象
     */
    protected Handler successor;
    /**
     * 示意处理请求的方法,虽然这个示意方法是没有传入参数的
     * 但实际是可以传入参数的,根据具体需要来选择是否传递参数
     */
    public abstract void handleRequest();
    /**
     * 取值方法
     */
    public Handler getSuccessor() {
        return successor;
    }
    /**
     * 赋值方法,设置后继的责任对象
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    
}
复制代码

  具体处理者角色

复制代码
public class ConcreteHandler extends Handler {
    /**
     * 处理方法,调用此方法处理请求
     */
    @Override
    public void handleRequest() {
        /**
         * 判断是否有后继的责任对象
         * 如果有,就转发请求给后继的责任对象
         * 如果没有,则处理请求
         */
        if(getSuccessor() != null)
        {            
            System.out.println("放过请求");
            getSuccessor().handleRequest();            
        }else
        {            
            System.out.println("处理请求");
        }
    }

}
复制代码

  客户端类

复制代码
public class Client {

    public static void main(String[] args) {
        //组装责任链
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();
        handler1.setSuccessor(handler2);
        //提交请求
        handler1.handleRequest();
    }

}

命令模式。

主要用于把发出命令和执行命令的责任分开,委派给不同对象。怎么理解呢?命令模式中请求的实现在接受者中实现但在最后客户请求服务时。具体的实现是通过请求者调用具体命令角色来实现。举个例子。录音机(播放,倒带,停止)三个功能

接收者角色,由录音机类扮演

复制代码
public class AudioPlayer {
    
    public void play(){
        System.out.println("播放...");
    }
    
    public void rewind(){
        System.out.println("倒带...");
    }
    
    public void stop(){
        System.out.println("停止...");
    }
}
复制代码

  抽象命令角色类

复制代码
public interface Command {
    /**
     * 执行方法
     */
    public void execute();
}
复制代码

  具体命令角色类

复制代码
public class PlayCommand implements Command {

    private AudioPlayer myAudio;
    
    public PlayCommand(AudioPlayer audioPlayer){
        myAudio = audioPlayer;
    }
    /**
     * 执行方法
     */
    @Override
    public void execute() {
        myAudio.play();
    }

}
复制代码
复制代码
public class RewindCommand implements Command {

    private AudioPlayer myAudio;
    
    public RewindCommand(AudioPlayer audioPlayer){
        myAudio = audioPlayer;
    }
    @Override
    public void execute() {
        myAudio.rewind();
    }

}
复制代码
复制代码
public class StopCommand implements Command {
    private AudioPlayer myAudio;
    
    public StopCommand(AudioPlayer audioPlayer){
        myAudio = audioPlayer;
    }
    @Override
    public void execute() {
        myAudio.stop();
    }

}
复制代码

  请求者角色,由键盘类扮演

复制代码
public class Keypad {
    private Command playCommand;
    private Command rewindCommand;
    private Command stopCommand;
    
    public void setPlayCommand(Command playCommand) {
        this.playCommand = playCommand;
    }
    public void setRewindCommand(Command rewindCommand) {
        this.rewindCommand = rewindCommand;
    }
    public void setStopCommand(Command stopCommand) {
        this.stopCommand = stopCommand;
    }
    /**
     * 执行播放方法
     */
    public void play(){
        playCommand.execute();
    }
    /**
     * 执行倒带方法
     */
    public void rewind(){
        rewindCommand.execute();
    }
    /**
     * 执行播放方法
     */
    public void stop(){
        stopCommand.execute();
    }
}
复制代码

  客户端角色,由茱丽小女孩扮演

复制代码
public class Julia {
    public static void main(String[]args){
        //创建接收者对象
        AudioPlayer audioPlayer = new AudioPlayer();
        //创建命令对象
        Command playCommand = new PlayCommand(audioPlayer);
        Command rewindCommand = new RewindCommand(audioPlayer);
        Command stopCommand = new StopCommand(audioPlayer);
        //创建请求者对象
        Keypad keypad = new Keypad();
        keypad.setPlayCommand(playCommand);
        keypad.setRewindCommand(rewindCommand);
        keypad.setStopCommand(stopCommand);
        //测试
        keypad.play();
        keypad.rewind();
        keypad.stop();
        keypad.play();
        keypad.stop();
    }
}
在例子之后我们再看类图是不就感觉简单一些


中介者模式

 使用场景:集中负责维护对象模型的关系完整性 以及需要 封装对象间交互方式的时候.
   其实MVC中的controller就是一种Mediator,是UI层 和后端应用sevice层间的中介者。中介者将交互的复杂性变为中介者的复杂性

 

   在此写了7个java类来描述说明Mediator设计模式的实现方式;

  1、 Colleague.java   交互对象的抽象类
  2、 Colleague1.java  交互对象1
  3、 Colleague2.java  交互对象2
  4、 Colleague3.java  交互对象3
  5、 Mediator.java    中介者抽象类
  6、 ConcreteMediator.java 具体的中介者
  7、 MediatorTest.java     带有main方法的测试类

 

===============   1、 Colleague.java
交互对象的抽象类,定义了中介者的注入方法 、交互的行为方法
package mediator;

public abstract class Colleague {
  //中介者
  private Mediator mediator;
  public Mediator getMediator() {
    return mediator;
  }
  public Colleague(Mediator m) {
    mediator = m;
  }
 
  //消息
  private String message;
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }

  //发送消息
  public abstract void sendMsg();

  //收到消息
  public abstract void getMsg(String msg);

  //发送消息
  public void sendMsg(String msg) {
    this.message = msg;
    mediator.action(this);
  }
}
===============   1 end

 

===============   2、 Colleague1.java
package mediator;

public class Colleague1 extends Colleague {
  public Colleague1(Mediator m) {
    super(m);
  }

  public void getMsg(String msg) {
    System.out.println("Colleague1 has got  the message  -'" + msg + "'");
  }

  public void sendMsg() {
    System.out.println("Colleague1 has send the message '" + getMessage() + "'");
  }
}
===============   2 end

 

===============   3、 Colleague2.java
package mediator;

public class Colleague2 extends Colleague {
  public Colleague2(Mediator m) {
    super(m);
  }

  public void getMsg(String msg) {
    System.out.println("Colleague2 has got  the message  -'" + msg + "'");
  }

  public void sendMsg() {
    System.out.println("Colleague2 has send the message '" + getMessage() + "'");
  }
}
===============   3 end

 

===============   4、 Colleague3.java
package mediator;

public class Colleague3 extends Colleague {
  public Colleague3(Mediator m) {
    super(m);
  }

  public void getMsg(String msg) {
    System.out.println("Colleague3 has got  the message  -'" + msg + "'");
  }

  public void sendMsg() {
    System.out.println("Colleague3 has send the message '" + getMessage() + "'");
  }
}
===============   4 end

 

===============   5、 Mediator.java
package mediator;

abstract class Mediator {
  //Mediator针对Colleague的一个交互行为
  public abstract void action(Colleague sender);
  //加入Colleague对象
  public abstract void addCollegue(Colleague colleague);
}
===============   5 end

 

===============   6、 ConcreteMediator.java
  具体的中介者,负责管理Colleague对象间的关系、以及Colleague对象间的交互
package mediator;

import java.util.ArrayList;
import java.util.List;

public class ConcreteMediator extends Mediator {

  private List<Colleague> colleagues = new ArrayList<Colleague>(0);
 
  public void addCollegue(Colleague colleague) {
    colleagues.add(colleague);
  }

  public void action(Colleague actor) {
    String msg = actor.getMessage();
    //send msg
    for (Colleague colleague : colleagues) {
      if(colleague.equals(actor)){
        colleague.sendMsg();
        break;
      }
    }
   
    //get msg
    for (Colleague colleague : colleagues) {
      if(colleague.equals(actor))
        continue;
       
      colleague.getMsg(msg);
    }
  }
}
===============   6 end

 

===============   7、 MediatorTest.java
package mediator;

public class MediatorTest {

  public static void main(String[] args) {
   //生成中介者 并注入到各个Colleague对象中
    Mediator mediator = new ConcreteMediator();
    Colleague colleague1 = new Colleague1(mediator);
    Colleague colleague2 = new Colleague2(mediator);
    Colleague colleague3 = new Colleague3(mediator);
 
 //注册对象到中介
    mediator.addCollegue(colleague1);
    mediator.addCollegue(colleague2);
    mediator.addCollegue(colleague3);
   
 //Colleague1 触发行为
    colleague1.sendMsg("Hi,it's time to lunch. Let's go!");
    System.out.println();
    //Colleague2 触发行为
    colleague2.sendMsg("Is anybody here!");
    System.out.println();
    //Colleague3 触发行为
    colleague3.sendMsg("Wait!I will lunch off right away.");
    System.out.println();
   
  }
}

观察者模式

观察者模式又称为发布订阅模式,模型视图模式,源-监听器模式。它定义一种一对多的依赖关系,让多个观察者同时监听一个主题对象。这个主题对象发生改变时,所有观察者做出相应变化。例如我们买衣服。我们去买衣服结果没货。我们会把自己的联系方式留下来(注册),等有货时商家通知你。其实这就是一个观察者模式。我们以及其他买衣服者是观察者,商家是被观察者。商家状态改变(有衣服),通知观察者,观察者也做出相应变化(去买衣服)。一个简单的Java例子:

//抽象观察者角色
public interface Watcher
{
    public void update(String str);

}
复制代码

  然后定义抽象的主题角色,即抽象的被观察者,在其中声明方法(添加、移除观察者,通知观察者):

复制代码
//抽象主题角色,watched:被观察
public interface Watched
{
    public void addWatcher(Watcher watcher);

    public void removeWatcher(Watcher watcher);

    public void notifyWatchers(String str);

}
复制代码

  然后定义具体的观察者:

复制代码
public class ConcreteWatcher implements Watcher
{

    @Override
    public void update(String str)
    {
        System.out.println(str);
    }

}
复制代码

  之后是具体的主题角色: 

复制代码
import java.util.ArrayList;
import java.util.List;

public class ConcreteWatched implements Watched
{
    // 存放观察者
    private List<Watcher> list = new ArrayList<Watcher>();

    @Override
    public void addWatcher(Watcher watcher)
    {
        list.add(watcher);
    }

    @Override
    public void removeWatcher(Watcher watcher)
    {
        list.remove(watcher);
    }

    @Override
    public void notifyWatchers(String str)
    {
        // 自动调用实际上是主题进行调用的
        for (Watcher watcher : list)
        {
            watcher.update(str);
        }
    }

}
复制代码

  编写测试类:

复制代码
public class Test
{
    public static void main(String[] args)
    {
        Watched girl = new ConcreteWatched();
        
        Watcher watcher1 = new ConcreteWatcher();
        Watcher watcher2 = new ConcreteWatcher();
        Watcher watcher3 = new ConcreteWatcher();
        
        girl.addWatcher(watcher1);
        girl.addWatcher(watcher2);
        girl.addWatcher(watcher3);
        
        girl.notifyWatchers("开心");
    }

}
访问者模式

访问者模式适用于数据结构相对稳定的系统,它将算法与对象结构分离开,是操作能相对自由的演化。看一下类图

Java 设计模式 之 访问者模式(Visitor) - 低调的华丽 - 辉色空间

public abstract class Customer {

         private String customerId;
         private String name;
 
         public String getCustomerId() {
                   return customerId;
         }
         public void setCustomerId(String customerId) {
                  this.customerId = customerId;
         }
         public String getName() {
                  return name;
         }
         public void setName(String name) {
                 this.name = name;
         }
 
         /**
          * 接受访问者的访问
          * @param visitor
          */
         public abstract void accept(Visitor visitor);

/**
 * 企业客户
 */
public class EnterpriseCustomer extends Customer {

          private String linkman;
          private String linkTelephone;
          private String registerAddress;
 
          public String getLinkman() {
                    return linkman;
          }

          public void setLinkman(String linkman) {
                   this.linkman = linkman;
          }

          public String getLinkTelephone() {
                  return linkTelephone;
          }

          public void setLinkTelephone(String linkTelephone) {
                  this.linkTelephone = linkTelephone;
          }

          public String getRegisterAddress() {
                  return registerAddress;
          }

          public void setRegisterAddress(String registerAddress) {
                    this.registerAddress = registerAddress;
          }

          @Override
          public void accept(Visitor visitor) {
                   //回调访问者对象的方法
                   visitor.visitEnterpriseCustomer(this);
          }

}

/**
 * 个人客户
 */
public class PersonalCustomer extends Customer {

          private String telephone;
          private int age;
 
          public String getTelephone() {
                    return telephone;
          }

          public void setTelephone(String telephone) {
                   this.telephone = telephone;
          }

          public int getAge() {
                  return age;
          }

          public void setAge(int age) {
                  this.age = age;
          }

          @Override
          public void accept(Visitor visitor) {
                   //回调访问者对象的方法
                   visitor.visitPersonalCustomer(this);
          }

}

/**
 * 访问者接口
 */
public interface Visitor {

          /**
           * 访问企业客户,相当于给企业客户添加访问者功能
           * @param ec 企业客户对象
           */
          public void visitEnterpriseCustomer(EnterpriseCustomer ec);
          /**
           * 访问个人客户,相当于给个人客户添加访问者的功能
           * @param pc
           */
          public void visitPersonalCustomer(PersonalCustomer pc);
}

/**
 * 具体的访问者,实现对客户的偏好分析
 */
public class PredilectionAnalyzeVisitor implements Visitor {

           @Override
           public void visitEnterpriseCustomer(EnterpriseCustomer ec) {
                   // TODO 根据以往的购买历史、潜在购买意向,以及客户所在行业的发展趋势、客户的发展趋势等的分析
                   System.out.println("现在对企业客户" + ec.getName() + "进行产品偏好分析");
           }

           @Override
           public void visitPersonalCustomer(PersonalCustomer pc) {
                   System.out.println("现在对个人客户" + pc.getName() + "进行产品偏好分析");
           }

}

/**
 * 具体的访问者,实现客户提出服务请求的功能
 */
public class ServiceRequestVisitor implements Visitor {

           @Override
            public void visitEnterpriseCustomer(EnterpriseCustomer ec) {
                       // TODO 企业客户提出的具体服务请求
                       System.out.println(ec.getName() + "企业提出服务请求");
            }

            @Override
            public void visitPersonalCustomer(PersonalCustomer pc) {
                      // TODO 个人客户提出的具体服务请求
                     System.out.println("客户" + pc.getName() + "提出服务请求");
            }

}
public class ObjectStructure {

          /**
           * 要操作的客户集合
           */
          private Collection<Customer> col new ArrayList<Customer>();
          /**
           * 提供客户端操作的高层接口,具体的功能由客户端传入的访问者决定
           * @param visitor 客户端需要的访问者
           */
          public void handleRequest(Visitor visitor) {
                    for(Customer cm : col) {
                             cm.accept(visitor);
                     }
          }
          /**
           * 组建对象结构,想对象中添加元素
           * 不同的对象结构有不同的构建方式
           * @param ele 加入到对象的结构元素
           */
          public void addElement(Customer ele) {
                    this.col.add(ele);
          }
}

public class Client {

          public static void main(String[] args) {
  
                    ObjectStructure os = new ObjectStructure();
                    Customer cml = new EnterpriseCustomer();
                    cml.setName("ABC集团");
                    os.addElement(cml);
  
                    Customer cm2 = new EnterpriseCustomer();
                    cm2.setName("CDE公司");
                    os.addElement(cm2);
  
                    Customer cm3 = new PersonalCustomer();
                    cm3.setName("张三");
                    os.addElement(cm3);
  
                    ServiceRequestVisitor srVisitor = new ServiceRequestVisitor();
                    os.handleRequest(srVisitor);
  
                    PredilectionAnalyzeVisitor paVisitor = new PredilectionAnalyzeVisitor();
                    os.handleRequest(paVisitor);
  
                   WorthAnalyzeVisitor waVisitor = new WorthAnalyzeVisitor();
                   os.handleRequest(waVisitor);
         }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值