设计模式之行为型模式

2023-05-16

文章目录

    • 行为型模式(Behavioral Pattern)
      • 1. 观察者模式(Observer Pattern)
      • 2. 中介者模式(Mediator Pattern)
      • 3. 访问者模式(Visitor Pattern)
      • 4. 状态模式(State Pattern)
      • 5. 策略模式(Strategy Pattern)
      • 6. 命令模式(Command Pattern)
      • 7. 模板模式(Template Pattern)
      • 8. 责任链模式(Chain of Responsibility Pattern)
      • 9. 备忘录模式(Memento Pattern)
      • 10. 解释器模式(Interpreter Pattern)
      • 11. 迭代器模式(Iterator Pattern)

行为型模式(Behavioral Pattern)

在系统运行时,对象之间并不是孤立的,一个对象的运行会影响到其他对象。行为型模式通过划分类和对象的职责,关注系统在运行时对象之间的交互关系。

行为型模式分为类行为型模式和对象行为型模式两种:
类行为型模式:类的行为型模式使用继承关系在几个类之间分配行为,类行为型模式主要通过多态等方式来分配父类与子类的职责。
对象行为型模式:对象的行为型模式则使用对象的聚合关联关系来分配行为,对象行为型模式主要是通过对象关联等方式来分配两个或多个类的职责。

1. 观察者模式(Observer Pattern)

系统中的对象之间往往存在依赖关系,一个对象的改变会导致其他对象做出相应的反应。发生改变的叫做目标,收到改变通知的对象称作观察者,一个目标可以有多个观察者,观察者之间没有联系,方便扩展,是一种一对多的关系。每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新,故观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式。
在这里插入图片描述

A. 观察者模式的实现

public class ObserverPatternDemo {
  public static void main(String[] arg) {
    Subject sub = new Subject();
    BinaryObserver bo = new BinaryObserver();
    OctalObserver oo = new OctalObserver();
    sub.addObserver(bo);
    sub.addObserver(oo);
    
    sub.change(3);
    sub.change(8);
  }
}

public interface Observer {
  public void update(int i);
}
public class BinaryObserver extends Observer{

   public void update(int i) {
      System.out.println( "Binary String: " 
      + Integer.toBinaryString(i)); 
   }
}
public class OctalObserver extends Observer{
 
   public void update(int i) {
     System.out.println( "Octal String: " 
     + Integer.toOctalString(i)); 
   }
}

public class Subject {
  private List list;
  public Subject() {
    list = new ArrayList<Observer>();
  }
  public void addObserver(Observer o) {
    list.add(o);
  }
  public void notifyObserver(int i) {
    for(Observer o : list) {
      o.update(i);
    }
  }
  public void change(int i) {
    notifyObserver(i);
  }
}

B. 观察者模式的优缺
优:建立一套触发机制,解耦目标与观察者,符合开闭原则
缺:若观察者与目标直接按存在循环依赖,可能导致系统崩溃
C. 观察者模式适用场景
一个对象的改变将导致其他一个或多个对象也发生改变,但不知道具体有多少对象将发生改变;或者在系统中需要创建一个触发链。观察者模式可以用来实现MVC模式,观察者模式中的观察目标就是MVC模式中的模型(Model),而观察者就是MVC中的视图(View),控制器(Controller)充当两者之间的中介者(Mediator)。当模型层的数据发生改变时,视图层将自动改变其显示内容。

2. 中介者模式(Mediator Pattern)

当对象之间存在较多直接关联关系时,一个对象的变化会导致与之相关联的所有对象都得修改,复用性差,扩展性低。为了减少对象两两之间复杂的引用关系,使之成为一个松耦合的系统,我们引入中介者模式,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
中介者模式可以使对象之间的关系数量急剧减少。中介者主要承担两种职责。从结构上来讲起到中转作用,各个对象无需显式引用其他对象,需要通信时,通过中介者即可。从行为的较多来讲起到协调作用,中介者将对象之间的关系进行封装,将同事成员之间的关系行为进行分离和封装。
在这里插入图片描述

