Java策略设计模式中通用逻辑的合理编写位置探讨
Java策略模式中通用文件验证逻辑的合理实现方案
针对你要给所有文件解析策略添加通用验证(比如文件存在、大小非0、文件名合法等)的需求,最直接高效的方案是把通用逻辑放到抽象基类BaseFileParser中,具体实现和分析如下:
方案一:抽象基类封装通用逻辑,子类专注解析
利用基类的非抽象方法统一处理验证流程,子类只需要实现各自的解析逻辑,既避免代码重复,又符合单一职责原则。
修改后的基类 BaseFileParser.java
public abstract class BaseFileParser { // 通用文件验证逻辑,所有子类共享 protected void validateFile(File file) { // 验证文件存在 if (!file.exists()) { throw new IllegalArgumentException("目标文件不存在"); } // 验证文件大小大于0 if (file.length() <= 0) { throw new IllegalArgumentException("文件大小不能为0"); } // 验证文件名格式(示例:只允许xml/csv后缀,文件名由合法字符组成) String fileName = file.getName(); if (!fileName.matches("^[a-zA-Z0-9_\\-]+\\.(xml|csv)$")) { throw new IllegalArgumentException("文件名格式不合法,需为xml或csv格式"); } } // 子类需实现的具体解析方法 protected abstract void doParseFile(File file); // 对外统一入口:先执行验证,再调用子类解析逻辑 public void parseFile(File file) { validateFile(file); doParseFile(file); } }
修改后的XML解析子类 XMLFileParser.java
public class XMLFileParser extends BaseFileParser { @Override protected void doParseFile(File file) { // 只需要实现XML专属的解析逻辑 System.out.println("开始解析XML文件:" + file.getAbsolutePath()); // 具体解析代码... } }
修改后的CSV解析子类 CSVFileParser.java
public class CSVFileParser extends BaseFileParser { @Override protected void doParseFile(File file) { // 只需要实现CSV专属的解析逻辑 System.out.println("开始解析CSV文件:" + file.getAbsolutePath()); // 具体解析代码... } }
修改后的客户端 Client.java
public class Client { private BaseFileParser baseFileParser; public Client(BaseFileParser baseFileParser) { this.baseFileParser = baseFileParser; } public void parseFile(File file) { baseFileParser.parseFile(file); } public static void main(String args[]) { // 解析XML文件 Client xmlClient = new Client(new XMLFileParser()); xmlClient.parseFile(new File("test.xml")); // 解析CSV文件 Client csvClient = new Client(new CSVFileParser()); csvClient.parseFile(new File("data.csv")); } }
方案优势:
- 通用验证逻辑集中管理,无需在每个子类重复编写,符合DRY(Don't Repeat Yourself)原则
- 子类仅需关注自身的解析逻辑,职责更单一
- 后续修改验证规则时,仅需改动基类即可,所有子类自动生效,维护成本低
方案二:装饰器模式(适合原有代码无法修改的场景)
如果你的基类和子类已经固定、无法修改,可以用装饰器模式给每个策略类动态添加验证功能,但这种方式会增加类的数量,适合临时扩展的场景。
装饰器类示例 ValidatedFileParserDecorator.java
public class ValidatedFileParserDecorator extends BaseFileParser { private BaseFileParser delegateParser; public ValidatedFileParserDecorator(BaseFileParser delegateParser) { this.delegateParser = delegateParser; } // 通用验证逻辑 private void validateFile(File file) { if (!file.exists()) throw new IllegalArgumentException("文件不存在"); if (file.length() <= 0) throw new IllegalArgumentException("文件大小为0"); // 其他验证规则... } @Override public void parseFile(File file) { validateFile(file); // 调用原解析器的逻辑 delegateParser.parseFile(file); } }
客户端使用方式
public static void main(String args[]) { // 给XML解析器动态添加验证功能 BaseFileParser validatedXmlParser = new ValidatedFileParserDecorator(new XMLFileParser()); Client client = new Client(validatedXmlParser); client.parseFile(new File("test.xml")); }
总结
优先选择方案一,因为它完全贴合你现有的继承结构,代码简洁直观,维护起来也更方便。装饰器模式仅适合原有代码无法改动的特殊场景。
内容的提问来源于stack exchange,提问作者JavaUser
相关产品推荐
相关产品推荐

