历览千载书,时时见遗烈。这篇文章主要讲述未更新完毕相关的知识,希望能为你提供帮助。
行为型模式
1、行为模式关注点"怎样运行对象/类",所以我们关注类/对象的运行时流程控制。
2、行为模式用于描述程序在运行时复杂的流程控制,描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间的职责分配。
3、行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分配行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度更低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。
文章图片
模板方法模式:父类定义算法骨架,某些实现放子类
策略模式:每种算法独立封装,根据不同情况使用不同算法策略
状态模式:每种状态独立封装,不同状态内部封装了不同行为
命令模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开
责任链模式:所有处理者封装为链式结构,依次调用
备忘录模式:把核心信息抽取出来,可以进行保存
解释器模式:定义语法解析规则
观察者模式:维护多个观察者依赖,状态变化通知所有观察者
中介者模式:取消类/对象的直接调用关系,使用中介者维护
迭代器模式:定义集合数据的遍历规则
访问者模式:分离对象结构与元素的执行算法
【未更新完毕】除了模板方法模式和解释器模式是类行为模式,其他的全部属于对象行为模式
模板方法模式
在模板方法模式中,一个抽象类公开定义了执行它的方法的方式模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
模板方法包含两个角色:
抽象类/抽象模板
具体子类/具体实现
例子
做饭都要经历加热,添加食材,添加调料,翻炒,出锅,这是一个模板,有方法是固定的不需要改变的,如加热,翻炒,出锅,这些就可以定义到模板里,加什么食材,加什么调料,这些是不一定的,可以随时改变,就在子类中实现。
package com.example.design.template;
/**
* 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("出锅。。。。。。。");
package com.example.design.template;
public class AutoCookMachine extends CookTemplate
@Override
public void addfood()
System.out.println("加三个小白菜。。。。。。");
@Override
public void addsalt()
System.out.println("放三勺盐。。。。。。。");
package com.example.design.template;
public class MainTest
public static void main(String[] args)
AutoCookMachine autoCookMachine = new AutoCookMachine();
autoCookMachine.cook();
输出:
开火。。。。。。。。
加三个小白菜。。。。。。
放三勺盐。。。。。。。
翻炒中。。。。。。
出锅。。。。。。。
Disconnected from the target VM, address: 127.0.0.1:50875, transport: socket
Process finished with exit code 0
策略模式
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户,属于对象行为模式
策略模式的主要角色如下
抽象策略类:公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现
具体策略类:实现了抽象策略定义的接口,提供具体的算法实现
环境类:持有一个策略类的引用,最终给客户端调用
文章图片
例子
1、从北京到上海,有很多种策略到达,火车、飞机、高铁等等,每一种策略都可以达到相同的效果或目的。选择策略的依据是费用,时间,使用工具还有每种方式的方便程度。
2、打一局和平精英最终胜利路,策略有很多种,例如:稳健运营策略、冲锋向前策略。结果都是胜利。以此为实例如下
package com.example.design.strategy;
/**
* 环境类
*/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("win......");
package com.example.design.strategy;
/**
* 游戏策略
*/
public interface GameStrategy
//战斗策略
void warStrategy();
package com.example.design.strategy;
/**
* 稳健运营策略
*/
public class SteadyStrategy implements GameStrategy@Override
public void warStrategy()
System.out.println("各路小心。。。。及时支援。。。");
package com.example.design.strategy;
/**
* 冲锋向前策略
*/
public class UziStrategy implements GameStrategy
@Override
public void warStrategy()
System.out.println("所有人向前冲");
package com.example.design.strategy;
public class MainTest
public static void main(String[] args)
TeamGNR teamGNR = new TeamGNR();
teamGNR.setGameStrategy(new UziStrategy());
teamGNR.startGame();
System.out.println("==================a");
teamGNR.setGameStrategy(new SteadyStrategy());
teamGNR.startGame();
游戏开始......
所有人向前冲
win......
==================
游戏开始......
各路小心。。。。及时支援。。。
win......
Disconnected from the target VM, address: 127.0.0.1:51147, transport: socket
状态模式
状态模式:对有状态的对象,把复杂的判断逻辑提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式包含以下主要角色
环境类角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换
抽象状态角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为
具体状态角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换
例子
一个人有吃牛肉面状态,休假状态,打游戏状态,需要用一个抽象类把状态抽象为同一类行为,然后在使用不同的子类实现。环境类调用抽象类的状态方法,并且拥有流转状态的方法。
此时一个人就可以在牛肉面状态,休假状态,打游戏状态这三个状态之间任意切换了。
文章图片
package com.example.design.state;
/**
* 抽象状态
*/
public interface TeamState
//玩游戏
void playGame();
//切换到下一个状态
//状态的流转是状态模式的核心
TeamState next();
package com.example.design.state;
/**
* 吃牛肉面状态
*/
public class BeafNodleState implements TeamState
@Override
public void playGame()
System.out.println("牛肉面真好吃。。。。。。");
@Override
public TeamState next()
return new MatchState();
package com.example.design.state;
/**
* 竞赛状态
*/
public class MatchState implements TeamState
@Override
public void playGame()
System.out.println("全力以赴打比赛。。。。。。");
@Override
public TeamState next()
return new VocationState();
package com.example.design.state;
/**
* 休假状态
*/
public class VocationState implements TeamState
@Override
public void playGame()
System.out.println("三亚旅游真舒服。。。饿了。。。不玩游戏");
//状态流转@Override
public TeamState next()
return new BeafNodleState();
package com.example.design.state;
/**
* 环境类
*/
public class SKTTeam private TeamState teamState;
public void setTeamState(TeamState teamState)
this.teamState = teamState;
//开始游戏
public void startGame()
//状态不同会导致不同的游戏结果
teamState.playGame();
//状态的流转
void nextState()
teamState=teamState.next();
package com.example.design.state;
public class MainTest public static void main(String[] args)
SKTTeam sktTeam = new SKTTeam();
VocationState vocationState = new VocationState();
sktTeam.setTeamState(vocationState);
sktTeam.startGame();
sktTeam.nextState();
sktTeam.startGame();
sktTeam.nextState();
sktTeam.startGame();
System.out.println("===============");
中介者模式
中介者模式:用一个中介对象来封装一系列的对象交互,中介者使各个对象不需要显式的相互引用,减少对象间混乱的依赖关系,从而使其耦合松散,而且可以独立的改变他们之间的交互,对象行为型模式
中介者模式的角色
抽象中介者
具体中介者
抽象同事类
具体同事类
文章图片
例子
飞机的起飞和降落如果没有中介者,如下图,每个飞机每次起飞和降落都需要连接其他所有飞机的机长,了解跑道和空域的占用情况来确认能不能起飞或者降落,这样及其麻烦。
有了塔台就不一样了,每个飞机起飞或者降落的时候都把信号发给塔台,塔台统计总体的情况,其他飞机起飞或降落,直接向塔台获取信息即可。中介者模式,得到了很好的解耦。
文章图片
文章图片
package com.example.design.mediator;
/**
* 抽象机长
*/
public abstract class Captain
//起飞
abstract void fly();
//降落
abstract void land();
//完成
abstract void success();
package com.example.design.mediator;
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("HU8778完成动作。。。。。。");
controlTower.acceptRequest(this,"success");
package com.example.design.mediator;
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,"success");
package com.example.design.mediator;
public class XC9527 extends Captain
//要保证所有的机长都对应同一个塔台
ControlTower controlTower;
public void setControlTower(ControlTower controlTower)
this.controlTower = controlTower;
@Override
void fly()
System.out.println("XC9527请求起飞。。。。。。");
controlTower.acceptRequest(this,"fly");
@Override
void land()
System.out.println("XC9527请求降落。。。。。。");
controlTower.acceptRequest(this,"land");
@Override
void success()
System.out.println("XC9527完成动作。。。。。。");
controlTower.acceptRequest(this,"success");
package com.example.design.mediator;
/**
* 塔台:中介者
*/
public class ControlTower
private boolean canDo = true;
//接受请求
public void acceptRequest(Captain captain,String action)
//
if("fly".equals(action) || "land".equals(action))
if(canDo)
System.out.println("允许......");
canDo=false;
else
System.out.println("不允许......");
if("success".equals(action))
canDo=true;
package com.example.design.mediator;
public class MainTest
public static void main(String[] args)
HU8778 hu8778 = new HU8778();
SC8633 sc8633 = new SC8633();
ControlTower controlTower = new ControlTower();
hu8778.setControlTower(controlTower);
sc8633.setControlTower(controlTower);
hu8778.fly();
//加hu8778.success();
代表完成,其他飞机可以执行任务
// hu8778.success();
sc8633.fly();
观察者模式
观察者模式:定义对象的一种一对多的依赖关系,使得每当一个对象的状态发生改变时,其关系依赖对象皆得到通知,并被自动更新。观察者模式又叫做发布-订阅模式,模型-视图模式,源-监听器模式,或从属者模式。
观察者模式的角色
目标
具体目标
观察者
具体观察者
文章图片
例子
抖音主播直播,把消息发给粉丝,粉丝就是主播的观察者
package com.example.design.observer;
/**
* 抖音主播
* 粉丝观察主播
*/
public abstract class AbstractTikToker
//添加粉丝
abstract void addFans(AbstractFans abstractFans);
//通知粉丝
abstract void notifyFans(String msg);
package com.example.design.observer;
import java.util.ArrayList;
import java.util.List;
public class MMTikToker extends AbstractTikToker
//观察者的核心
List<
AbstractFans>
fansList=new ArrayList<
>
();
void startSell()
System.out.println("雷丰阳。。。。。。开始卖货。。。。。源码设计");
notifyFans("我开始卖东西了,是源码设计,只要666");
void endSell()
System.out.println("雷丰阳。。。结束卖货。。。源码设计课lllll");
notifyFans("雷丰阳。。。结束卖货。。。源码设计课");
@Override
void addFans(AbstractFans abstractFans)
fansList.add(abstractFans);
//观察者
@Override
void notifyFans(String msg)
for (AbstractFans fans : fansList)
//1、所有粉丝都拿来通知
fans.acceptMsg(msg);
package com.example.design.observer;
public class HumanFans extends AbstractFans
@Override
void acceptMsg(String mag)
System.out.println("主播说::"+mag);
package com.example.design.observer;
public class RobotFans extends AbstractFans
@Override
void acceptMsg(String mag)
System.out.println("呸。。。。");
package com.example.design.observer;
/**
* 抽象观察者
*/
public abstract class AbstractFans
abstract voidacceptMsg(String mag);
void follow(AbstractTikToker tikToker)
//主播增粉了
tikToker.addFans(this);
package com.example.design.observer;
public class MainTest
public static void main(String[] args)
MMTikToker mmTikToker = new MMTikToker();
mmTikToker.startSell();
RobotFans robotFans1 = new RobotFans();
RobotFans robotFans2 = new RobotFans();
RobotFans robotFans3 = new RobotFans();
robotFans1.follow(mmTikToker);
robotFans2.follow(mmTikToker);
robotFans3.follow(mmTikToker);
HumanFans humanFans = new HumanFans();
humanFans.follow(mmTikToker);
System.out.println("=============>
");
mmTikToker.endSell();
备忘录模式
备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又称快债模式。
角色
发起人角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息
备忘录角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
管理者角色:对备忘录进行管理,提供保存于获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
文章图片
package com.example.design.memento;
import lombok.Data;
@Data
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+"\\t"+"level"+level);
package com.example.design.memento;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* 游戏服务器
* 管理者
*/
public class GameServer
//管理备忘录信息
Map<
Integer,GameRecord>
recordMap=new HashMap<
>
();
int i=1;
void add(GameRecord gameRecord)
gameRecord.setId(i++);
recordMap.put(gameRecord.id,gameRecord);
LeiGamer getRecord(Integer id) throws InvocationTargetException, IllegalAccessException
GameRecord gameRecord = recordMap.get(id);
//获取到备忘录里面的东西以后还要逆转
LeiGamer leiGamer = new LeiGamer();
//用工具类属性对拷
BeanUtils.copyProperties(leiGamer,gameRecord);
return leiGamer;
package com.example.design.memento;
import lombok.Data;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.Random;
/**
* 游戏者:游戏发起人
* 当前游戏信息
*/
@Data
public class LeiGamer
Integer coin;
//剩余金币
Integer hp;
//血量
Integer mp;
//蓝量
Integer level;
//等级
//以上是内部状态,我们需要记录保存的信息GameServer gameServer =new GameServer();
//保存游戏记录
void saveGameRecord() throws InvocationTargetException, IllegalAccessException
System.out.println("正在保存当前记录。。。。。。");
GameRecord gameRecord=new GameRecord();
//当前游戏信息保存到备忘录
BeanUtils.copyProperties(gameRecord,this);
gameServer.add(gameRecord);
//从备忘录获取游戏的历史存档
LeiGamer getFromMemento(Integer id) throws InvocationTargetException, IllegalAccessException
System.out.println("获取历史存档信息。。。。。。");
LeiGamer 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 InvocationTargetException, IllegalAccessException
System.out.println("退出&
存档");
saveGameRecord();
package com.example.design.memento;
import java.lang.reflect.InvocationTargetException;
/**
* 备忘录的关键点:
* 1、备忘录的设计(提取属性)
* 2、备忘录对象和原对象的互转操作
*序列化
*保存数据库
*/
public class MainTest
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException
LeiGamer leiGamer = new LeiGamer();
leiGamer.playGame();
leiGamer.saveGameRecord();
leiGamer.playGame();
leiGamer.playGame();
leiGamer.saveGameRecord();
LeiGamer fromMemento = leiGamer.getFromMemento(1);
fromMemento.playGame();
推荐阅读
- [Python公开课]零基础玩转Python进阶篇----第二节(Python的异常分析及解决)
- crontab的环境变量配置
- 实施遇到Ubuntu系统问题
- 漫画趣解Flink实时数仓
- #私藏项目实操分享#现代企业信息化综合运维管理实例
- 自动化快速部署OpenStack Train版控制节点
- 2021前端校招直通车,实现Offer零距离
- 全网稀缺的DDD(领域驱动设计)思想解读及落地指南
- 笨叔(用4维空间来理解进程负载)