每个同事类需要通过中介者对象与其他对象交互。中介者对象一般需要保持参与通信的所有对象

  • Mediator是抽象中介者,定义了同事对象到中介者对象的接口
  • ConceteMediator是具体中介对象,需要直到所有参与通信的同事对象,并完成对象之间的通信
  • Colleague是抽象同事类
  • ConcreteColleague具体同事类,有单独的行为,不了解其他同事类的行为

A. 中介者模式的实现

public class MediatorPatternDemo {
  public static void main(String[] arg) {
    Mediator mailBox = new MailBox();
    Colleague sender = new Sender(mailBox);
    Colleague postman= new Postman(mailBoz);
    
    sender.mail();
  }
}

public interface class Mediator {
  public void getMessage(Colleague c);
}
public class MailBox implements Mediator {
  public void getMessage(Colleague c) {
    if(c instanceof Sender) {
      System.out.print("send mail");
    } else if (c instanceof Postman) {
      System.out.print("get mail");
    }
  }
  
}

public interface Colleague {
  public void mail();
}
public class Sender implements Colleague {
  private Mediator med;
  public Sender(Mediator m) {
    this.med = m;
  }
  public void mail() {
    med.getMessage(this);
  }
}
public class Postman implements Colleague {
  private Mediator med;
  public Postman(Mediator m) {
    this.med = m;
  }
  public void mail() {
    med.getMessage(this);
  }
}

B. 中介者模式的优缺
优:较少了对象间得交互,将对象之间解耦
缺:中介者实现了交互细节,可能会复杂难以维护
C. 中介者模式的适应环境
对象之间存在复杂得引用关系,结构混乱,难以复用。MVC中的控制器就是中介者

3. 访问者模式(Visitor Pattern)

在大部分场景中,一个元素可能会有多个方法来操作它,而被访问对象与访问方法之间的耦合不利于访问方法的扩展。访问者模式通过将访问方法封装使之与访问对象分离,在被访问对象的类中添加一个访问自己的方法来与访问者进行关联(将访问者作为参数传入,访问者调用的是当前访问对象)。访问方法可以独立于访问对象而变化。
在这里插入图片描述

Visitor是抽象访问者,为具体的访问行为行为提供操作
ConcreteVisitor是具体访问者,实现具体访问方法
ObjectStructure包含参与访问的所有对象,定义接口允许访问者访问元素
Element定义一个accept方法,接收一个访问者对象
ConcreteElement为具体元素,实现accept方法

A. 访问者模式的实现

public class VisitorPatternDemo {
  public static void main(String[] arg) {
    Computer cmp = new Computer();
    ComputerPart keyBoard = new KeyBoard("keyboard");
    ComputerPart mouse = new Mouse("mouse");
    ComputerVisitor visitor = new ComputerVisitor();
    //ComputerVisitor visitor2 = new ComputerVisitor2();
    cmp.addElement(keyBpard);
    cmp.addElement(mouse);
    
    cmp.display(visitor);
    //cmp.display(visitor2);
  }
}
public class Computer {
  private List<ComputerPart> elements;
  public Computer() {
    list = new ArrayList<ComputerPart>();
  }
  public void addElement(Element e) {
    elements.add(e);
  }
  public void display(Visitor v) {
    for(ComputerPart cp : elements) {
      //由元素发起调用,针对不同的访问方法,应用于同一元素
      cp.accept(v);
    }
  }
}

public abstract class ComputerPart {
  private String name;
  public ComputerPart(String name) {
    this.name = name;
  }
  public String getName() {
    return this.name;
  }
  public void accept(Visitor v);
}
public class KeyBord extends ComputerPart {
  public KeyBord(String name) {
    super(name);
  }
  public void accept(Visitor v) {
    v.visit(this);
  }
}
public class Mouse extends ComputerPart {
  public Mouse(String name) {
    super(name);
  }
  public void accept(Visitor v) {
    v.visit(this);
  }
}

