0
点赞
收藏
分享

微信扫一扫

万字解析设计模式之迭代器模式、备忘录模式

一、迭代器模式

1.1概述

1.2结构

1.3实现

 

package com.yanyu.Iterator;

public class Student {
    private String name;

    private String number;

    public Student(String name, String number) {
        this.name = name;
        this.number = number;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number='" + number + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }


}

抽象迭代器(Iterator)角色

package com.yanyu.Iterator;

public interface StudentIterator {
    boolean hasNext();
    Student next();
}

具体迭代器(Concretelterator)角色

package com.yanyu.Iterator;


import java.util.List;

public class StudentIteratorImpl implements StudentIterator {
    private List<Student> list;
    private int position = 0;

    public StudentIteratorImpl(List<Student> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return position < list.size();
    }

    @Override
    public Student next() {
        Student currentStudent = list.get(position);
        position ++;
        return currentStudent;
    }
}

 抽象聚合(Aggregate)角色

package com.yanyu.Iterator;


public interface StudentAggregate {
    void addStudent(Student student);

    void removeStudent(Student student);

    StudentIterator getStudentIterator();
}

具体聚合(ConcreteAggregate)角色

package com.yanyu.Iterator;

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

public class StudentAggregateImpl implements StudentAggregate {

    private List<Student> list = new ArrayList<Student>();  // 学生列表

    @Override
    public void addStudent(Student student) {
        this.list.add(student);
    }

    @Override
    public void removeStudent(Student student) {
        this.list.remove(student);
    }

    @Override
    public StudentIterator getStudentIterator() {
        return new StudentIteratorImpl(list);
    }
}

客户端类

package com.yanyu.Iterator;

public class Client {
    public static void main(String[] args) {
        // 创建聚合对象
        StudentAggregateImpl aggregate = new StudentAggregateImpl();
        // 添加元素
        aggregate.addStudent(new Student("张三", "001"));
        aggregate.addStudent(new Student("李四", "002"));
        aggregate.addStudent(new Student("王五", "003"));
        aggregate.addStudent(new Student("赵六", "004"));

        // 遍历聚合对象
        // 1. 获取迭代器对象
        StudentIterator iterator = aggregate.getStudentIterator();
        // 2. 遍历
        while(iterator.hasNext()) {
            // 3. 获取元素
            Student student = iterator.next();
            System.out.println(student.toString());
        }
    }
}

1.4优缺点

1.5应用场景 

二、备忘录模式

2.1概述

2.2结构

2.3实现

【例】游戏挑战BOSS

游戏中的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗之前的状态。

要实现上述案例,有两种方式:

  • “白箱”备忘录模式
  • “黑箱”备忘录模式

“白箱”备忘录模式

备忘录角色对任何对象都提供一个接口,即宽接口,备忘录角色的内部所存储的状态就对所有对象公开。类图如下

 发起人


package com.yanyu.memory.whitebox;

//游戏角色类
public class GameRole {
    private int vit; //生命力
    private int atk; //攻击力
    private int def; //防御力

    //初始化状态
    public void initState() {
        this.vit = 100; // 初始化生命力为100
        this.atk = 100; // 初始化攻击力为100
        this.def = 100; // 初始化防御力为100
    }

    //战斗
    public void fight() {
        this.vit = 0; // 生命力归零
        this.atk = 0; // 攻击力归零
        this.def = 0; // 防御力归零
    }

    //保存角色状态
    public RoleStateMemento saveState() {
        return new RoleStateMemento(vit, atk, def); // 创建并返回包含当前状态的备忘录对象
    }

    //回复角色状态
    public void recoverState(RoleStateMemento roleStateMemento) {
        this.vit = roleStateMemento.getVit(); // 恢复生命力
        this.atk = roleStateMemento.getAtk(); // 恢复攻击力
        this.def = roleStateMemento.getDef(); // 恢复防御力
    }

    public void stateDisplay() {
        System.out.println("角色生命力:" + vit); // 显示生命力
        System.out.println("角色攻击力:" + atk); // 显示攻击力
        System.out.println("角色防御力:" + def); // 显示防御力
    }

    public int getVit() {
        return vit; // 返回生命力
    }

    public void setVit(int vit) {
        this.vit = vit; // 设置生命力
    }

    public int getAtk() {
        return atk; // 返回攻击力
    }

    public void setAtk(int atk) {
        this.atk = atk; // 设置攻击力
    }

    public int getDef() {
        return def; // 返回防御力
    }

    public void setDef(int def) {
        this.def = def; // 设置防御力
    }
}

备忘录(Memento)角色

package com.yanyu.memory.whitebox;


//游戏状态存储类(备忘录类)
public class RoleStateMemento {
    private int vit; // 生命力
    private int atk; // 攻击力
    private int def; // 防御力

    // 构造函数,传入生命力、攻击力、防御力进行初始化
    public RoleStateMemento(int vit, int atk, int def) {
        this.vit = vit; // 初始化生命力
        this.atk = atk; // 初始化攻击力
        this.def = def; // 初始化防御力
    }

