diff --git a/w9/AI架构审计.txt b/w9/AI架构审计.txt new file mode 100644 index 0000000..78d9b84 --- /dev/null +++ b/w9/AI架构审计.txt @@ -0,0 +1,26 @@ +指令:作为Java架构审计师,请检查以下MVC三层划分是否存在越权行为: +1. 模型层:Article(包含标题、内容、作者、发布日期字段,仅提供Getter/Setter) +2. 控制层:CommandController(处理用户命令逻辑)、HistoryCommand(记录命令历史) +3. 视图层:ConsoleView(仅负责控制台输入输出) +请分析各层职责边界是否清晰,是否存在跨层直接操作数据、越权访问等问题。 + +输出: +一、审计结论 +MVC 三层架构职责边界清晰,无跨层操作数据、越权访问等行为,仅存在一处非风险优化点。 + +二、各层合规性分析 +1.模型层(Article) +仅封装数据,提供Getter/Setter,无业务逻辑、跨层依赖,数据访问受控,合规。 +2.控制层(CommandController/HistoryCommand) +仅处理命令逻辑、记录命令历史,通过公开接口操作模型层数据,无越权接管视图层职责,合规。 +3.视图层(ConsoleView) +仅负责控制台10,无业务逻辑,通过 Getter 获取模型层数据,无越权修改行为,合规。 + +三,优化建议 (非风险) +HistoryCommand 若采用静态存储命令历史,建议改为实例成员变量,通过单例/工厂模式调用,降低耦合。 + +四、实施建议 +1.保留现有分层,视图层仅接收控制层数据,控制层作为数据交互中枢,模型层保持纯数据载 +体特性; +2.按需优化 HistoryCommand 设计; +3.迭代中校验职责边界,避免混淆。 \ No newline at end of file diff --git a/w9/Article.java b/w9/Article.java new file mode 100644 index 0000000..30a1bf2 --- /dev/null +++ b/w9/Article.java @@ -0,0 +1,65 @@ +import java.util.Date; + +/** + * 文章实体类(MVC-模型层) + */ +public class Article { + private String title; // 标题 + private String content; // 内容 + private String author; // 新增:作者 + private Date publishDate; // 新增:发布日期 + + // 全参构造器 + public Article(String title, String content, String author, Date publishDate) { + this.title = title; + this.content = content; + this.author = author; + this.publishDate = publishDate; + } + + // 空参构造器 + public Article() {} + + // Getter & Setter + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public Date getPublishDate() { + return publishDate; + } + + public void setPublishDate(Date publishDate) { + this.publishDate = publishDate; + } + + @Override + public String toString() { + return "Article{" + + "title='" + title + '\'' + + ", content='" + content + '\'' + + ", author='" + author + '\'' + + ", publishDate=" + publishDate + + '}'; + } +} \ No newline at end of file diff --git a/w9/CommandController.java b/w9/CommandController.java new file mode 100644 index 0000000..85009cc --- /dev/null +++ b/w9/CommandController.java @@ -0,0 +1,17 @@ +/** + * 命令控制类(MVC-控制层核心) + */ +public class CommandController { + public void executeCommand(String input) { + // 解析命令别名 + String realCommand = CommandParser.parseAlias(input); + + // 执行对应命令逻辑 + if ("crawl".equals(realCommand)) { + System.out.println("执行爬取操作..."); + } + + // 记录原始命令到历史 + HistoryCommand.addCommand(input); + } +} \ No newline at end of file diff --git a/w9/CommandParser.java b/w9/CommandParser.java new file mode 100644 index 0000000..4efa293 --- /dev/null +++ b/w9/CommandParser.java @@ -0,0 +1,18 @@ +/** + * 命令解析工具类(控制层-处理命令别名) + */ +public class CommandParser { + public static String parseAlias(String command) { + if (command == null) { + return null; + } + // 处理别名:c -> crawl + switch (command.trim()) { + case "c": + return "crawl"; + // 可扩展其他别名 + default: + return command.trim(); + } + } +} \ No newline at end of file diff --git a/w9/ConsoleView.java b/w9/ConsoleView.java new file mode 100644 index 0000000..f7d28d6 --- /dev/null +++ b/w9/ConsoleView.java @@ -0,0 +1,12 @@ +/** + * 控制台视图类(MVC-视图层) + */ +public class ConsoleView { + public void render() { + // 应用暗色主题常量 + System.out.println("=== 暗色主题模式 ==="); + System.out.println("背景色:" + ViewConstants.BACKGROUND_COLOR); + System.out.println("文本色:" + ViewConstants.TEXT_COLOR); + // 其他视图渲染逻辑 + } +} \ No newline at end of file diff --git a/w9/CrawlController.java b/w9/CrawlController.java new file mode 100644 index 0000000..b5f0b4c --- /dev/null +++ b/w9/CrawlController.java @@ -0,0 +1,14 @@ +/** + * 爬取控制类(MVC-控制层) + */ +public class CrawlController { + public void crawl(String url) { + // 验证URL格式 + if (!UrlValidator.isValidUrl(url)) { + System.out.println("URL格式非法:" + url); + return; + } + // 执行爬取逻辑(示例) + System.out.println("爬取URL:" + url + " 成功"); + } +} \ No newline at end of file diff --git a/w9/HistoryCommand.java b/w9/HistoryCommand.java new file mode 100644 index 0000000..8d3a8d1 --- /dev/null +++ b/w9/HistoryCommand.java @@ -0,0 +1,27 @@ +import java.util.ArrayList; +import java.util.List; + +/** + * 命令历史记录类(MVC-控制层辅助) + */ +public class HistoryCommand { + // 私有化List,避免外部直接修改 + private static final List commandList = new ArrayList<>(); + + // 新增命令记录 + public static void addCommand(String command) { + if (command != null && !command.trim().isEmpty()) { + commandList.add(command); + } + } + + // 获取所有命令记录(返回副本,避免外部修改原集合) + public static List getCommandList() { + return new ArrayList<>(commandList); + } + + // 清空命令记录 + public static void clearHistory() { + commandList.clear(); + } +} \ No newline at end of file diff --git a/w9/Main.java b/w9/Main.java new file mode 100644 index 0000000..7ee3964 --- /dev/null +++ b/w9/Main.java @@ -0,0 +1,29 @@ +import java.util.Date; +import java.util.List; + +/** + * 程序主入口(测试所有功能) + */ +public class Main { + public static void main(String[] args) { + // 1. 测试Article扩展字段 + Article article = new Article("Java MVC", "MVC分层设计", "张三", new Date()); + System.out.println("Article信息:" + article); + + // 2. 测试命令别名+历史记录 + CommandController cmdController = new CommandController(); + cmdController.executeCommand("c"); // 别名c -> crawl + cmdController.executeCommand("crawl"); // 原始命令 + List history = HistoryCommand.getCommandList(); + System.out.println("命令历史:" + history); + + // 3. 测试URL验证 + CrawlController crawlController = new CrawlController(); + crawlController.crawl("https://www.example.com"); // 合法URL + crawlController.crawl("invalid-url"); // 非法URL + + // 4. 测试暗色主题 + ConsoleView view = new ConsoleView(); + view.render(); + } +} \ No newline at end of file diff --git a/w9/UrlValidator.java b/w9/UrlValidator.java new file mode 100644 index 0000000..06dc0a3 --- /dev/null +++ b/w9/UrlValidator.java @@ -0,0 +1,18 @@ +import java.util.regex.Pattern; + +/** + * URL验证工具类(工具层) + */ +public class UrlValidator { + // URL正则表达式(简化版,适配http/https/ftp) + private static final String URL_REGEX = "^(https?|ftp)://[a-zA-Z0-9.-]+(:\\d+)?(/.*)?$"; + private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX); + + // 验证URL格式 + public static boolean isValidUrl(String url) { + if (url == null || url.trim().isEmpty()) { + return false; + } + return URL_PATTERN.matcher(url.trim()).matches(); + } +} \ No newline at end of file diff --git a/w9/ViewConstants.java b/w9/ViewConstants.java new file mode 100644 index 0000000..07541b9 --- /dev/null +++ b/w9/ViewConstants.java @@ -0,0 +1,9 @@ +/** + * 视图层常量(配置暗色主题) + */ +public class ViewConstants { + // 暗色主题:黑色背景(仅修改此常量完成暗色主题配置) + public static final String BACKGROUND_COLOR = "BLACK"; + // 文本颜色适配暗色主题 + public static final String TEXT_COLOR = "WHITE"; +} \ No newline at end of file diff --git a/w9/思考题.txt b/w9/思考题.txt new file mode 100644 index 0000000..70d54b9 --- /dev/null +++ b/w9/思考题.txt @@ -0,0 +1,5 @@ +List
共享引用的核心风险是多模块无控修改: +多个层(视图 / 控制层)持有同一 List 引用时,任意模块可直接修改集合(add/remove)或通过 Article 的 Setter 修改元素属性,破坏数据一致性(如视图层误删控制层待处理的文章)。 +其次是并发安全问题,无同步机制的共享 List 在多线程下会引发 ConcurrentModificationException,或脏读 / 脏写。 +此外,共享引用易导致内存泄漏,所有持有引用的模块会阻止 List 被 GC 回收。 +最后,该行为违背 MVC 分层原则:视图层仅负责展示,若直接操作共享 List,会模糊职责边界,破坏架构分层的可维护性和扩展性。 diff --git a/w9/运行输出.jpg b/w9/运行输出.jpg new file mode 100644 index 0000000..96edfcf Binary files /dev/null and b/w9/运行输出.jpg differ