public interface Visitor {
  public void visit(ComputerPart part);
}
public class ComputerVisitor {
  public void visit(ComputerPart part) {
    System.out.print(part.getName());
  }
}

B. 访问者模式的优缺
优:符合单一职责原则,高扩展性
缺:被访问对象变更困难
C. 访问者模式的适用场景
对象很少变化而在其上的操作经常变化

4. 状态模式(State Pattern)

在一些场景中,对象的行为会根据一些属性的取值而发生变化。这些变化的属性叫做状态,对象与外部事件的交互会使状态发生变化,行为相应也会变化。状态模式的关键是引入了一个抽象类来专门表示对象的状态,对象的每一种具体状态类都继承了该类,不同的具体状态类实现了不同状态的行为。状态与行为一一对应。
在这里插入图片描述

环境类是拥有状态的对象,在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象,可以定义初始状态;
抽象状态类用于定义一个接口以封装与环境类的一个特定状态相关的行为;
具体状态类是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。

A. 状态模式的实现

public class StatePatternDemo {
  public static void main(String[] arg) {
    Switch s = new Switch();
    for(int i = 0; i < 5; i++) {
      s.operation();
    }
  }
}

public class Switch {
  //初始状态
  private State state;
  
  public Switch() {
    state = new Off();
  }
  public void setState(State s) {
    this.state = s;
  }
  public void operation() {
    System.out.println("Current state is" + this.state.name);
    state.action(this);
  }
}
public abstract class State {
  public String name;
  public State(String name) {
    this.name = name;
  }
  public String getName() {
    return this.name;
  }
  public abstract void action(Switch s);
}

public class Off extends State {
  public Off() {
    super("off");
  }
  public void action(Switch s) {
    s.setState(new On());
  }
}
public class On extends State {
  public On() {
    super("on");
  }
  public void action(Switch s) {
    s.setState(new Off());
  }
}

B. 状态模式的优缺
优:封装了转换规则,方便增加新状态;多个环境对象可共享一个状态对象
缺:增加类的数量,增加状态时还需修改状态转换的源码
C. 状态模式的适用
代码中包含大量与对象状态有关的条件语句;或者对象的行为依赖于状态比如代办事项,已完成,未完成等。

5. 策略模式(Strategy Pattern)

在系统设计中,实现某一功能的方式可能有多种,其中每一种方式称为一个策略。策略模式通过将每一种算法封装为独立的策略类,可以灵活的选择并添加新的策略。一般会用一个抽象的策略类来做算法的定义,而具体每种算法则对应于一个具体策略类,使算法独立于使用它的客户而变化。
在这里插入图片描述

A. 策略模式的实现

public class StrategyPatternDemo {
  public static void main(String[] arg) {
    Context c = new Context();
    
    Strategy add = new AddStrategy();
    c.setStrategy(add);
    System.out.print("2+1=%d", c.execute(2, 1));
    Strategy sub = new SubStrategy();
    c.setStrategy(sub);
    System.out.print("2-1=%d", c.execute(2, 1));
  }
}

public class Context {
  private Strategy strategy;
  public void setStrategy(Strategy strategy) {
    this.strategy = strategy ;
  }
  public int execute(int x, int y) {
    return strategy.operation(x, y);
  }
}

public interface Strategy {
  public int operation(int x, int y);
}
public class AddStrategy implements Strategy {
  public int operation(int x, int y) {
    return x + y;
  }
}
public class SubStrategy implements Strategy {
  public int operation(int x, int y) {
    return x - y;
  }
}

B. 策略模式的优缺
优:符合开闭原则,灵活更换或添加算法,避免多重条件转移
缺:产生多个策略类;调用端需要了解所有类略类

C. 策略模式的适用环境
系统中出现复杂多重判断;一系列算法行为需要相互替换;系统中有很多类,区别仅在于行为差异。

