12 changed files with 240 additions and 0 deletions
@ -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.迭代中校验职责边界,避免混淆。 |
||||
@ -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 + |
||||
|
'}'; |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
// 其他视图渲染逻辑
|
||||
|
} |
||||
|
} |
||||
@ -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 + " 成功"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 命令历史记录类(MVC-控制层辅助) |
||||
|
*/ |
||||
|
public class HistoryCommand { |
||||
|
// 私有化List,避免外部直接修改
|
||||
|
private static final List<String> commandList = new ArrayList<>(); |
||||
|
|
||||
|
// 新增命令记录
|
||||
|
public static void addCommand(String command) { |
||||
|
if (command != null && !command.trim().isEmpty()) { |
||||
|
commandList.add(command); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 获取所有命令记录(返回副本,避免外部修改原集合)
|
||||
|
public static List<String> getCommandList() { |
||||
|
return new ArrayList<>(commandList); |
||||
|
} |
||||
|
|
||||
|
// 清空命令记录
|
||||
|
public static void clearHistory() { |
||||
|
commandList.clear(); |
||||
|
} |
||||
|
} |
||||
@ -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<String> 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(); |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
/** |
||||
|
* 视图层常量(配置暗色主题) |
||||
|
*/ |
||||
|
public class ViewConstants { |
||||
|
// 暗色主题:黑色背景(仅修改此常量完成暗色主题配置)
|
||||
|
public static final String BACKGROUND_COLOR = "BLACK"; |
||||
|
// 文本颜色适配暗色主题
|
||||
|
public static final String TEXT_COLOR = "WHITE"; |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
List<Article> 共享引用的核心风险是多模块无控修改: |
||||
|
多个层(视图 / 控制层)持有同一 List 引用时,任意模块可直接修改集合(add/remove)或通过 Article 的 Setter 修改元素属性,破坏数据一致性(如视图层误删控制层待处理的文章)。 |
||||
|
其次是并发安全问题,无同步机制的共享 List 在多线程下会引发 ConcurrentModificationException,或脏读 / 脏写。 |
||||
|
此外,共享引用易导致内存泄漏,所有持有引用的模块会阻止 List 被 GC 回收。 |
||||
|
最后,该行为违背 MVC 分层原则:视图层仅负责展示,若直接操作共享 List,会模糊职责边界,破坏架构分层的可维护性和扩展性。 |
||||
|
After Width: | Height: | Size: 78 KiB |
Loading…
Reference in new issue