• 学点设计模式,盘点Spring等源码中与设计模式的那些事之行为型模型


    学点设计模式,盘点Spring等源码中与设计模式的那些事之行为型模型

    • 行为型模型更多的关注怎样将一个类或者对象运行起来,关注他们的运行时流程控制。
    • 行为型模型包括:模板方法(Template Method)模式、策略(Strategy)模式、状态(State)模式,命令(Command)模式、职责链(Chain of Responsibility)模式、备忘录(Memento)模式、解释器(Interpreter)模式、观察者(Observer)模式、中介者(Mediator)模式、迭代器(Iterator)模式和访问者(Visitor)模式。

    1、模板方法模式

    • 定义:一个抽象类公开定义了执行它的方法的方式模板,简单说就是它定义好了算法的步骤,具体细节你来实现。
    • 比如现在定义一个做饭的机器,它已经定义好了做饭的步骤先干啥再干啥,然后由我们实现里边的一些细节,比如加入什么食物,放多少调料等,这个做饭机就会按照步骤开始做饭。
      在这里插入图片描述
    • 代码示例
    //定义抽象模板
    public abstract class CookTemplate {
        /**
         * 定义算法:定义好了模板
         * 父类可以实现某些步骤
         * 留关键给子类
         */
        public void cook(){
            //定义算法步骤
            heating(); 
            addfood();
            addsalt();
            stirfry(); 
            end(); 
        }
        //加热方法
        public void heating(){
            System.out.println("开火...");
        };
        //添加食物
        public abstract void addfood();
        //加盐
        public abstract void addsalt();
        //翻炒
        public  void stirfry(){
            System.out.println("翻炒中...");
        };
        //出锅
        public  void end(){
            System.out.println("出锅....");
        };
    }
    
    //关键细节,放什么菜和调料
    public class AutoCookMachine extends CookTemplate{
        @Override
        public void addfood() {
            System.out.println("放了三个小白菜");
        }
        @Override
        public void addsalt() {
            System.out.println("放了三勺盐");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    2、策略模式

    • 定义:比如现在有一系列的算法,我们将每个算法封装起来,想要用哪个就传哪个,使他们之间可以相互替换且不影响使用。
    • 比如现在有一款游戏,我们可以选择不同的策略进行,比如我们想要各自猥琐发育,还是主动发起攻击,或者其他许多的策略,我们将这些策略提取出来,想要使用哪个就调用哪个。
      在这里插入图片描述
    • 代码示例
    //游戏的环境类
    public class TeamGNR {
        //抽取游戏策略算法,并进行引用
        private GameStrategy gameStrategy;
    
        public void setGameStrategy(GameStrategy gameStrategy) {
            this.gameStrategy = gameStrategy;
        }
    
        public void startGame(){
            System.out.println("游戏开始.....");
            //游戏策略
            gameStrategy.warStrategy();
            System.out.println("游戏结束......");
        }
    }
    //抽象的策略
    public interface GameStrategy {
        //战斗策略
        void warStrategy();
    }
    //实现自己的策略,可以扩展多个
    public class SteadyStrategy implements GameStrategy {
        @Override
        public void warStrategy() {
            System.out.println("猥琐发育...别浪...");
        }
    }
    
    public class UziStrategy implements GameStrategy{
        @Override
        public void warStrategy() {
            System.out.println("发起进攻.....");
        }
    }
    //Test
    public static void main(String[] args) {
            TeamGNR gnr = new TeamGNR();
    		//想要使用哪个策略就传哪个
            gnr.setGameStrategy(new RandomStrategy());
            gnr.startGame();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3、状态模式

    • 定义:状态模式和策略模式的类图基本相同,不同的是关注点,策略关注于多个算法,每个算法产生不同的方式,而状态模式关注于多种状态,状态不同,产生的效果不同。
    • 状态模式的关键在于状态的流转,比如还是刚才的打游戏例子,我在又饿又累的状态下,打游戏可能就输了,然后我现在吃饱睡好了,就能打赢了。
      在这里插入图片描述
    • 代码举例
    //环境类
    public class SKTTeam {
        private TeamState teamState;
    
        public void setTeamState(TeamState teamState) {
            this.teamState = teamState;
        }
    
        //开始游戏
        public void startGame(){
            //状态不同会导致不同的游戏结果
            teamState.playGame();
        }
        //下一个状态
        void nextState(){
            teamState = teamState.next();
        }
    }
    //抽象状态
    public interface TeamState {
        //玩游戏
        void playGame();
        //切换到下一个状态
        TeamState next();
    }
    //休息状态
    public class VocationState implements TeamState {
        @Override
        public void playGame() {
            System.out.println("休假状态...不想玩游戏");
            //状态流转
        }
    
        @Override
        public TeamState next() {
            return new HungerState();
        }
    }
    //饥饿状态
    public class HungerState implements TeamState {
    
        @Override
        public void playGame() {
            System.out.println("肚子饿了...,游戏输了");
        }
    
        @Override
        public TeamState next() {
            return new MatchState();
        }
    }
    //吃饱喝足好好打
    public class MatchState implements TeamState{
        @Override
        public void playGame() {
            System.out.println("吃饱喝足...全力以赴打比赛....");
        }
    
        //状态模式的核心
        @Override
        public TeamState next() {
            return new VocationState();
        }
    }
    //Test
    public static void main(String[] args) {
    
            SKTTeam sktTeam = new SKTTeam();
            TeamState state = new VocationState();
            sktTeam.setTeamState(state);
            sktTeam.startGame();
    
            state = state.next();
            sktTeam.setTeamState(state);
            sktTeam.startGame();
            
            state = state.next();
            sktTeam.setTeamState(state);
            sktTeam.startGame();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    4、中介者模式

    • 定义:可以将网状的复杂交互关系,利用一个中间者,转变成星状的交互关系,中介者使各对象不需要显式地相互引用,减少对象间混乱的依赖关系,从而使其耦合松散
    • 比如飞机场有许多的飞机,每个飞机降落前都需要询问是否可以降落,总不能让所有的飞机驾驶员之间交流谁先降吧,这时就有一个中间的塔台,大家都问它。
      在这里插入图片描述
    • 代码示例
    //中介者,塔台
    public class ControlTower {
    
        private boolean canDo = true;
    
        //接受请求...
        public void acceptRequest(Captain captain,String action){
            if("fly".equals(action)||"land".equals(action)){
                //
                if(canDo == true){
                    System.out.println("允许......");
                    canDo = false;
                }else {
                    System.out.println("不允许.....");
                }
            }
            if("success".equals(action)){
                canDo = true;
            }
        }
    }
    //抽象的机长
    public abstract class Captain {
        //起飞
        abstract void fly();
        //降落
        abstract void land();
        //完成
        abstract void success();
    }
    //来几个飞机
    public class HU8778 extends Captain{
        ControlTower controlTower;
    
        public void setControlTower(ControlTower controlTower) {
            this.controlTower = controlTower;
        }
        @Override
        void fly() {
            System.out.println("HU8778请求起飞......");
            //问每个机长能否起飞?
            controlTower.acceptRequest(this,"fly");
        }
        @Override
        void land() {
            System.out.println("HU8778请求降落......");
            controlTower.acceptRequest(this,"land");
        }
        @Override
        void success() {
            System.out.println("完成......");
            controlTower.acceptRequest(this,"success");
        }
    }
    //
    public class SC8633 extends Captain{
        ControlTower controlTower ;
    
        public void setControlTower(ControlTower controlTower) {
            this.controlTower = controlTower;
        }
        @Override
        void fly() {
            System.out.println("SC8633 请求起飞......");
            //问每个机长能否起飞?
            controlTower.acceptRequest(this,"fly");
        }
        @Override
        void land() {
            System.out.println("SC8633 请求降落......");
            //问每个机长能否起飞?
            controlTower.acceptRequest(this,";land");
        }
        @Override
        void success() {
            System.out.println("SC8633 完成......");
            //问每个机长能否起飞?
            controlTower.acceptRequest(this,"fly");
        }
    }
    //Test......
    public static void main(String[] args) {
            HU8778 hu8778 = new HU8778();
            SC8633 sc8633 = new SC8633();
    
            ControlTower tower = new ControlTower();
            hu8778.setControlTower(tower);
            sc8633.setControlTower(tower);
    
            hu8778.fly();
            hu8778.success();
            sc8633.fly();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    5、观察者模式

    • 定义:定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
    • 举个栗子:比如我们现在非常流行的直播,一个主播有很多的粉丝,当主播发布一条短视频或者要直播时,希望可以主动通知每一位粉丝,而不用粉丝自己查看。
      在这里插入图片描述
      代码示例
    //抽象的主播
    public abstract class AbstractTikToker {
        //添加粉丝
        abstract void addFans(AbstractFans fans);
        //通知粉丝
        abstract void notifyFans(String msg);
    }
    
    //抽象观察者、粉丝
    public abstract class AbstractFans {
    
        abstract void acceptMsg(String msg);
    
        void follow(AbstractTikToker tikToker){
            //主播增粉了
            tikToker.addFans(this);
        };
    }
    
    //真实粉丝
    public class HumanFans extends AbstractFans {
        @Override
        void acceptMsg(String msg) {
            System.out.println(msg);
        }
    }
    
    //机器人
    public class RobotFans extends AbstractFans {
        @Override
        void acceptMsg(String msg) {
            System.out.println("这是机器人粉丝");
        }
    }
    
    //主播直播啦
    public class MMTikToker  extends AbstractTikToker{
    
        //1、观察者的核心,维护一个列表
        List<AbstractFans> fansList = new ArrayList<>();
    
        void start() {
            notifyFans("主播上线快来围观吧!!!!!!!");
        }
        void end() {
            notifyFans("本次直播到这里就结束啦!!!!");
        }
    
        @Override
        void addFans(AbstractFans fans) {
            fansList.add(fans);
        }
        @Override
        void notifyFans(String msg) {
            //1、所有粉丝拿来通知
            for (AbstractFans fans : fansList) {
                fans.acceptMsg(msg);
            }
        }
    }
    
    //Test
    public static void main(String[] args) {
    
            MMTikToker toker = new MMTikToker();
    
            RobotFans fans1 = new RobotFans();
            fans1.follow(toker);
    
            HumanFans humanFans = new HumanFans();
            humanFans.follow(toker);
    
            toker.start();
            toker.end();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    6、备忘录模式

    • 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,当以后需要时能将该对象恢复到原先保存的状态,就相当于序列化与反序列化的过程。
      在这里插入图片描述
    • 举个栗子:玩游戏时,对游戏的状态进行存档
    //当前游戏信息
    public class Gamer {
        Integer coin;//剩余金币
        Integer hp;//血量
        Integer mp;//蓝量
        Integer level;//等级
        //以上的是内部状态,我们需要记录保存的信息
    
        GameServer gameServer = new GameServer();
    
        //保存游戏记录
        void saveGameRecord() throws Exception {
            System.out.println("正在保存当前记录....");
            GameRecord gameRecord = new GameRecord();
            //当前游戏信息保存到备忘录
            BeanUtils.copyProperties(gameRecord,this);
            gameServer.add(gameRecord);
        }
    
        //从备忘录获取游戏历史存档
        Gamer getFromMemento(Integer id) throws Exception {
            System.out.println("获取历史存档信息....");
            Gamer record = gameServer.getRecord(id);
            return record;
        }
    
        //玩游戏
        void playGame(){
            int i = new Random().nextInt();
            System.out.println("......(〃'▽'〃)......"+i);
    
            coin = i;
            hp = i;
            mp = i;
            level = i;
        }
    
        //退出游戏
        void exitGame() throws Exception {
            System.out.println("退出&存档");
            saveGameRecord();
        }
    }
    //备忘录
    public class GameRecord {
        Integer id; //代表生成记录的id
        Integer coin;//剩余金币
        Integer hp;//血量
        Integer mp;//蓝量
        Integer level;//等级
    
        //获取当前备忘录信息
        void getCurrent(){
            System.out.println("coin:"+coin+";\t"+"hp:"+hp+";\t mp:"+mp);
        }
    }
    
    //游戏服务器
    public class GameServer {
    
        //管理备忘录信息的
        Map<Integer,GameRecord> records = new HashMap<>();
        int i = 1;
    
        void add(GameRecord gameRecord){
            gameRecord.setId(i++);
            records.put(gameRecord.id,gameRecord);
        }
    
        Gamer getRecord(Integer id) throws Exception {
            GameRecord gameRecord = records.get(id);
            //获取到备忘录里面的内容以后还要逆转
            Gamer gamer = new Gamer();
            //BeanUtils:工具类,属性对拷,记得加依赖
            BeanUtils.copyProperties(gamer,gameRecord);
            return gamer;
        }
    }
    //Test
    public static void main(String[] args) throws Exception {
            Gamer gamer = new Gamer();
            gamer.playGame();
            //保存
            gamer.saveGameRecord();
            Gamer fromMemento = gamer.getFromMemento(1);
            fromMemento.playGame();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    7、解释器模式

    • 定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子
    • 定义听起来比较晦涩,举个栗子:现在有一个景区,我们进门的时候要刷身份证,景区系统对一些特殊人员给予免票政策,比如本地人不需要买票,老人、儿童不需要买票,医生不需要买票等。当人们进门时刷省份证,会给系统传入一个字符串,系统解析判断这个人需不需要买票。
      在这里插入图片描述
    • 代码实现
    //景区
    public class Area {
        Set<String> city = new HashSet<>();
        Set<String> type = new HashSet<>();
        IDCardExpression idCardReader;//读卡器,表达式解析器
    
        public Area(){
            //免费人群
            city.add("武汉市");
            city.add("上海市");
            type.add("医生");
            type.add("老人");
            type.add("儿童");
            //最小解析
            TerminalExpression city =
                    new TerminalExpression(this.city, ":");
            TerminalExpression type =
                    new TerminalExpression(this.type, "-");
            //以上满足一个即可
            idCardReader = new OrExpression(city,type);
        }
    
        //传入表达式,判断当前表达式是否指定为免费人群
        void getTicket(String expression){
            boolean interpret = idCardReader.interpret(expression);
            if(interpret){
                System.out.println("恭喜你,免票通过....");
            }else {
                System.out.println("对不起,请2元购票....");
            }
        }
    }
    
    //抽象表达式的解析
    public abstract class IDCardExpression {
        //定义解析逻辑:城市:姓名-职业
        abstract boolean interpret(String expression);
    }
    
    //终结符表达式,多少种解析规则就需要定义多少种规则类
    public class TerminalExpression extends IDCardExpression {
    
        IDCardExpression childExp;
        Set<String> data;  //免费数据
        String symbol; //定义解析用的符号
    
        public TerminalExpression( Set<String>  data,String symbol){
            this.data = data;
            this.symbol = symbol;
        }
    
        @Override
        boolean interpret(String expression) {
    
            //按照指定符号分割
            String[] split = expression.split(symbol);
            boolean result = false;
            for (String s : split) {
                if(data.contains(s)){
                    return true;
                };//说明是免费的信息里面的
            }
            //不在免费行列
            return false;
        }
    }
    
    //非终结表达式
    public class OrExpression extends IDCardExpression {
    
        //组合两个终结表达式。最终的判断结果是终结表达式判断出来的,这个表达式只是一个桥梁
        private IDCardExpression cityExp;
        private IDCardExpression typeExp;
    
        public OrExpression(IDCardExpression cityExp, IDCardExpression typeExp) {
            this.cityExp = cityExp;
            this.typeExp = typeExp;
        }
    
        @Override
        boolean interpret(String expression) {
            //定义所有终结表达式的合并逻辑,符合一个即符合
            return cityExp.interpret(expression) || typeExp.interpret(expression);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    8、命令模式

    • 定义:将请求封装成一个对象,使发请求和执行请求分隔开,方便命令的存储、传递和调用。比如我们电视机的遥控器,每按一个按钮就是一条请求。
      在这里插入图片描述
    • 举例:使用遥控器换台、调大声音
    //抽象命令类
    public interface Command {
        void execute();
    }
    
    //具体命令
    public class ChangeShow implements Command{
    
        //Dao
        private Receiver receiver = new Receiver();
        @Override
        public void execute() {
            System.out.println("换台......");
            receiver.changeTV();
        }
    }
    
    //具体命令
    public class VoiceUp implements Command{
    
        private Receiver receiver = new Receiver();
    
        @Override
        public void execute() {
            System.out.println("调大声音....");
            receiver.voiceUp();
        }
    }
    
    //接受者、电视机
    public class Receiver {
        public void changeTV(){
            System.out.println("换台了......");
        }
        public void voiceUp(){
            System.out.println("声音开大了.....");
        }
    }
    
    //命令调用者(发起者)
    public class Invoker {
        Command command;
    
        public void call(){
            //命令
            command.execute();
        }
        public void setCommand(Command command) {
            this.command = command;
        }
    }
    //Test
    public static void main(String[] args) {
            Invoker invoker = new Invoker();
            invoker.setCommand(new VoiceUp());
            invoker.call();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    9、迭代器模式

    • 定义:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
    • 在遍历一个聚合对象时,定义一个迭代器,支持以不同的方式遍历一个聚合对象,分离数据和遍历职责。
      在这里插入图片描述
    • 实现示例:
    //抽象容器
    public interface Container {
        public Iterator getIterator();
    }
    
    //抽象迭代器
    public interface Iterator {
        public boolean hasNext();
        public Object next();
    }
    
    //具体容器
    public class NameRepository implements Container {
        public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};
    
        @Override
        public Iterator getIterator() {
            return new NameIterator();
        }
    
        private class NameIterator implements Iterator {
    
            int index;
    
            @Override
            public boolean hasNext() {
                if(index < names.length){
                    return true;
                }
                return false;
            }
    
            @Override
            public Object next() {
                if(this.hasNext()){
                    return names[index++];
                }
                return null;
            }
        }
    }
    
    //遍历打印
    public class IteratorPatternDemo {
        public static void main(String[] args) {
    
            NameRepository namesRepository = new NameRepository();
    
            for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
                String name = (String)iter.next();
                System.out.println("Name : " + name);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    10、访问者模式

    • 定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。
    • 访问者模式是行为型类模式,主要目的是:让数据结构与数据操作分离。
    • 举个栗子:比如最开始的小爱同学,它只能回答固定的问题,而且不能联网。现在的我们想要让它更加智能,让它可以联网,数据可以存储在网上,回答更多的问题。那么我们总不能把它拆了重新造吧,这时就可以使用访问者模式,在小爱同学的硬件上预留扩展升级接口,我们向它发送升级包来进行升级。
      在这里插入图片描述
    • 代码实现
    //硬件,抽象元素类
    public  abstract class Hardware {
        String command;//封装硬件的处理指令
    
        public Hardware(String command){
            this.command = command;
        }
        //收到命令以后进行工作
        abstract public void work();
        //定义接受软件升级包的方法。这个方法应该具体硬件去实现
         abstract public void accept(Vistor vistor);
    }
    
    //其中的一种硬件
    public class CPU extends Hardware{
        public CPU(String command) {
            super(command);
        }
        @Override
        public void work() {
            System.out.println("CPU处理指令:"+command);
        }
        @Override
        public void accept(Vistor vistor) {
            //给升级包提供一个改CPU指令等信息的办法
            vistor.visitCPU(this);
        }
    }
    
    //其中的另一种硬件
    public class Disk extends Hardware{
        public Disk(String command) {
            super(command);
        }
    
        @Override
        public void work() {
            System.out.println("Disk保存指令的历史记录:"+command);
        }
        @Override
        public void accept(Vistor vistor) {
            vistor.visitDisk(this);
        }
    }
    
    //小爱机器人
    public class XiaoAi {
    
        private CPU cpu = new CPU("今天天气怎么样?");
        private Disk disk = new Disk("今天天气怎么样?");
    
        void answerQuestion(){
            cpu.work();
            disk.work();
        }
    
        //接受升级包
        public void acceptUpdate(Vistor aPackage) {
            //升级CPU
            aPackage.visitCPU(cpu);
            aPackage.visitDisk(disk);
        }
    }
    
    //升级包的接口
    public interface Vistor {
        //访问者能访问元素。
        void visitDisk(Disk disk);
        void visitCPU(CPU cpu);
    }
    
    //真正的升级包,可以更改指令
    public class UpdatePackage implements Vistor{
    
        private String ext;
        public  UpdatePackage(String ext){
            this.ext = ext;
        }
        @Override
        public void visitDisk(Disk disk) {
            disk.command += " >>> "+ext;
        }
        @Override
        public void visitCPU(CPU cpu) {
            //改属性为例
            cpu.command += ">>>> "+ext;
        }
    }
    
    //Test
    public class MainTest {
    
        public static void main(String[] args) {
    
            XiaoAi xiaoAi = new XiaoAi();
            xiaoAi.answerQuestion();
    
            //升级。cpu联网处理指令
            //升级。disk保存到云存储
            UpdatePackage aPackage = new UpdatePackage("联网增强功能");
            xiaoAi.acceptUpdate(aPackage);
            //访问者
            xiaoAi.answerQuestion();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    11、责任链模式

    • 定义:将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。最常见的就是Web中的Filter(过滤器)。
    • 责任链3个关注点:链条的引用点、下一个责任者、构造链条。
      在这里插入图片描述
    • 场景举例:我们来模仿写一个简单版的回旋责任链过滤器,代码实现如下
    //抽象的Filter接口
    public interface Filter {
        void doFilter(Request request,Response response,FilterChain chain);
    }
    
    //第一个具体的Filter
    public class HttpFilter implements Filter{
        @Override
        public void doFilter(Request request, Response response, FilterChain chain) {
            //第一个filter的功能
            request.msg+=">>>";
            System.out.println("HttpFilter...doFilter之前");
            //放行
            chain.doFilter(request,response,chain);
            System.out.println("HttpFilter...doFilter之后");
        }
    }
    
    //第二个具体的Filter
    public class CharacterFilter implements Filter{
        @Override
        public void doFilter(Request request, Response response, FilterChain chain) {
            //功能
            request.msg +=" ====";
            System.out.println("CharacterFilter...doFilter之前");
            //放行
            chain.doFilter(request,response,chain);
            System.out.println("CharacterFilter...doFilter之后");
        }
    }
    
    //第三个具体的Filter
    public class EncodingFilter  implements Filter{
        @Override
        public void doFilter(Request request, Response response, FilterChain chain) {
            request.msg+=" oooo";
            System.out.println("EncodingFilter...doFilter之前");
            //放行
            chain.doFilter(request,response,chain);
            System.out.println("EncodingFilter...doFilter之后");
        }
    }
    
    //FilterChain,靠他维护链条
    public class FilterChain implements Filter {
    
        //记录当前执行的步骤游标
        int cursor = 0;
        //filter的链
        List<Filter> filtersChain = new ArrayList<>();
        //最终要执行的目标方法
        MyTarget target;
    
        public void setTarget(MyTarget target) {
            this.target = target;
        }
        public MyTarget getTarget() {
            return target;
        }
    
        //添加filter
        void addFilter(Filter filter){
            filtersChain.add(filter);
        }
    
        @Override
        public void doFilter(Request request, Response response, FilterChain chain) {
            //游标小于总数量filter一直往下获取执行
            if(cursor < filtersChain.size()){
                //第一次执行第一个filter,依次往下
                Filter filter = filtersChain.get(cursor);
                cursor++;
                //执行filter
                filter.doFilter(request,response,chain);
            }else {
                //filter完了,该执行目标方法了
                target.hello();
            }
        }
    }
    
    @Data
    //请求
    public class Request {
        String msg; //请求内容
        public Request(String msg){
            this.msg = msg;
        }
    }
    
    @Data
    //响应
    public class Response {
        String content;
        public Response(String content){
            this.content = content;
        }
    }
    
    public class MyTarget {
        void hello(){
            System.out.println("调用my.hello()");
        }
    }
    
    //Test
    public static void main(String[] args) {
            //先new一个FilterChain
            FilterChain chain = new FilterChain();
    
            //(模拟)从web.xml读取filter加入
            HttpFilter filter = new HttpFilter();
            CharacterFilter characterFilter = new CharacterFilter();
            EncodingFilter encodingFilter = new EncodingFilter();
            chain.addFilter(filter);
            chain.addFilter(characterFilter);
            chain.addFilter(encodingFilter);
            //目标方法
            chain.setTarget(new MyTarget());
            //filter链式执行。
            chain.doFilter(new Request("hello world"),
                    new Response("world,world"),chain);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    在这里插入图片描述
    代码有点长,耐不下心看可以复制到IDEA调试一下,上边完整代码可运行。


    呼~~,终于结束了,感觉这篇有点长了…

  • 相关阅读:
    MySQL添加、查看、修改与删除数据
    java通过zookeeper 高可用方式连接hiveserver2
    android studio 打包 jar aar
    【华为机试真题 JAVA】字符串加密-100
    java Spring Boot 手动启动热部署
    算法学习-单调双端队列
    更新npm淘宝镜像源
    使用VMware搭建OceanStor_eStor存储超详细教程
    Redisson分布式锁
    Spring面试题3:说一说MVC框架的底层实现
  • 原文地址:https://blog.csdn.net/NICK_53/article/details/127738490