6. 命令模式(Command Pattern)

在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但是有时需要对行为进行记录或者撤销,紧耦合的方式就非常不便。命令模式则通过将行为抽象为对象,实现行为的请求者与接受者之间解耦,请求者与接收者之间没有直接引用关系。命令模式的本质是对命令进行封装,将命令的请求者与接收者分割开,请求放不必知道接收方的接口及命令的执行过程。命令模式的关键在于引入了抽象命令接口,命令请求者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。命令模式也称为动作(Action)模式或事务(Transaction)模式。

在这里插入图片描述

Invoker是调用者,命令的发送端
Receiver是接收者,命令的具体实施者
Command是命令类,对所有命令进行抽象
ConcreteCommand是具体命令,将命令的接收者与命令绑定,执行接受者的相应操作

A.命令模式的实现

public interface Command {
  public void execute();
  public void undo();
}

//定义一个灯类,以及对灯的操作
public class LightReceiver {
  public void on() {
    System.out.print("light on");
  }
  public void off() {
    System.out.print("light off");
  }
}

//定义一个开灯的命令
public class LightOnCommand implements Command {
  private LightReceiver light;
  public LightOnCommand(LightReceiver light) {
    this.light = light;
  }
  public void execute() {
    light.on();
  }
  public void undo() {
    light.off();
  }
}
//定义一个关灯的命令
public class LightOffCommand implements Command {
  private LightReceiver light;
  public LightOffCommand(LightReceiver light) {
    this.light = light;
  }
  public void execute() {
    light.off();
  }
  public void undo() {
    light.on();
  }
}
//空对象模式(Null Object Pattern)
//定义一个空命令,便于初始化,提供默认行为,省掉空操作判断
public class NullCommand implements Command {
  public void execute() {}
  public void undo() {}
}

public class RemoteController {
  //对命令进行分组
  Command[] onCommands;
  Command[] offCommands;
  Command undoCommand;
  
  public RemoteController(int n) {
      onCommands = new Command[n];
      offCommands = new Command[n];
      for(int i = 0; i < n; i++) {
        onCommands[i] = new NullCommand();
        offCommands[i] = new NullCommand();
      }
  }
  public void setCommand(int num, Command onCommand, Command offCommand) {
    onCommands[num] = onCommand;
    offCommands[num] = offCommand;
  }

  public void onButton(int i) {
    onCommand[i].execute();
    undoCommand = onCommand[i];
  }
  public void offButton(int i) {
    offCommand[i].execute();
    undoCommand = offCommand[i];
  }
  public void undo() {
    undoCommand.undo();
  }
}

public class CommandPatternDemo {
  public static void main(String[] arg) {
    //定义一个遥控器和一个灯分别作为命令的发起与接受端
    RemoteController controller = new RemoteController(3);
    LightReceiver light = new LightReceiver();
    //定义两个命令
    Command lightOn = new LightOnCommand(light);
    Command lightOff = new LightOffCommand(light);
    //添加命令到控制器
    controller.setCommand(0, lightOn, lightOff);
    controller.onButton(0);
    controller.offButton(0);
    controller.undo();
  }
}

B. 命令模式的优缺
优:降低耦合度,易添加新的命令,易实现行为的撤销操作
缺:产生过多命令类

C. 命令模式的适用场景
系统需要命令的发送与接收端解耦,不得直接交互
系统需要在不同的时间指定请求、将请求排队和执行请求。
系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
系统需要将一组操作组合在一起,即支持宏命令

7. 模板模式(Template Pattern)

在系统功能实现时可能会有很多方法算法步骤大同小异,存在通用方法,为避免重复编写,可以对方法的的公共部分进行抽象,将算法的实现延迟到子类中。通过定义方法的模板,可以在不改变算法结构的情况下按需重写方法。一般模板方法都加上 final 关键词,保证它就不会被重写,以防止恶意操作。
在这里插入图片描述

AbstractClass抽象类,类中实现了模板方法,定义了算法的执行框架
ConcreteClass实现了抽象类中的方法