    // 获取生命力
    public int getVit() {
        return vit; // 返回生命力
    }

    // 设置生命力
    public void setVit(int vit) {
        this.vit = vit; // 设置生命力
    }

    // 获取攻击力
    public int getAtk() {
        return atk; // 返回攻击力
    }

    // 设置攻击力
    public void setAtk(int atk) {
        this.atk = atk; // 设置攻击力
    }

    // 获取防御力
    public int getDef() {
        return def; // 返回防御力
    }

    // 设置防御力
    public void setDef(int def) {
        this.def = def; // 设置防御力
    }
}

管理者(Caretaker)角色

package com.yanyu.memory.whitebox;

//角色状态管理者类
public class RoleStateCaretaker {
    private RoleStateMemento roleStateMemento; // 保存角色状态的备忘录对象

    // 获取角色状态的备忘录对象
    public RoleStateMemento getRoleStateMemento() {
        return roleStateMemento; // 返回角色状态的备忘录对象
    }

    // 设置角色状态的备忘录对象
    public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
        this.roleStateMemento = roleStateMemento; // 设置角色状态的备忘录对象
    }
}

客户端类

package com.yanyu.memory.whitebox;



//测试类
public class Client {
    public static void main(String[] args) {
        System.out.println("------------大战Boss前------------");
        //大战Boss前
        GameRole gameRole = new GameRole(); // 创建游戏角色对象
        gameRole.initState(); // 初始化角色状态
        gameRole.stateDisplay(); // 显示角色状态

        //保存进度
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker(); // 创建角色状态管理者对象
        roleStateCaretaker.setRoleStateMemento(gameRole.saveState()); // 保存当前角色状态到备忘录对象

        System.out.println("------------大战Boss后------------");
        //大战Boss时,损耗严重
        gameRole.fight(); // 模拟角色大战Boss,损耗状态
        gameRole.stateDisplay(); // 显示角色损耗后的状态
        System.out.println("------------恢复之前状态------------");
        //恢复之前状态
        gameRole.recoverState(roleStateCaretaker.getRoleStateMemento()); // 恢复之前保存的角色状态
        gameRole.stateDisplay(); // 显示恢复后的角色状态
    }
}

“黑箱”备忘录模式

窄接口 

package com.yanyu.memory.blackbox;

public interface Memento {
}

 发起人

package com.yanyu.memory.blackbox;


// 游戏角色类
public class GameRole {
    private int vit; // 生命力
    private int atk; // 攻击力
    private int def; // 防御力

    // 初始化状态
    public void initState() {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    // 战斗
    public void fight() {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }

    // 保存角色状态
    public Memento saveState() {
        return new RoleStateMemento(vit, atk, def);
    }

    // 回复角色状态
    public void recoverState(Memento memento) {
        RoleStateMemento roleStateMemento = (RoleStateMemento) memento;
        this.vit = roleStateMemento.getVit();
        this.atk = roleStateMemento.getAtk();
        this.def = roleStateMemento.getDef();
    }

    public void stateDisplay() {
        System.out.println("角色生命力:" + vit);
        System.out.println("角色攻击力:" + atk);
        System.out.println("角色防御力:" + def);
    }

    public int getVit() {
        return vit;
    }

    public void setVit(int vit) {
        this.vit = vit;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDef() {
        return def;
    }

    public void setDef(int def) {
        this.def = def;
    }

    // 角色状态备忘录类
    private class RoleStateMemento implements Memento {
        private int vit;
        private int atk;
        private int def;

        public RoleStateMemento(int vit, int atk, int def) {
            this.vit = vit;
            this.atk = atk;
            this.def = def;
        }

        public int getVit() {
            return vit;
        }

        public void setVit(int vit) {
            this.vit = vit;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }
    }
}

管理者角色

package com.yanyu.memory.blackbox;


//角色状态管理者类
public class RoleStateCaretaker {
    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}

 客户端类

package com.yanyu.memory.blackbox;

public class Client {
    public static void main(String[] args) {
        System.out.println("------------大战Boss前------------");
        //大战Boss前
        GameRole gameRole = new GameRole();
        gameRole.initState();
        gameRole.stateDisplay();
        //保存进度
        RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
        roleStateCaretaker.setMemento(gameRole.saveState());

        System.out.println("------------大战Boss后------------");
        //大战Boss时,损耗严重
        gameRole.fight();
        gameRole.stateDisplay();
        System.out.println("------------恢复之前状态------------");
        //恢复之前状态
        gameRole.recoverState(roleStateCaretaker.getMemento());
        gameRole.stateDisplay();
    }
}

三、迭代器模式实验

抽象迭代器

package step1;
//抽象迭代器
public interface AbstractInterator{
     void next();    //移至下一个元素
     boolean isLast();   //判断是否为最后一个元素
     void previous();   //移至上一个元素
     boolean isFirst();  //判断是否为第一个元素
     Object getNextItem();  //获取下一个元素
     Object getPreviousItem();   //获取上一个元素
}

具体迭代器

package step1;

import java.util.List;

// 抽象迭代器容器
public abstract class AbstractObjectList {
    // 定义对象列表
    protected List<Object> objects;

    // 构造方法,接收一个对象列表
    public AbstractObjectList(List objects) {
        this.objects = objects;
    }

    // 添加对象到列表
    public void addObject(Object obj) {
        this.objects.add(obj);
    }

    // 从列表中移除对象
    public void removeObject(Object obj) {
        this.objects.remove(obj);
    }

    // 获取对象列表
    public List getObjects() {
        return this.objects;
    }

    // 声明创建迭代器对象的抽象工厂方法
    public abstract AbstractInterator createIterator();
}

 抽象聚合(Aggregate)角色

package step1;

import java.util.List;
//具体商品的容器
public class ProductList extends AbstractObjectList{
    public ProductList(List products) {

        super(products);
    }

    //实现创建迭代器对象的具体方法
    @Override
    public AbstractInterator createIterator() {

        return new ProductIterator(this);
    }
}

具体聚和角色

package step1;

import java.util.List;

// 具体商品的迭代器
public class ProductIterator implements AbstractInterator {
    private List products;  // 商品列表
    private int cursor1;     // 定义一个游标,用于记录正向遍历的位置
    private int cursor2;     // 定义一个游标,用于记录逆向遍历的位置

    // 构造方法,接收一个商品列表
    public ProductIterator(ProductList list) {
        this.products = list.getObjects();  // 获取集合对象
        cursor1 = 0;    // 设置正向遍历游标的初始值
        cursor2 = products.size() - 1;  // 设置逆向遍历游标的初始值
    }

    @Override
    public void next() {
        if (cursor1 < products.size()) {
            cursor1++;
        }
    }

    @Override
    public boolean isLast() {
        return (cursor1 == products.size());
    }

    @Override
    public void previous() {
        if (cursor2 > -1) {
            cursor2--;
        }
    }

    @Override
    public boolean isFirst() {
        return (cursor2 == -1);
    }

    @Override
    public Object getNextItem() {
        return products.get(cursor1);
    }

    @Override
    public Object getPreviousItem() {
        return products.get(cursor2);
    }
}

 客户端类

package step1;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        List products = new ArrayList<String>();
        Scanner scanner = new Scanner(System.in);
        int nums = scanner.nextInt();
        for (int i = 0; i < nums; i++) {
            products.add(scanner.next());
        }
        /********** Begin *********/
        ///请用java自带的iterator实现products的正向遍历访问

       Iterator<String> iterator = products.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }


        /********** End *********/
        System.out.println("--------------------");

        /********** Begin *********/
        ///请用自定义的iterator实现products的反向遍历访问
         AbstractInterator iterator1 = new ProductIterator(new ProductList(products));
        while (!iterator1.isFirst()) {
            System.out.println(iterator1.getPreviousItem());
            iterator1.previous();
        }



        /********** End *********/
    }
}

四、备忘录模式实验

窄接口

package step1;

public interface Memento {
}

 发起人(Originator)角色

package step1;

public class Originator {
    private  String mould;

    public void  ReadMould()
    {
        //假设从数据库中读取模板代码
        this.mould = "this is ______code";
    }
    ///setMould是学生修改以后提交的代码
    public void setMould( String code)
    {
        this.mould= code;
    }
    public String getMould()
    {
        return mould;
    }
    private static class MementoImpl implements Memento
    {
        /********** Begin *********/
        private String mould;
        public MementoImpl(String mould) {
            this.mould = mould;
        }

        public String getMould(){
            return mould;
        }

        public void setMemento(String mould) {
            this.mould = mould;
        }

       
        /********** End *********/
    }
    public Memento createMemento() {
        /********** Begin *********/
         return new MementoImpl(mould);
        /********** End *********/
    }
    public void restoreMemento(Memento memento)
    {
        /********** Begin *********/
        MementoImpl roleStateMemento = (MementoImpl) memento;
        this.mould = roleStateMemento.getMould();
        /********** End *********/
    }
}

管理者角色 

package step1;

public class Caretaker {
    private Memento memento = null;

    public void setMemento(Memento memento){
        this.memento = memento;
    }
    public Memento getMemento(){
        return this.memento;
    }

}

客户端类

package step1;

import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        // 创建原始对象和备忘录管理者对象
        Originator originator=new Originator();
        Caretaker caretaker=new Caretaker();
        
        // 从文件中读取原始代码框架
        originator.ReadMould();
        
        // 打印显示原始代码框架
        System.out.println(originator.getMould());
        
        // 创建备份
        caretaker.setMemento(originator.createMemento());
        
        // 模拟学生提交最终代码
        Scanner scanner = new Scanner(System.in);
        String mycode = scanner.nextLine();
        originator.setMould(mycode);
        
        // 打印显示修改后的代码框架
        System.out.println(originator.getMould());
        
        // 恢复备份并显示
        originator.restoreMemento(caretaker.getMemento());
        System.out.println(originator.getMould());
    }
}

 

举报

相关推荐

0 条评论