首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,093 阅读
2
类的加载
744 阅读
3
Spring Cloud OAuth2.0
727 阅读
4
SpringBoot自动装配原理
693 阅读
5
集合不安全问题
589 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
Mybatis
Spring
html5
蘇阿細
累计撰写
391
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
页面
统计
关于
搜索到
391
篇与
的结果
2022-09-19
行为型模式-观察者模式
(1)概述观察者模式又称发布 - 订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态变化时,会通知所有的观察者对象,使它们能够自动更新自己(2)结构抽象主题(抽象被观察者):抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加/删除观察者对象具体主题(具体被观察者):该角色将有关状态存入具体观察者对象,在具体主题的内部发生改变时,给所有注册过的观察者发送通知抽象观察者:它定义了一个更新接口,使得在得到主题更改时通知更新自己具体观察者:实现抽象观察者定义的更新接口,以便在得到主题更改时通知更新自身的状态(3)案例以订阅公众号为例抽象主题角色public interface Subject { /** * 添加观察者对象(订阅者) * @param observer 观察者对象 */ void attach(Observer observer); /** * 删除观察者对象(订阅者) * @param observer 观察者对象 */ void detach(Observer observer); /** * 通志观察者(订阅者)更新消息 * @param message 消息 */ void notify(String message); }具体主题角色public class SubscriptionSubject implements Subject { private List<Observer> userList = new ArrayList<>(); @Override public void attach(Observer observer) { userList.add(observer); } @Override public void detach(Observer observer) { userList.remove(observer); } @Override public void notify(String message) { //通知所有订阅者 for (Observer observer : userList) { observer.update(message); } } }抽象观察者角色public interface Observer { /** * 更新 * @param message 消息 */ void update(String message); }具体观察者角色public class User implements Observer { private String name; public User(String name) { this.name = name; } @Override public void update(String message) { System.out.println(name + "接收到消息:" + message); } }Clientpublic class Client { public static void main(String[] args) { //创建公众号 SubscriptionSubject subject = new SubscriptionSubject(); //订阅公众号 subject.attach(new User("孙笑川")); subject.attach(new User("药水哥")); subject.attach(new User("刘波")); //公众号发布新的消息 subject.notify("带带大师兄"); } }(4)优缺点降低了被观察者与观察者之间的耦合被观察者发送消息,所有观察者都可以收到,可以实现广播机制观察者过多时,对系统性能会产生一定的影响如果被观察者有循环依赖,在发送消息时可能导致观察者循环调用(5)使用场景当对象存在一对多关系,一个对象的状态发生改变会影响其他的对象当一个抽象模型存在两个方面,其中一方面依赖于另一方面时
2022年09月19日
36 阅读
0 评论
0 点赞
2022-09-16
行为型模式-状态模式
(1)概述对有状态的对象,把复杂的“判断逻辑“提取到不同的状态对象中,允许其状态对象在其内部状态发生改变时改变其行为(2)结构环境角色:也称为上下文,它定义了客户程序需要的接口,维护一个当前状态并将与状态相关的操作委托给当前状态对象来处理抽象状态角色:定义接口用以封装环境对象中的特定状态所对应的行为具体状态角色:实现抽象状态所定义的行为(3)案例以乘坐电梯为例环境角色public class Context { /** * 对应状态对象的常量 */ public final static OpeningState OPENING_STATE = new OpeningState(); public final static ClosingState CLOSING_STATE = new ClosingState(); public final static RunningState RUNNING_STATE = new RunningState(); public final static StoppingState STOPPING_STATE = new StoppingState(); /** * 当前电梯状态变量 */ private LiftState liftState; public LiftState getLiftState() { return liftState; } public void setLiftState(LiftState liftState) { this.liftState = liftState; //设置当前状态对象中的Context对象 liftState.setContext(this); } public void open() { this.liftState.open(); } public void close() { this.liftState.close(); } public void run() { this.liftState.run(); } public void stop() { this.liftState.stop(); } }抽象状态角色public abstract class LiftState { //环境角色类变量 protected Context context; public void setContext(Context context) { this.context = context; } /** * 开门 */ public abstract void open(); /** * 关门 */ public abstract void close(); /** * 运行 */ public abstract void run(); /** * 停止 */ public abstract void stop(); }具体状态角色public class OpeningState extends LiftState { @Override public void open() { System.out.println("电梯门开了"); } @Override public void close() { //修改状态 super.context.setLiftState(Context.CLOSING_STATE); //调用当前状态中的Context中的close方法 super.context.close(); } @Override public void run() { } @Override public void stop() { } } public class RunningState extends LiftState { @Override public void open() { } @Override public void close() { } @Override public void run() { System.out.println("电梯正在运行"); } @Override public void stop() { super.context.setLiftState(Context.STOPPING_STATE); super.context.stop(); } } public class ClosingState extends LiftState { @Override public void open() { super.context.setLiftState(Context.OPENING_STATE); super.context.open(); } @Override public void close() { System.out.println("电梯门关了"); } @Override public void run() { super.context.setLiftState(Context.RUNNING_STATE); super.context.run(); } @Override public void stop() { super.context.setLiftState(Context.STOPPING_STATE); super.context.stop(); } } public class StoppingState extends LiftState { @Override public void open() { super.context.setLiftState(Context.OPENING_STATE); super.context.open(); } @Override public void close() { super.context.setLiftState(Context.CLOSING_STATE); super.context.close(); } @Override public void run() { super.context.setLiftState(Context.RUNNING_STATE); super.context.run(); } @Override public void stop() { System.out.println("电梯停了"); } }Clientpublic class Client { public static void main(String[] args) { //创建环境角色对象 Context context = new Context(); //设置当前电梯状态 context.setLiftState(new RunningState()); context.open(); context.close(); context.run(); context.stop(); } }(4)优缺点将所有与某个状态相关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块可能导致类和对象的个数增多结果与实现较为复杂,若果使用不当可能会导致结构与代码的混乱不符合开闭原则(5)使用场景当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变他的行为时一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时
2022年09月16日
23 阅读
0 评论
0 点赞
2022-09-16
行为型模式-责任链模式
(1)概述为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连城一条链;当有请求发生时,可将请求沿着这条链传递,只到有对象处理它为止(2)结构抽象处理者角色:定义处理请求的接口,包含抽象处理方法和一个后继链接具体处理者角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理则处理,否则将该请求转发给后继者客户类角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节及请求传递的过程(3)案例以请假为例抽象处理者角色public abstract class Handler { protected final static int ONE = 1; protected final static int THREE = 3; protected final static int SEVEN = 7; //不同角色可以处理的请假天数区间 private int startNum; private int endNum; //声明后继者(该案例中的上级领导) private Handler nextHandler; public Handler(int startNum) { this.startNum = startNum; } public Handler(int startNum, int endNum) { this.startNum = startNum; this.endNum = endNum; } /** * 设置上级领导对象 * * @param nextHandler */ public void setNextHandler(Handler nextHandler) { this.nextHandler = nextHandler; } /** * 各级领导处理请假条的方法 * * @param leave */ protected abstract void handlerLeave(LeaveRequest leave); /** * 提交请假申请 * * @param leave */ public final void submit(LeaveRequest leave) { //当前领导审批 this.handlerLeave(leave); //上级领导审批 if (this.nextHandler != null && leave.getNum() > this.endNum) { this.nextHandler.handlerLeave(leave); } else { System.out.println("流程结束"); } } }具体处理者角色public class GroupLeader extends Handler { public GroupLeader() { super(0, Handler.ONE); } @Override protected void handlerLeave(LeaveRequest leave) { System.out.println(leave.getName() + "由于" + leave.getContent() + ",请假:" + leave.getNum() + "天"); System.out.println("组长审批意见:同意"); } } public class Manager extends Handler { public Manager() { super(Handler.ONE, Handler.THREE); } @Override protected void handlerLeave(LeaveRequest leave) { System.out.println(leave.getName() + "由于" + leave.getContent() + ",请假:" + leave.getNum() + "天"); System.out.println("部门经理意见:同意"); } } public class GeneralManager extends Handler { public GeneralManager() { super(Handler.THREE, Handler.SEVEN); } @Override protected void handlerLeave(LeaveRequest leave) { System.out.println(leave.getName() + "由于" + leave.getContent() + ",请假:" + leave.getNum() + "天"); System.out.println("总经理审批意见:同意"); } }客户类角色public class LeaveRequest { //请假人 private String name; //请假天数 private int num; //请假事由 private String content; public LeaveRequest(String name, int num, String content) { this.name = name; this.num = num; this.content = content; } public String getName() { return name; } public int getNum() { return num; } public String getContent() { return content; } }Clientpublic class Client { public static void main(String[] args) { //创建请假条 LeaveRequest leaveRequest = new LeaveRequest("孙笑川", 2, "感冒"); //各级领导对象 GroupLeader groupLeader = new GroupLeader(); Manager manager = new Manager(); GeneralManager generalManager = new GeneralManager(); //设置处理者链 groupLeader.setNextHandler(manager); manager.setNextHandler(generalManager); //发起请假申请 groupLeader.submit(leaveRequest); } }(4)优缺点降低了请求发送者和接收者的耦合度可根据需求添加新的处理类,复合开闭原则增强了给对象指派职责的灵活性,当工作流程发生变化时,可以动态的改变链内的成员或成员之间的顺序,也可以动态的新增/删除责任简化了对象之间的连接,一个对象只需保持一个指向其后继者的引用,不需要保持其他所有处理者的引用,对客户端来说避免了众多的 if...else 语句职责明确,每个类只需关心自己的职责内容,不能处理的传递给下一个对象,复合类的单一职责原则不能保证每一个请求一定被处理,由于一个请求没有明确的接收者,所以不能暴政它一定被处理,该请求可能一直传递到链的末端也得不到处理较长的责任链可能涉及的多个处理对象,对性能有一定的影响责任链建立的合理性需要靠客户端来保证,增加了客户端的复杂性,可能会由于责任链的设置错误而导致系统出错(如循环调用等)
2022年09月16日
36 阅读
0 评论
0 点赞
2022-09-16
行为型模式-命令模式
(1)概述将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开,使两者之间通过命令对象来进行沟通,便于命令对象的存储、传递、调用、增加及管理(2)结构抽象命令角色:定义命令的接口,声明执行的方法具体命令角色:具体的命令,实现命令接口,持有接收者,并调用接收者的功能来完成命令要执行的操作实现者/接收者角色:执行命令的对象(任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能)调用者/请求者角色:要求命令对象执行请求,持有命令对象(一个或多个),客户端真正触发命令并要求命令执行相应操作的地方(即使用命令对象的入口)(3)案例以点餐为例抽象命令角色public interface Command { /** * 执行命令 */ void execute(); }public class Order { private int diningTable; private Map<String, Integer> foodDic = new HashMap<>(); public int getDiningTable() { return diningTable; } public void setDiningTable(int diningTable) { this.diningTable = diningTable; } public Map<String, Integer> getFoodDic() { return foodDic; } public void setFood(String foodName, int num) { foodDic.put(foodName, num); } }具体命令角色public class OrderCommand implements Command { //持有接收者对象 private SeniorChef receiver; //持有订单对象 private Order order; public OrderCommand(SeniorChef receiver, Order order) { this.receiver = receiver; this.order = order; } @Override public void execute() { System.out.println(order.getDiningTable() + "号桌的订单:"); Map<String, Integer> foodDic = order.getFoodDic(); for (String foodName : foodDic.keySet()) { receiver.makeFood(foodName, foodDic.get(foodName)); } System.out.println(order.getDiningTable() + "号桌的菜品已准备完毕!"); } }实现者/接收者角色public class SeniorChef { public void makeFood(String foodName, int num) { System.out.println("制作了" + num + "份 " + foodName); } }调用者/请求者角色public class Waiter { //持有多个命令对象 private List<Command> commands = new ArrayList<>(); public void command(Command command) { commands.add(command); } public void orderUp() { System.out.println("新订单来了"); for (Command command : commands) { if (command != null) { command.execute(); } } } }Clientpublic class Client { public static void main(String[] args) { //创建订单 Order order1 = new Order(); order1.setDiningTable(1); order1.setFood("小混沌", 1); order1.setFood("煎饼", 1); Order order2 = new Order(); order2.setDiningTable(2); order2.setFood("小炒肉盖饭", 1); order2.setFood("酸梅汤", 1); //创建厨师 SeniorChef receiver = new SeniorChef(); //创建命令对象 OrderCommand command1 = new OrderCommand(receiver, order1); OrderCommand command2 = new OrderCommand(receiver, order2); //创建服务员(调用者) Waiter waiter = new Waiter(); waiter.command(command1); waiter.command(command2); //发起命令 waiter.orderUp(); } }(4)优缺点将调用操作的对象与实现该操作的对象解耦,降低了系统的耦合度增加/删除命令时不会影响其他的类,符合开闭原则通过与组合模式结合,将多个命令装配成一组命令,可以实现宏命令可以实现命令的撤销 redo 与恢复 undo使用该模式可能产生很多的具体命令类(但不会造成类爆炸)系统结构更加复杂(5)使用场景系统需要将请求调用者和接收者解耦,使两者不进行直接交互时系统需要根据不同的情况指定请求、排队请求、执行请求时系统需要支持命令的撤销 redo 与恢复 undo 时
2022年09月16日
26 阅读
0 评论
0 点赞
2022-09-16
行为型模式-策略模式
(1)概述该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变换不会影响客户的使用;它属于对象行为模式,通过对算法进行封装,把使用算法的责任和算法的实现分开,并委派给不同的对象对这些算法进行管理(2)结构抽象策略类:该角色给出所有的策略类所需的接口具体策略类:实现抽象策略定义的接口,提供具体的算法实现或行为环境类:持有一个策略类的引用,供客户端调用(3)案例以促销活动为例抽象策略类public interface Strategy { /** * 展示促销活动 */ void show(); }具体策略类public class StrategyA implements Strategy { @Override public void show() { System.out.println("促销活动A"); } } public class StrategyB implements Strategy { @Override public void show() { System.out.println("促销活动B"); } } public class StrategyC implements Strategy { @Override public void show() { System.out.println("促销活动C"); } }环境类public class SalesMan { private Strategy strategy; public SalesMan(Strategy strategy) { this.strategy = strategy; } public Strategy getStrategy() { return strategy; } public void setStrategy(Strategy strategy) { this.strategy = strategy; } /** * 促销员展示促销活动 */ public void salesManShow() { strategy.show(); } }Clientpublic class Client { public static void main(String[] args) { //促销活动A SalesMan salesMan = new SalesMan(new StrategyA()); salesMan.salesManShow(); System.out.println("======================="); //促销活动B salesMan.setStrategy(new StrategyB()); salesMan.salesManShow(); System.out.println("======================="); //促销活动C salesMan.setStrategy(new StrategyC()); salesMan.salesManShow(); } }(4)优缺点策略类之间可以自由切换新增策略时增加对应的具体策略类即可,复合开闭原则在一定程度上减少了条件选择语句的使用客户端必须知道所有的策略类,并自行决定使用哪一个可能产生很多的具体策略类(5)使用场景系统中需要动态的在几种算法中选择一种时一个类定义了多种行为,且这些行为在这个类的操作中以多个条件语句的形式出现时,可将每个分支条件移入各自对应的策略类中系统中的算法各自独立,且要求对客户隐藏实现的细节时多个类只区别在表现型为不同,可选择策略模式,在运行时动态选择具体要执行的行为
2022年09月16日
31 阅读
0 评论
0 点赞
2022-09-16
行为型模式-模板方法
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,涉及算法和对象间职责的分配分为:模板方法、策略模式、命令模式、责任链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式;其中模板方法、解释器模式属于类行为模式,其他属于对象行为模式模板方法(1)概述定义一个操作中的算法骨架,并将其中的一些步骤延迟到子类中执行,使得子类可以在不改变主干步骤的情况下重定义该算法的某些特定步骤(2)结构抽象类:负责给出一个算法的轮廓和骨架,由一个模板方法和若干个基本方法构成模板方法:定义算法的骨架,按指定的顺序调用其包含的基本方法基本方法:实现算法的各个步骤(模板方法的组成部分)抽象方法:由抽象类声明,由其具体子类实现具体方法:由抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承钩子方法:在抽象类中已实现,包括用于判断的逻辑方法和需要子类重写的空方法两个部分具体子类:实现抽象类中定义的抽象方法和钩子方法钩子方法一般是用于做判断的逻辑方法,类名为 isXXX,返回值类型为 boolean(3)案例以炒菜为例抽象类public abstract class AbstractClass { /** * 模板方法 */ public final void cookProcess() { pourOil(); heatOil(); pourVegetable(); pourSauce(); fry(); } public void pourOil() { System.out.println("倒油"); } public void heatOil() { System.out.println("热油"); } /** * 倒蔬菜 */ public abstract void pourVegetable(); /** * 放调料 */ public abstract void pourSauce(); public void fry() { System.out.println("准备完毕,开始炒菜"); } }具体类public class ConcreteClass_BaoCai extends AbstractClass { @Override public void pourVegetable() { System.out.println("放入包菜"); } @Override public void pourSauce() { System.out.println("放入辣椒"); } } public class ConcreteClass_CaiXin extends AbstractClass { @Override public void pourVegetable() { System.out.println("放入菜心"); } @Override public void pourSauce() { System.out.println("放入蒜瓣"); } }Clientpublic class Client { public static void main(String[] args) { //炒包菜 ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai(); baoCai.cookProcess(); } }(4)优缺点代码复用,相同的代码可以放到抽象父类中,不同的代码放在对应的子类中实现了反向控制,通过父类调用其子类的操作,并通过子类的不同实现扩展不同的行为,复合开闭原则对每个不同的实现都需要定义一个子类,导致类的个数及系统设计难度的增加反向控制降低了代码的易读性(5)使用场景算法的整体步骤固定,但其中的个别部分易变时,使用模板方法可将易变的部分抽象出来,由其子类实现需要通过子类决定父类中的某个步骤是否执行,实现子类对父类的反向控制
2022年09月16日
45 阅读
0 评论
0 点赞
2022-09-16
结构型模式-享元模式
(1)概述运用共享技术来有效支持大量细粒度对象的复用,通过共享已经存在的对象来大幅度减少需要创建对象的数量、避免大量相似对象的开销,从而提高系统资源的利用率(2)结构享元模式存在两种状态:内部状态,即不会随着环境的改变而改变的可共享部分外部状态,内部状态反之享元模式实现的要领就是区分应用中的这两种状态,并将外部状态外部化包含的角色:抽象享元角色:通常是一个接口或抽象类,声明具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)具体享元角色:它实现了抽象享元类,称为享元对象;在具体享元类中为内部状态提供了存储空间(可以结合单例模式来设计具体享元类)非享元角色:并不是所有抽象享元类的子类都需要被共享不能被共享的子类可以设计为非共享具体享元类,当需要它时,可以直接通过实例化创建享元工厂角色:负责创建和管理享元角色,当客户对象请求一个享元对象时,享元工厂检查系统中是否存在该对象,有则直接提供,反之则创建一个对应的新的享元对象(3)案例以俄罗斯方块为例:抽象享元角色public abstract class AbstractBox { /** * 获取图像 * * @return */ public abstract String getShape(); public void display(String color) { System.out.println("方块形状:" + getShape() + ",颜色:" + color); } }具体享元角色public class IBox extends AbstractBox { @Override public String getShape() { return "I"; } } public class LBox extends AbstractBox { @Override public String getShape() { return "L"; } } public class OBox extends AbstractBox { @Override public String getShape() { return "O"; } }享元工厂public class BoxFactory { private HashMap<String, AbstractBox> map; private BoxFactory() { map = new HashMap<>(); map.put("I", new IBox()); map.put("L", new LBox()); map.put("O", new OBox()); } /** * 饿汉式 * * @return */ public static BoxFactory getInstance() { return factory; } private static BoxFactory factory = new BoxFactory(); /** * 根据名称获取图形 * * @param key * @return */ public AbstractBox getShape(String key) { return map.get(key); } }Clientpublic class Client { public static void main(String[] args) { //获取I型盒子 AbstractBox boxI = BoxFactory.getInstance().getShape("I"); boxI.display("灰色"); //获取L型盒子 AbstractBox boxL = BoxFactory.getInstance().getShape("L"); boxL.display("蓝色"); //获取O型盒子 AbstractBox boxO1 = BoxFactory.getInstance().getShape("O"); boxO1.display("绿色"); //获取O图形 AbstractBox boxO2 = BoxFactory.getInstance().getShape("O"); boxO2.display("红色"); //验证两个O型盒子是否为同一对象 System.out.println("两个O型盒子是否为同一对象:" + (boxO1 == boxO2)); } }(4)优缺点极大地减少了内存中相同或相似对象的数量,节约了资源享元模式中的外部状态相对独立,且不影响内部状态为了使对象可以共享,需要装享元对象的部分状态外部化,增加了系统的复杂度(5)使用场景系统中有大量相同或相似的对象对象的大部分状态都可以外部化,可以将这些外部状态传入对象中在使用该模式时需要维护对应的享元对象存储池,需要耗费一定的资源,因此,须在多次重复使用享元对象且必要的情况下才使用该模式
2022年09月16日
26 阅读
0 评论
0 点赞
2022-09-07
结构型模式-组合模式
(1)概述组合模式又称为部分整体模式,是用于把一组相似的对象当作一个单一的对象,该模式依据树形结构来组合对象,用来表示部分以及整体层次(2)结构抽象根节点:定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性树枝节点:定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成树结构叶子节点:其下再无分支,是系统层次遍历的最小单位(3)案例以树形菜单为例:抽象根节点public abstract class MenuComponent { protected String name; protected int level; /** * 添加菜单 * * @param menuComponent */ public void add(MenuComponent menuComponent) { throw new UnsupportedOperationException(); } /** * 移除菜单 * * @param menuComponent */ public void remove(MenuComponent menuComponent) { throw new UnsupportedOperationException(); } /** * 查询子菜单 * * @param index * @return */ public MenuComponent getChild(int index) { throw new UnsupportedOperationException(); } /** * 查询菜单或菜单项的名称 * * @return */ public String getName() { return name; } /** * 打印菜单(包含子菜单和子菜单项) */ public abstract void print(); }树枝节点public class Menu extends MenuComponent { private List<MenuComponent> menuComponentList = new ArrayList<>(); public Menu(String name, int level) { this.name = name; this.level = level; } @Override public void add(MenuComponent menuComponent) { menuComponentList.add(menuComponent); } @Override public void remove(MenuComponent menuComponent) { menuComponentList.remove(menuComponent); } @Override public MenuComponent getChild(int index) { return menuComponentList.get(index); } @Override public void print() { for (int i = 0; i < level; i++) { System.out.print(" "); } //打印菜单名称 System.out.println(name); //打印子菜单/子菜单项名称 for (MenuComponent menuComponent : menuComponentList) { menuComponent.print(); } } } public class MenuItem extends MenuComponent { public MenuItem(String name, int level) { this.name = name; this.level = level; } @Override public void print() { for (int i = 0; i < level; i++) { System.out.print(" "); } //打印菜单项名称 System.out.println(name); } }测试public class Client { public static void main(String[] args) { //创建菜单 MenuComponent menue1 = new Menu("菜单一", 2); menue1.add(new MenuItem("1", 3)); menue1.add(new MenuItem("2", 3)); menue1.add(new MenuItem("3", 3)); MenuComponent menue2 = new Menu("菜单二", 2); menue2.add(new MenuItem("1", 3)); menue2.add(new MenuItem("2", 3)); menue2.add(new MenuItem("3", 3)); MenuComponent menue3 = new Menu("菜单三", 2); menue3.add(new MenuItem("1", 3)); menue3.add(new MenuItem("2", 3)); menue3.add(new MenuItem("3", 3)); MenuComponent menue4 = new Menu("菜单四", 2); menue4.add(new MenuItem("1", 3)); menue4.add(new MenuItem("2", 3)); menue4.add(new MenuItem("3", 3)); //将二级菜单添加到一级菜单中 MenuComponent component = new Menu("根菜单", 1); component.add(menue1); component.add(menue2); component.add(menue3); component.add(menue4); //打印菜单 component.print(); } }(4)分类透明组合模式在该模式中,抽象根节点角色声明了所有用于管理成员对象的方法,以此确保所有的构建类都有相同的接口,即标准组合模式该模式不够安全,因为叶子对象和容器对象有着本质上的区别,叶子对象不可能有下级节点(即不包含成员对象)因此提供的 add()、remove()方法是没有意义的,在运行时调用由于未提供相应的错误处理代码而出错安全组合模式该模式中的抽象根节点角色未提供任何管理成员对象的方法,而是在树枝节点类中声明并实现这些方法,它的缺点是不够透明,因为叶子对象和容器对象具有不同的方法,容器对象中用于管理成员对象的方法没有在抽象根节点中定义,客户端不能实现相应的抽象编程,必须区别对待叶子对象和容器对象(5)优缺点可以清楚定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,便于对整个层次结构的管理客户端可以一致的使用一个组合结构或其中的单个对象,无需关心处理的是单个对象还是整个组合结构新增/删除节点符合开闭原则通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但整个管理的过程并不复杂(6)使用场景多用于需要使用树形结构的场景
2022年09月07日
53 阅读
0 评论
0 点赞
1
...
12
13
14
...
49