A. 模板模式的实现

public class TemplatePatternDemo {
  public static void main(String[] arg) {
    Game game = new Football();
    game.play();
    
    game = new Jump();
    game.play();
  }
}

public abstract class Game {
  public abstract void initialize();
  public abstract void start();
  public abstract void end();
  
  public final void play() {
    initialize();
    start();
    end();
  }
}
public class Jump extends Game {
  public abstract void initialize() {
    System.out.println("initialize ...");
  }
  public abstract void start() {
    System.out.println("start jump");
  }
  public abstract void end() {
    System.out.println("end jump");
  }
}
public class Football extends Game {
  public abstract void initialize() {
    System.out.println("initialize ...");
  }
  public abstract void start() {
    System.out.println("start football");
  }
  public abstract void end() {
    System.out.println("end football");
  }
}

B. 模板模式的优缺
优:封装不变部分,扩展可变部分,行为由父类控制,实现由子类确定,易维护
缺:不同的实现都要重新定义类,可能导致类数量增加
C. 模板模式的使用场景
多个方法有公共方法且整体逻辑相同。

8. 责任链模式(Chain of Responsibility Pattern)

为避免请求的发送方与接收方耦合,可以尝试让多个对象都接收请求,把这些对象连成链,请求沿该链传递,直到有对象成功接收为止。责任链模式就是为请求创建了一个接收者对象的链来实现发送者与接收者的解耦。每个接收者包含另一个接收者的引用,如果当前对象不能处理请求则把请求传递到下一个接收者。
图片: https://uploader.shimo.im/f/wpDAxQ6lD0dp9Qm1.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjUwNDE5NDYsImZpbGVHVUlEIjoiR3FENkpURFRUM3ZReWdLWCIsImlhdCI6MTY2NTA0MTY0NiwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo2NjY4ODY1NX0.EqqnHwnmhL-XbKUL69wxGVRiDwjgNmjyMf2h0-Ne3SI

A. 责任链模式的实现

public class PurchaseRequest {
  private float price;
  public PurchaseRequest(float price) {
    this.price = price;
  }
  public float getPrice() {
    return this.price;
  }
}
public abstract class Approver {
  private Approver next;
  private String name;
  
  public Approver(String name) {
    this.name = name;
  }
  public void setNext(Approver app) {
    this.next = app;
  }
  public abstract void process(PurchaseRequest r);
}

public class DepartmentApprover extends Approver {
  public DepartmentApprover(String name) {
    super(name);
  }
  public void process(PurchaseRequest r) {
    if(r.getPrice() <= 1000) {
      System.out.print(r.getPrice() +"-->"+ this.name);
    } else {
      next.process(r);
    }
  }
}
public class CollegeApprover extends Approver {
  public CollegeApprover(String name) {
    super(name);
  }
  public void process(PurchaseRequest r) {
    if(r.getPrice() > 1000 && r.getPrice() <= 2000) {
      System.out.print(r.getPrice() +"-->"+ this.name);
    } else {
      next.process(r);
    }
  }
}
public class UniversityApprover extends Approver {
  public UniversityApprover(String name) {
    super(name);
  }
  public void process(PurchaseRequest r) {
    if(r.getPrice() > 2000) {
      System.out.print(r.getPrice() +"-->"+ this.name);
    } else {
      next.process(r);
    }
  }
}

public class ResponsibilityChainDemo {
  public static void main(string[] arg) {
    PurchaseRequest r = new PurchaseRequest(1500);
    DepartmentApprover d = new DepartmentApprover("主任");
    CollegeApprover c = new CollegeApprover("院长");
    UniversityApprover u = new UniversityApprover("校长");
    
    //设置为环形链,可以从任意位置开始判断
    d.setNext(c);
    c.setNext(u);
    u.setNext(d);
    
    d.process(r);
  }
}

