浙江网站建设推广公司找哪家,软件开发项目名称有哪些,网站搭建用什么语言,漯河住房和城乡建设局网站前言 本文为 【23种设计模式】行为型模式 相关内容介绍#xff0c;下边将对访问者模式#xff0c;模板模式#xff0c;策略模式#xff0c;状态模式#xff0c;观察者模式#xff0c;备忘录模式#xff0c;中介者模式#xff0c;迭代器模式#xff0c;解释器模式…前言 本文为 【23种设计模式】行为型模式 相关内容介绍下边将对访问者模式模板模式策略模式状态模式观察者模式备忘录模式中介者模式迭代器模式解释器模式命令模式责任链模式具体包括它们的特点与实现等进行详尽介绍~
博主主页小新要变强 的主页 Java全栈学习路线可参考【Java全栈学习路线】最全的Java学习路线及知识清单Java自学方向指引内含最全Java全栈学习技术清单~ 算法刷题路线可参考算法刷题路线总结与相关资料分享内含最详尽的算法刷题路线指南及相关资料分享~ Java微服务开源项目可参考企业级Java微服务开源项目开源框架用于学习、毕设、公司项目、私活等减少开发工作让您只关注业务 目录 行为型模式详细介绍前言目录一、中介者模式1️⃣介绍2️⃣实现二、迭代器模式1️⃣介绍2️⃣实现三、解释器模式1️⃣介绍2️⃣实现四、命令模式1️⃣介绍2️⃣实现五、责任链模式1️⃣介绍2️⃣实现后记一、中介者模式 中介者模式Mediator Pattern是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类该类通常处理不同类之间的通信并支持松耦合使代码易于维护。中介者模式属于行为型模式。
1️⃣介绍
意图 用一个中介对象来封装一系列的对象交互中介者使各对象不需要显式地相互引用从而使其耦合松散而且可以独立地改变它们之间的交互。
主要解决 对象与对象之间存在大量的关联关系这样势必会导致系统的结构变得很复杂同时若一个对象发生改变我们也需要跟踪与之相关联的对象同时做出相应的处理。
何时使用 多个类相互耦合形成了网状结构。
如何解决 将上述网状结构分离为星型结构。
关键代码 对象 Colleague 之间的通信封装到一个类中单独处理。
应用实例
1、中国加入 WTO 之前是各个国家相互贸易结构复杂现在是各个国家通过 WTO 来互相贸易。2、机场调度系统。3、MVC 框架其中C控制器就是 M模型和 V视图的中介者。
优点
1、降低了类的复杂度将一对多转化成了一对一。2、各个类之间的解耦。3、符合迪米特原则。
缺点 中介者会庞大变得复杂难以维护。
使用场景
1、系统中对象之间存在比较复杂的引用关系导致它们之间的依赖关系结构混乱而且难以复用该对象。2、想通过一个中间类来封装多个类中的行为而又不想生成太多的子类。
注意事项 不应当在职责混乱的时候使用。
2️⃣实现
我们通过聊天室实例来演示中介者模式。实例中多个用户可以向聊天室发送消息聊天室向所有的用户显示消息。我们将创建两个类 ChatRoom 和 User。User 对象使用 ChatRoom 方法来分享他们的消息。
MediatorPatternDemo我们的演示类使用 User 对象来显示他们之间的通信。 1创建中介类。
ChatRoom.java
import java.util.Date;public class ChatRoom {public static void showMessage(User user, String message){System.out.println(new Date().toString() [ user.getName() ] : message);}
}2创建 user 类。
User.java
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}public User(String name){this.name name;}public void sendMessage(String message){ChatRoom.showMessage(this,message);}
}3使用 User 对象来显示他们之间的通信。
MediatorPatternDemo.java
public class MediatorPatternDemo {public static void main(String[] args) {User robert new User(Robert);User john new User(John);robert.sendMessage(Hi! John!);john.sendMessage(Hello! Robert!);}
}4执行程序
输出结果
Thu Jan 31 16:05:46 IST 2013 [Robert] : Hi! John!
Thu Jan 31 16:05:46 IST 2013 [John] : Hello! Robert!二、迭代器模式 迭代器模式Iterator Pattern是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素不需要知道集合对象的底层表示。
迭代器模式属于行为型模式。
1️⃣介绍
意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
主要解决 不同的方式来遍历整个整合对象。
何时使用 遍历一个聚合对象。
如何解决 把在元素之间游走的责任交给迭代器而不是聚合对象。
关键代码 定义接口hasNext, next。
应用实例 JAVA 中的 iterator。
优点
1、它支持以不同的方式遍历一个聚合对象。2、迭代器简化了聚合类。3、在同一个聚合上可以有多个遍历。4、在迭代器模式中增加新的聚合类和迭代器类都很方便无须修改原有代码。
缺点 由于迭代器模式将存储数据和遍历数据的职责分离增加新的聚合类需要对应增加新的迭代器类类的个数成对增加这在一定程度上增加了系统的复杂性。
使用场景
1、访问一个聚合对象的内容而无须暴露它的内部表示。2、需要为聚合对象提供多种遍历方式。3、为遍历不同的聚合结构提供一个统一的接口。
注意事项 迭代器模式就是分离了集合对象的遍历行为抽象出一个迭代器类来负责这样既可以做到不暴露集合的内部结构又可让外部代码透明地访问集合内部的数据。
2️⃣实现
我们将创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。
IteratorPatternDemo我们的演示类使用实体类 NamesRepository 来打印 NamesRepository 中存储为集合的 Names。 1创建接口
Iterator.java
public interface Iterator {public boolean hasNext();public Object next();
}Container.java
public interface Container {public Iterator getIterator();
}2创建实现了 Container 接口的实体类。该类有实现了 Iterator 接口的内部类 NameIterator。
NameRepository.java
public class NameRepository implements Container {public String[] names {Robert , John ,Julie , Lora};Overridepublic Iterator getIterator() {return new NameIterator();}private class NameIterator implements Iterator {int index;Overridepublic boolean hasNext() {if(index names.length){return true;}return false;}Overridepublic Object next() {if(this.hasNext()){return names[index];}return null;} }
}3使用 NameRepository 来获取迭代器并打印名字。
IteratorPatternDemo.java
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);} }
}4执行程序输出结果
Name : Robert
Name : John
Name : Julie
Name : Lora三、解释器模式 解释器模式Interpreter Pattern提供了评估语言的语法或表达式的方式它属于行为型模式。这种模式实现了一个表达式接口该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
1️⃣介绍
意图 给定一个语言定义它的文法表示并定义一个解释器这个解释器使用该标识来解释语言中的句子。
主要解决 对于一些固定文法构建一个解释句子的解释器。
何时使用 如果一种特定类型的问题发生的频率足够高那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器该解释器通过解释这些句子来解决该问题。
如何解决 构建语法树定义终结符与非终结符。
关键代码 构建环境类包含解释器之外的一些全局信息一般是 HashMap。
应用实例 编译器、运算表达式计算。
优点
1、可扩展性比较好灵活。2、增加了新的解释表达式的方式。3、易于实现简单文法。
缺点
1、可利用场景比较少。2、对于复杂的文法比较难维护。3、解释器模式会引起类膨胀。4、解释器模式采用递归调用方法。
使用场景
1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。2、一些重复出现的问题可以用一种简单的语言来进行表达。3、一个简单语法需要解释的场景。
注意事项 可利用场景比较少JAVA 中如果碰到可以用 expression4J 代替。
2️⃣实现
我们将创建一个接口 Expression 和实现了 Expression 接口的实体类。定义作为上下文中主要解释器的 TerminalExpression 类。其他的类 OrExpression、AndExpression 用于创建组合式表达式。
InterpreterPatternDemo我们的演示类使用 Expression 类创建规则和演示表达式的解析。 1创建一个表达式接口。
Expression.java
public interface Expression {public boolean interpret(String context);
}2创建实现了上述接口的实体类。
TerminalExpression.java
public class TerminalExpression implements Expression {private String data;public TerminalExpression(String data){this.data data; }Overridepublic boolean interpret(String context) {if(context.contains(data)){return true;}return false;}
}OrExpression.java
public class OrExpression implements Expression {private Expression expr1 null;private Expression expr2 null;public OrExpression(Expression expr1, Expression expr2) { this.expr1 expr1;this.expr2 expr2;}Overridepublic boolean interpret(String context) { return expr1.interpret(context) || expr2.interpret(context);}
}AndExpression.java
public class AndExpression implements Expression {private Expression expr1 null;private Expression expr2 null;public AndExpression(Expression expr1, Expression expr2) { this.expr1 expr1;this.expr2 expr2;}Overridepublic boolean interpret(String context) { return expr1.interpret(context) expr2.interpret(context);}
}3InterpreterPatternDemo 使用 Expression 类来创建规则并解析它们。
InterpreterPatternDemo.java
public class InterpreterPatternDemo {//规则Robert 和 John 是男性public static Expression getMaleExpression(){Expression robert new TerminalExpression(Robert);Expression john new TerminalExpression(John);return new OrExpression(robert, john); }//规则Julie 是一个已婚的女性public static Expression getMarriedWomanExpression(){Expression julie new TerminalExpression(Julie);Expression married new TerminalExpression(Married);return new AndExpression(julie, married); }public static void main(String[] args) {Expression isMale getMaleExpression();Expression isMarriedWoman getMarriedWomanExpression();System.out.println(John is male? isMale.interpret(John));System.out.println(Julie is a married women? isMarriedWoman.interpret(Married Julie));}
}4执行程序输出结果
John is male? true
Julie is a married women? true四、命令模式 命令模式Command Pattern是一种数据驱动的设计模式它属于行为型模式。请求以命令的形式包裹在对象中并传给调用对象。调用对象寻找可以处理该命令的合适的对象并把该命令传给相应的对象该对象执行命令。
1️⃣介绍
意图 将一个请求封装成一个对象从而使您可以用不同的请求对客户进行参数化。
主要解决 在软件系统中行为请求者与行为实现者通常是一种紧耦合的关系但某些场合比如需要对行为进行记录、撤销或重做、事务等处理时这种无法抵御变化的紧耦合的设计就不太合适。
何时使用 在某些场合比如要对行为进行记录、撤销/重做、事务等处理这种无法抵御变化的紧耦合是不合适的。在这种情况下如何将行为请求者与行为实现者解耦将一组行为抽象为对象可以实现二者之间的松耦合。
如何解决 通过调用者调用接受者执行命令顺序调用者→命令→接受者。
关键代码 定义三个角色
1、received 真正的命令执行对象2、Command3、invoker 使用命令对象的入口
应用实例 struts 1 中的 action 核心控制器 ActionServlet 只有一个相当于 Invoker而模型层的类会随着不同的应用有不同的模型类相当于具体的 Command。
优点
1、降低了系统耦合度。2、新的命令可以很容易添加到系统中去。
缺点 使用命令模式可能会导致某些系统有过多的具体命令类。
使用场景 认为是命令的地方都可以使用命令模式比如
1、GUI 中每一个按钮都是一条命令。2、模拟 CMD。
注意事项 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作也可以考虑使用命令模式见命令模式的扩展。
2️⃣实现
我们首先创建作为命令的接口 Order然后创建作为请求的 Stock 类。实体命令类 BuyStock 和 SellStock实现了 Order 接口将执行实际的命令处理。创建作为调用对象的类 Broker它接受订单并能下订单。
Broker 对象使用命令模式基于命令的类型确定哪个对象执行哪个命令。CommandPatternDemo 类使用 Broker 类来演示命令模式。 1创建一个命令接口。
Order.java
public interface Order {void execute();
}2创建一个请求类。
Stock.java
public class Stock {private String name ABC;private int quantity 10;public void buy(){System.out.println(Stock [ Name: name, Quantity: quantity ] bought);}public void sell(){System.out.println(Stock [ Name: name, Quantity: quantity ] sold);}
}3创建实现了 Order 接口的实体类。
BuyStock.java
public class BuyStock implements Order {private Stock abcStock;public BuyStock(Stock abcStock){this.abcStock abcStock;}public void execute() {abcStock.buy();}
}SellStock.java
public class SellStock implements Order {private Stock abcStock;public SellStock(Stock abcStock){this.abcStock abcStock;}public void execute() {abcStock.sell();}
}4创建命令调用类。
Broker.java
import java.util.ArrayList;
import java.util.List;public class Broker {private ListOrder orderList new ArrayListOrder(); public void takeOrder(Order order){orderList.add(order); }public void placeOrders(){for (Order order : orderList) {order.execute();}orderList.clear();}
}5使用 Broker 类来接受并执行命令。
CommandPatternDemo.java
public class CommandPatternDemo {public static void main(String[] args) {Stock abcStock new Stock();BuyStock buyStockOrder new BuyStock(abcStock);SellStock sellStockOrder new SellStock(abcStock);Broker broker new Broker();broker.takeOrder(buyStockOrder);broker.takeOrder(sellStockOrder);broker.placeOrders();}
}6执行程序
输出结果
Stock [ Name: ABC, Quantity: 10 ] bought
Stock [ Name: ABC, Quantity: 10 ] sold五、责任链模式 顾名思义责任链模式Chain of Responsibility Pattern为请求创建了一个接收者对象的链。这种模式给予请求的类型对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求那么它会把相同的请求传给下一个接收者依此类推。
1️⃣介绍
意图 避免请求发送者与接收者耦合在一起让多个对象都有可能接收请求将这些对象连接成一条链并且沿着这条链传递请求直到有对象处理它为止。
主要解决 职责链上的处理者负责处理请求客户只需要将请求发送到职责链上即可无须关心请求的处理细节和请求的传递所以职责链将请求的发送者和请求的处理者解耦了。
何时使用 在处理消息的时候以过滤很多道。
如何解决 拦截的类都实现统一接口。
关键代码 Handler 里面聚合它自己在 HandlerRequest 里判断是否合适如果没达到条件则向下传递向谁传递之前 set 进去。
应用实例
1、红楼梦中的击鼓传花。2、JS 中的事件冒泡。3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理Struts2 的拦截器jsp servlet 的 Filter。
优点
1、降低耦合度。它将请求的发送者和接收者解耦。2、简化了对象。使得对象不需要知道链的结构。3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序允许动态地新增或者删除责任。4、增加新的请求处理类很方便。
缺点
1、不能保证请求一定被接收。2、系统性能将受到一定影响而且在进行代码调试时不太方便可能会造成循环调用。3、可能不容易观察运行时的特征有碍于除错。
使用场景
1、有多个对象可以处理同一个请求具体哪个对象处理该请求由运行时刻自动确定。2、在不明确指定接收者的情况下向多个对象中的一个提交一个请求。3、可动态指定一组对象处理请求。
注意事项 在 JAVA WEB 中遇到很多应用。
2️⃣实现
我们创建抽象类 AbstractLogger带有详细的日志记录级别。然后我们创建三种类型的记录器都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别如果是则相应地打印出来否则将不打印并把消息传给下一个记录器。 1创建抽象的记录器类。
AbstractLogger.java
public abstract class AbstractLogger {public static int INFO 1;public static int DEBUG 2;public static int ERROR 3;protected int level;//责任链中的下一个元素protected AbstractLogger nextLogger;public void setNextLogger(AbstractLogger nextLogger){this.nextLogger nextLogger;}public void logMessage(int level, String message){if(this.level level){write(message);}if(nextLogger !null){nextLogger.logMessage(level, message);}}abstract protected void write(String message);}2创建扩展了该记录器类的实体类。
ConsoleLogger.java
public class ConsoleLogger extends AbstractLogger {public ConsoleLogger(int level){this.level level;}Overrideprotected void write(String message) { System.out.println(Standard Console::Logger: message);}
}ErrorLogger.java
public class ErrorLogger extends AbstractLogger {public ErrorLogger(int level){this.level level;}Overrideprotected void write(String message) { System.out.println(Error Console::Logger: message);}
}FileLogger.java
public class FileLogger extends AbstractLogger {public FileLogger(int level){this.level level;}Overrideprotected void write(String message) { System.out.println(File::Logger: message);}
}3创建不同类型的记录器。赋予它们不同的错误级别并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分。
ChainPatternDemo.java
public class ChainPatternDemo {private static AbstractLogger getChainOfLoggers(){AbstractLogger errorLogger new ErrorLogger(AbstractLogger.ERROR);AbstractLogger fileLogger new FileLogger(AbstractLogger.DEBUG);AbstractLogger consoleLogger new ConsoleLogger(AbstractLogger.INFO);errorLogger.setNextLogger(fileLogger);fileLogger.setNextLogger(consoleLogger);return errorLogger; }public static void main(String[] args) {AbstractLogger loggerChain getChainOfLoggers();loggerChain.logMessage(AbstractLogger.INFO, This is an information.);loggerChain.logMessage(AbstractLogger.DEBUG, This is a debug level information.);loggerChain.logMessage(AbstractLogger.ERROR, This is an error information.);}
}4执行程序
输出结果
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Standard Console::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.后记 Java全栈学习路线可参考【Java全栈学习路线】最全的Java学习路线及知识清单Java自学方向指引内含最全Java全栈学习技术清单~ 算法刷题路线可参考算法刷题路线总结与相关资料分享内含最详尽的算法刷题路线指南及相关资料分享~ 文章转载自: http://www.morning.nbhft.cn.gov.cn.nbhft.cn http://www.morning.pqnpd.cn.gov.cn.pqnpd.cn http://www.morning.wrlcy.cn.gov.cn.wrlcy.cn http://www.morning.chgmm.cn.gov.cn.chgmm.cn http://www.morning.ljqd.cn.gov.cn.ljqd.cn http://www.morning.reababy.com.gov.cn.reababy.com http://www.morning.krqhw.cn.gov.cn.krqhw.cn http://www.morning.gtwtk.cn.gov.cn.gtwtk.cn http://www.morning.dnhdp.cn.gov.cn.dnhdp.cn http://www.morning.hytfz.cn.gov.cn.hytfz.cn http://www.morning.knczz.cn.gov.cn.knczz.cn http://www.morning.brlcj.cn.gov.cn.brlcj.cn http://www.morning.pxbky.cn.gov.cn.pxbky.cn http://www.morning.byjwl.cn.gov.cn.byjwl.cn http://www.morning.gnkdp.cn.gov.cn.gnkdp.cn http://www.morning.nlwrg.cn.gov.cn.nlwrg.cn http://www.morning.mznqz.cn.gov.cn.mznqz.cn http://www.morning.wschl.cn.gov.cn.wschl.cn http://www.morning.xxiobql.cn.gov.cn.xxiobql.cn http://www.morning.nlkhr.cn.gov.cn.nlkhr.cn http://www.morning.nhgfz.cn.gov.cn.nhgfz.cn http://www.morning.jjxnp.cn.gov.cn.jjxnp.cn http://www.morning.dglszn.com.gov.cn.dglszn.com http://www.morning.wbqk.cn.gov.cn.wbqk.cn http://www.morning.nkmw.cn.gov.cn.nkmw.cn http://www.morning.xdnhw.cn.gov.cn.xdnhw.cn http://www.morning.xxzjb.cn.gov.cn.xxzjb.cn http://www.morning.tgtwy.cn.gov.cn.tgtwy.cn http://www.morning.fdrb.cn.gov.cn.fdrb.cn http://www.morning.wrbx.cn.gov.cn.wrbx.cn http://www.morning.gjfym.cn.gov.cn.gjfym.cn http://www.morning.jrplk.cn.gov.cn.jrplk.cn http://www.morning.kvzvoew.cn.gov.cn.kvzvoew.cn http://www.morning.ldpjm.cn.gov.cn.ldpjm.cn http://www.morning.bxyzr.cn.gov.cn.bxyzr.cn http://www.morning.rhsg.cn.gov.cn.rhsg.cn http://www.morning.kmcfw.cn.gov.cn.kmcfw.cn http://www.morning.xcnwf.cn.gov.cn.xcnwf.cn http://www.morning.mdmxf.cn.gov.cn.mdmxf.cn http://www.morning.rpdmj.cn.gov.cn.rpdmj.cn http://www.morning.mpszk.cn.gov.cn.mpszk.cn http://www.morning.ymjgx.cn.gov.cn.ymjgx.cn http://www.morning.lstmg.cn.gov.cn.lstmg.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.xhrws.cn.gov.cn.xhrws.cn http://www.morning.gwhjy.cn.gov.cn.gwhjy.cn http://www.morning.kyzja.com.gov.cn.kyzja.com http://www.morning.rcjyc.cn.gov.cn.rcjyc.cn http://www.morning.kgqww.cn.gov.cn.kgqww.cn http://www.morning.jzsgn.cn.gov.cn.jzsgn.cn http://www.morning.plznfnh.cn.gov.cn.plznfnh.cn http://www.morning.dkslm.cn.gov.cn.dkslm.cn http://www.morning.xctdn.cn.gov.cn.xctdn.cn http://www.morning.klwxh.cn.gov.cn.klwxh.cn http://www.morning.bkkgt.cn.gov.cn.bkkgt.cn http://www.morning.qnbgk.cn.gov.cn.qnbgk.cn http://www.morning.dtlnz.cn.gov.cn.dtlnz.cn http://www.morning.nfbkp.cn.gov.cn.nfbkp.cn http://www.morning.rxhsm.cn.gov.cn.rxhsm.cn http://www.morning.lyzwdt.com.gov.cn.lyzwdt.com http://www.morning.bfsqz.cn.gov.cn.bfsqz.cn http://www.morning.ppwdh.cn.gov.cn.ppwdh.cn http://www.morning.srhqm.cn.gov.cn.srhqm.cn http://www.morning.wjplm.cn.gov.cn.wjplm.cn http://www.morning.rmfw.cn.gov.cn.rmfw.cn http://www.morning.ruyuaixuexi.com.gov.cn.ruyuaixuexi.com http://www.morning.lhygbh.com.gov.cn.lhygbh.com http://www.morning.lhyhx.cn.gov.cn.lhyhx.cn http://www.morning.kqkmx.cn.gov.cn.kqkmx.cn http://www.morning.zrdqz.cn.gov.cn.zrdqz.cn http://www.morning.sbrxm.cn.gov.cn.sbrxm.cn http://www.morning.yszrk.cn.gov.cn.yszrk.cn http://www.morning.cprbp.cn.gov.cn.cprbp.cn http://www.morning.dblfl.cn.gov.cn.dblfl.cn http://www.morning.xbwqg.cn.gov.cn.xbwqg.cn http://www.morning.ksjnl.cn.gov.cn.ksjnl.cn http://www.morning.pcngq.cn.gov.cn.pcngq.cn http://www.morning.dqwykj.com.gov.cn.dqwykj.com http://www.morning.drtgt.cn.gov.cn.drtgt.cn http://www.morning.dtnzk.cn.gov.cn.dtnzk.cn