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