B. 责任链模式的优缺
优:降低耦合,方便增加新的请求处理类
缺:请求不一定被接收,不易观察运行时的特征,调试不方便
C. 责任链模式的适用场景
多个条件一次依赖;多个对象可以处理同一个请求;或者不明确接收者时,向多个对象提交一个请求;JS 中的事件冒泡

9. 备忘录模式(Memento Pattern)

在一些情况下我们需要保存对象的某个状态,允许用户错误操作后恢复之前的状态。备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便可以在以后将对象恢复到原先保存的状态。为了符合迪米特原则,还要增加一个备忘录管理类,客户端不直接与备忘录类耦合,而与备忘录管理类耦合。为了节约内存,可使用原型模式+备忘录模式。
在这里插入图片描述

Memento用于封装状态
Originator用于操作memento,决定存档还是读档
CareTaker用于保存记录的若干个memento
CareTaker相当于是个记事本,memento是其中的一页,originator是记录和查找的人,一次只处理一页,不让客户直接操作memento,避免强耦合。

A.备忘录模式的实现

public class MementoPatternDemo {
  public static void main(String[] arg) {
    //定义一个备忘录笔记本
    CareTaker book = new CareTaker();
    //定义一个记录笔
    Originator org = new Originator();
    
    //每一页备忘录由originator来处理
    org.setState("State I");
    org.setState("State II");
    //创建一页备忘录,将状态II记录在案
    Memento item = org.saveStateToMemento();
    //提交到笔记本中
    book.add(item);
    
    org.setState("State III");
    book.add(org.saveStateToMemento());
    //查找状态II
    item = book.get(0);
    //恢复状态,将当前状态设置为状态II
    org.getStateFromMemento(item);
  }
}

public class Memento {
  private String state;
  public Memento(String s) {
    state = s;
  }
  public String getState() {
    return state;
  }
}
public class CareTaker {
  private List mementoList;
  public CareTaker() {
    mementoList = new ArrayList<Memento>();
  }
  public void add(Memento m) {
    mementoList.add(m);
  }
  public Memento get(int index) {
    return mementoList.get(index);
  }
}
public class Originator {
  private String state;
  public void setState(String state){
      this.state = state;
  }
  public Memento saveStateToMemento(){
      return new Memento(state);
  }
  public void getStateFromMemento(Memento Memento){
      state = Memento.getState();
  }
}

B. 备忘录模式的优缺
优:提供了状态恢复的机制
缺:耗费资源
C. 备忘录模式的适用环境
需要恢复数据的场景中

10. 解释器模式(Interpreter Pattern)

解释器模式提供了一种解析文法或表达式的方式,通过实现一个接口来解释给定的上下文。比如sql解析等
在这里插入图片描述

A. 解释器模式的实现

public class InterpreterPatternDemo {
  public static void main(String[] arg) {
    Expression julie = new TerminalExpression("Julie");
    Expression married = new TerminalExpression("Married");
    Expression exp = new AndExpression(julie, married); 
    System.out.println("Julie is a married women? " 
      + exp.interpret("Married Julie"));   
  }
}

public interface Expression {
  public boolean interpret(String context);
}
public class TerminalExpression implements Expression {
  
  private String data;
  
  public TerminalExpression(String data) {
    this.data = data;
  }
  
  public boolean interpret(String context) {
    if(context.contains(data)) return true;
    return false;
  }
}
public class AndExpression implements Expression {
  private Expression exp1;
  private Expression exp2;
  
  public AndExpression(Expression e1, Expression e2) {
    this.exp1 = e1;
    this.exp2 = e2;
  }
  public boolean interpret(String context) {      
      return exp1.interpret(context) && exp2.interpret(context);
   }
}

B. 解释器模式的优缺
优:易实现简单文法,扩展性好
缺:应用场景特殊且少,复杂文法难维护,解释器模式采用递归调用
C. 解释器模式的适用场景
将要解释的句子表示为抽象语法树或复杂逻辑用简单语言来表达。Java中可以用expression4J

