做直播网站vps可以吗,申请免费个人网站,wordpress前端会员中心,深圳企业主页制作《设计模式之行为型模式》系列#xff0c;共包含以下文章#xff1a;
行为型模式#xff08;一#xff09;#xff1a;模板方法模式、观察者模式行为型模式#xff08;二#xff09;#xff1a;策略模式、命令模式行为型模式#xff08;三#xff09;#xff1a;责…《设计模式之行为型模式》系列共包含以下文章
行为型模式一模板方法模式、观察者模式行为型模式二策略模式、命令模式行为型模式三责任链模式、状态模式行为型模式四备忘录模式、中介者模式行为型模式五解释器模式、访问者模式、依赖注入 如果您觉得这篇文章有用 ✔️ 的话请给博主一个一键三连 吧 点赞 、关注 、收藏 您的支持 将激励 博主输出更多优质内容 行为型模式五解释器模式、访问者模式 9.解释器模式Interpreter9.1 代码示例9.1.1 定义表达式接口9.1.2 实现具体表达式类9.1.3 客户端 10.访问者模式Visitor10.1 代码示例10.1.1 元素接口10.1.2 具体元素10.1.3 访问者接口10.1.4 具体访问者10.1.5 对象结构10.1.6 客户端10.1.7 输出 11.依赖注入Dependency Injection11.1 代码示例11.1.1 构造器注入Constructor Injection11.1.2 设值方法注入Setter Injection11.1.3 接口注入11.1.3.1 定义注入接口11.1.3.2 实现注入接口11.1.3.3 客户端 11.2 总结 9.解释器模式Interpreter
解释器模式Interpreter是一种行为设计模式它主要用于处理语言、表达式或命令的解析和执行。这种模式定义了如何构建一个解释器来解析特定的语句或命令并执行相应的操作。下面是解释器模式的一些关键点
文法定义首先需要定义一个文法这个文法描述了语言或表达式的结构。例如一个简单的算术表达式文法可能包括加法、减法等操作。表达式接口定义一个抽象类或接口所有具体的表达式类都实现这个接口。接口通常包含一个 interpret 方法用于解释和执行表达式。具体表达式类实现表达式接口的具体类每个类负责解析和执行特定类型的表达式。例如AddExpression 类负责处理加法操作。上下文一个上下文对象用于存储解析过程中需要的信息如变量值、中间结果等。客户端客户端代码将表达式组合成一个大的表达式树然后调用 interpret 方法来解析和执行整个表达式。 9.1 代码示例
假设我们要解析和执行一个简单的算术表达式如 1 2 * 3。我们可以使用解释器模式来实现
9.1.1 定义表达式接口
public interface Expression {int interpret();
}9.1.2 实现具体表达式类
public class NumberExpression implements Expression {private int number;public NumberExpression(int number) {this.number number;}Overridepublic int interpret() {return number;}
}public class AddExpression implements Expression {private Expression left, right;public AddExpression(Expression left, Expression right) {this.left left;this.right right;}Overridepublic int interpret() {return left.interpret() right.interpret();}
}public class MultiplyExpression implements Expression {private Expression left, right;public MultiplyExpression(Expression left, Expression right) {this.left left;this.right right;}Overridepublic int interpret() {return left.interpret() * right.interpret();}
}9.1.3 客户端
public class Client {public static void main(String[] args) {Expression expression new AddExpression(new NumberExpression(1),new MultiplyExpression(new NumberExpression(2),new NumberExpression(3)));int result expression.interpret();System.out.println(结果: result); // 输出: 结果: 7}
}expression 是一个 AddExpression 对象。 调用 AddExpression 的 interpret 方法 left.interpret() 调用 NumberExpression(1) 的 interpret 方法返回 1。right.interpret() 调用 MultiplyExpression(2, 3) 的 interpret 方法 left.interpret() 调用 NumberExpression(2) 的 interpret 方法返回 2。right.interpret() 调用 NumberExpression(3) 的 interpret 方法返回 3。MultiplyExpression 的 interpret 方法返回 2 * 3 6。 AddExpression 的 interpret 方法返回 1 6 7。
通过这种方式解释器模式可以灵活地解析和执行复杂的表达式同时保持代码的可扩展性和可维护性。
10.访问者模式Visitor
访问者模式Visitor是一种行为设计模式它允许你在不改变数据结构的情况下为数据结构中的元素添加新的操作。这种模式特别适用于数据结构相对稳定但需要在数据结构上定义很多操作的场景。以下是访问者模式的几个关键点
元素Element定义一个接受访问者的方法 accept(Visitor visitor)该方法会调用访问者的方法来访问元素。访问者Visitor定义一系列访问方法每个方法对应一种元素类型。访问方法通常命名为 visit(Element element)。具体元素ConcreteElement实现 accept 方法该方法会调用访问者的一个访问方法。具体访问者ConcreteVisitor实现访问者接口中的访问方法对具体元素进行操作。对象结构ObjectStructure可以是集合或其他数据结构包含元素对象并提供方法让访问者访问这些元素。 10.1 代码示例
假设你有一个文档编辑器文档中包含不同类型的对象如文本段落和图片。你希望在不修改这些对象的情况下为它们添加新的操作比如计算字数或生成缩略图。
10.1.1 元素接口
interface Element {void accept(Visitor visitor);
}10.1.2 具体元素
class Paragraph implements Element {private String text;public Paragraph(String text) {this.text text;}public String getText() {return text;}Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}class Image implements Element {private String url;public Image(String url) {this.url url;}public String getUrl() {return url;}Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}10.1.3 访问者接口
interface Visitor {void visit(Paragraph paragraph);void visit(Image image);
}10.1.4 具体访问者
class WordCountVisitor implements Visitor {private int wordCount 0;Overridepublic void visit(Paragraph paragraph) {String[] words paragraph.getText().split(\\s);wordCount words.length;}Overridepublic void visit(Image image) {// 图片不增加字数}public int getWordCount() {return wordCount;}
}class ThumbnailGeneratorVisitor implements Visitor {Overridepublic void visit(Paragraph paragraph) {// 文本段落不需要生成缩略图}Overridepublic void visit(Image image) {System.out.println(Generating thumbnail for image: image.getUrl());}
}10.1.5 对象结构
class Document {private ListElement elements new ArrayList();public void addElement(Element element) {elements.add(element);}public void accept(Visitor visitor) {for (Element element : elements) {element.accept(visitor);}}
}10.1.6 客户端
public class VisitorPatternDemo {public static void main(String[] args) {Document document new Document();document.addElement(new Paragraph(Hello, world!));document.addElement(new Image(http://example.com/image.jpg));WordCountVisitor wordCountVisitor new WordCountVisitor();document.accept(wordCountVisitor);System.out.println(Total word count: wordCountVisitor.getWordCount());ThumbnailGeneratorVisitor thumbnailGeneratorVisitor new ThumbnailGeneratorVisitor();document.accept(thumbnailGeneratorVisitor);}
}10.1.7 输出
Total word count: 2
Generating thumbnail for image: http://example.com/image.jpg通过访问者模式你可以在不修改文档元素的情况下为它们添加新的操作如计算字数和生成缩略图。
11.依赖注入Dependency Injection
依赖注入Dependency Injection是一种设计模式用于实现控制反转Inversion of ControlIoC。它的主要目的是减少代码之间的耦合提高代码的可测试性和可维护性。通过依赖注入对象的依赖关系由外部提供而不是由对象自己创建或查找。 11.1 代码示例
假设有一个 Logger 接口和两个实现类 FileLogger 和 ConsoleLogger以及一个需要日志功能的 UserService 类。
11.1.1 构造器注入Constructor Injection
通过构造器传递依赖对象。
优点依赖关系清晰不可变性好。缺点构造器参数过多时代码可读性下降。
// Logger 接口
interface Logger {void log(String message);
}// FileLogger 实现
class FileLogger implements Logger {Overridepublic void log(String message) {System.out.println(File: message);}
}// ConsoleLogger 实现
class ConsoleLogger implements Logger {Overridepublic void log(String message) {System.out.println(Console: message);}
}// UserService 类通过构造器注入 Logger
class UserService {private final Logger logger;public UserService(Logger logger) {this.logger logger;}public void createUser(String name) {logger.log(Creating user: name);// 其他创建用户的逻辑}
}// 客户端代码
public class Main {public static void main(String[] args) {Logger logger new ConsoleLogger();UserService userService new UserService(logger);userService.createUser(Alice);}
}11.1.2 设值方法注入Setter Injection
通过设值方法setter传递依赖对象。
优点灵活性高便于修改依赖关系。缺点依赖关系不那么明显对象可能处于不完整状态。
// Logger 接口
interface Logger {void log(String message);
}// FileLogger 实现
class FileLogger implements Logger {Overridepublic void log(String message) {System.out.println(File: message);}
}// ConsoleLogger 实现
class ConsoleLogger implements Logger {Overridepublic void log(String message) {System.out.println(Console: message);}
}// UserService 类通过设值方法注入 Logger
class UserService {private Logger logger;public void setLogger(Logger logger) {this.logger logger;}public void createUser(String name) {logger.log(Creating user: name);// 其他创建用户的逻辑}
}// 客户端代码
public class Main {public static void main(String[] args) {UserService userService new UserService();Logger logger new ConsoleLogger();userService.setLogger(logger);userService.createUser(Alice);}
}11.1.3 接口注入
通过接口方法传递依赖对象。
优点灵活性高适用于复杂的依赖关系。缺点实现复杂使用较少。
11.1.3.1 定义注入接口
// Logger 接口
interface Logger {void log(String message);
}// FileLogger 实现
class FileLogger implements Logger {Overridepublic void log(String message) {System.out.println(File: message);}
}// ConsoleLogger 实现
class ConsoleLogger implements Logger {Overridepublic void log(String message) {System.out.println(Console: message);}
}// 注入接口
interface LoggerInjector {void injectLogger(Logger logger);
}11.1.3.2 实现注入接口
UserService 类需要实现 LoggerInjector 接口并提供一个方法来注入 Logger 对象。
// UserService 类实现 LoggerInjector 接口
class UserService implements LoggerInjector {private Logger logger;Overridepublic void injectLogger(Logger logger) {this.logger logger;}public void createUser(String name) {logger.log(Creating user: name);// 其他创建用户的逻辑}
}11.1.3.3 客户端
public class Main {public static void main(String[] args) {// 创建 UserService 对象UserService userService new UserService();// 创建 Logger 对象Logger logger new ConsoleLogger();// 通过 LoggerInjector 接口注入 Logger 对象((LoggerInjector) userService).injectLogger(logger);// 使用 UserServiceuserService.createUser(Alice);}
}类型转换 userService 是一个 UserService 类的实例。UserService 类实现了 LoggerInjector 接口因此 userService 也可以被视为 LoggerInjector 类型的对象。通过 ((LoggerInjector) userService)我们将 userService 强制转换为 LoggerInjector 类型。 调用注入方法 LoggerInjector 接口定义了一个 injectLogger 方法。通过类型转换后我们可以调用 injectLogger 方法将 Logger 对象注入到 UserService 中。
11.2 总结
依赖注入是一种强大的设计模式通过外部提供依赖关系使得代码更加灵活、可测试和可维护。
降低耦合度对象不再负责创建或查找其依赖依赖关系由外部提供。提高可测试性可以通过注入不同的依赖来测试对象的行为。提高可维护性依赖关系明确代码更易于理解和维护。
构造器注入、设值方法注入和接口注入是实现依赖注入的三种主要方式每种方式都有其适用场景和优缺点。