11. 迭代器模式(Iterator Pattern)

迭代器模式用于顺序访问集合对象的元素而无需了解集合对象的底层表示。元素间的游走操作交给迭代器而不是聚合对象。常见的接口入hasNext, next。
在这里插入图片描述

A. 迭代模式的实现

public class IteratorPatternDemo {
  public static void main(String[] arg) {
    Container record = new NameRecord();
    
    for(Iterator it = record.getIterator(); it.hasNext();) {
      System.out.println((String)it.next());
    }
  }
}

public interface Iterator {
  public boolean hasNext();
  public Object next();
}
public interface Container {
  public Interator getIterator();
}

public class NameRecord implements Container {
  public String[] names = {"jack", "tom", "henry"};
  
  public Iterator getIterator() {
    return new NameIterator();
  }
  
  public class NameIterator implements Iterator {
    private int index = 0;
    public boolean hasNext() {
      if(index < names.length) return true;
      return false;
    }
    public Object next() {
      if(this.hasNext()) return names[index++];
      return null;
    }
  }
}

B. 迭代模式的优缺
优:支持以不同的方式遍历聚合对象,方便增加新的聚合类和迭代器类
缺:迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类
C.迭代模式的适用场景
聚合对象需要多种遍历方式;或者遍历聚合对象时无需暴露内部表示

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式之行为型模式 的相关文章

随机推荐

  • 动态链接库与静态链接库的区别

    静态链接库与动态链接库都是共享代码的方式 xff0c 如果采用静态链接库 xff0c 则无论你愿不愿意 xff0c lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了 但是若使用 DLL xff0c 该 DLL 不必被包含在最终
  • ssm——小学期实训总结

    实训总结 经过这两个星期短暂的学习 xff0c 我学习了ssm的框架搭建与web前端设计基础 在第一个星期 xff0c 老师着重为我们讲了框架的原理 搭建与运用 xff1b 而在第二个星期 xff0c 重点则转移到了小组对项目的开发与研究上
  • 节点中心性

    文章目录 度中心性 Degree Centrality 特征向量中心性 Eigenvector Centrality Katz中心性 Katz Centrality Katz index PageRank中心性PageRank算法 接近中心
  • 机器学习面试知识点总结

    文章目录 计算学习理论过拟合与欠拟合过拟合欠拟合 偏差与方差最大似然估计与贝叶斯估计极大似然估计贝叶斯决策论贝叶斯估计 特征工程与特征选择特征工程逐层归一化特征选择 模型融合融合策略 评估方法与评价指标评估方法评价指标 优化算法正则化深度模
  • Multi-view graph convolutional networks with attention mechanism

    摘要 传统的图卷积网络关注于如何高效的探索不同阶跳数 hops 的邻居节点的信息 但是目前的基于GCN的图网络模型都是构建在固定邻接矩阵上的即实际图的一个拓扑视角 当数据包含噪声或者图不完备时 xff0c 这种方式会限制模型的表达能力 由于
  • An Empirical Study of Graph Contrastive Learning

    摘要 图对比学习在图表示学习领域树立了新的范式 xff0c 不需要人工标注信息 但对GCL的分析却寥寥无几 本文通过分析一般化的GCL范式的各个部分包括增强函数 xff0c 对比模式 xff0c 对比目标和负采样技术 xff0c 然后分析各
  • Data Augmentation

    自监督深度学习模型的精确性严重依赖于训练时数据的多样性和数据量 模型要想在更复杂任务上有较好的效果一般会有大量的隐藏单元 一般在训练过程中训练隐藏单元越多需要的数据越多 xff0c 即任务复杂度与参数量与需要的数据量成正比 由于训练复杂任务
  • Semi-Supervised and Self-Supervised Classification with Multi-View Graph Neural Networks

    摘要 图神经网络在图结构数据中取得了很好的效果但是大多数的模型使用的还是叫浅层的结构 xff0c 当模型层数加深时很容易过平滑 本文基于多视图来聚合更多的信息 我们首先设计两个互补的视图来描述全局结构和节点特征相似性 xff0c 然后使用注
  • GCC: Graph Contrastive Coding for Graph Neural Network Pre-Training

    摘要 目前图表示学习在许多任务上取得了很好的效果但是都是关注于具体领域的并不具有迁移性 本文借鉴预训练思想 xff0c 设计了一个自监督图神经网络框架来在多个网络中捕获一般化的网络拓扑结构属性 我们设计的预训练任务是在多个网络之间判别子图实
  • Graph Contrastive Learning with Adaptive Augmentation

    摘要 对比学习在无监督图表示学习中取得了很好的效果 xff0c 大部分图对比学习首先对输入图做随机增强生成两个视图然后最大化两个视图表示的一致性 其中 xff0c 图上的增强方式是非常重要的部分鲜有人探索 我们认为数据增强模式应该保留图固有
  • A Survey on Graph Structure Learning: Progress and Opportunities

    文章目录 摘要引言预备知识GSL pipline Graph Structure ModelingMetric based ApproachesNeural ApproachesDirect Approaches Postprocessin
  • 图构造总结-Graph‑based semi‑supervised learning via improving the quality of the graph dynamically

    前言 本博文主要对论文中提到的图构造方法进行梳理 xff0c 论文自己提出的模型并未介绍 xff0c 感兴趣的可以阅读原文 摘要 基于图的半监督学习GSSL主要包含两个过程 xff1a 图的构建和标签推测 传统的GSSL中这两个过程是完全独
  • 超图构造综述,Hypergraph Learning: Methods and Practices

    文章目录 摘要引言基础知识Hypergraph GenerationDistance based hypergraph generationRepresentation based hypergraph generationAttribut
  • 图论基础知识总结

    文章目录 图的概念路图的代数表示邻接矩阵可达矩阵完全关联矩阵拉普拉斯矩阵对称归一化拉普拉斯矩阵随机游走归一化拉普拉斯矩阵 欧拉图与汉密尔顿图平面图对偶与着色数与生成树最小生成树算法 xff1a 根树图的存储邻接矩阵邻接表十字链表邻接多重表
  • 图增强与图对比学习

    文章目录 对比学习数据增强基于特征的增强基于结构的增强基于采样的增强自适应的增强 代理任务同尺度对比跨尺度对比 目标函数参考 CSDN排版太垃圾了 xff0c 点此连接去知乎看吧 xff01 xff01 xff01 xff01 xff01
  • K-Core, K-Shell & K-Crust傻傻分不清楚

    K Core算法是用于在图中寻找符合一定紧密关系条件的子图结构的算法 xff0c 通常用于进行子图划分 xff0c 去除不重要的结点 参考论文k core Theories and applications ScienceDirect K
  • 社区发现算法总结

    图划分指将网络顶点划分为指定规模 xff0c 指定数量的非重叠群组 xff0c 使得群组之间的边数最小 图划分时 xff0c 群组的数量和规模是固定的 社区发现不同于图划分的是网络群组的数量和规模不是由实验者确定的 xff0c 而是由网络本
  • 机器学习面经--常见问题

    csdn的排版真的太垃圾了 xff0c 想看的移步知乎 1 xff0c Normalization 数据标准化处理主要包括数据同趋化处理和无量纲化处理两个方面 数据同趋化处理主要解决不同性质数据问题 xff0c 对不同性质指标直接加总不能正
  • 设计模式之创建型模式

    文章目录 创建型模式 Creational Pattern 1 1单例模式 Singleton Pattern 1 2工厂模式 Factory Pattern 1 3抽象工厂模式 Abstract Factory Pattern 1 4建造
  • 设计模式之行为型模式

    文章目录 行为型模式 Behavioral Pattern 1 观察者模式 Observer Pattern 2 中介者模式 Mediator Pattern 3 访问者模式 Visitor Pattern 4 状态模式 State Pat