From e22e5303bdc817baebe294d2a1f384da7a165bf5 Mon Sep 17 00:00:00 2001 From: wangminjun <1203597864@qq.com> Date: Mon, 11 May 2026 11:58:32 +0800 Subject: [PATCH] 202506050218 --- w9/AI协助记录.txt | 3 + w9/java-cli/.gitignore | 4 + w9/java-cli/README.md | 17 + w9/java-cli/java-cli/.gitignore | 4 + w9/java-cli/java-cli/README.md | 17 + w9/java-cli/java-cli/pom.xml | 45 ++ .../java/com/example/datacollect/Main.java | 21 + .../example/datacollect/command/Command.java | 9 + .../datacollect/command/CrawlCommand.java | 27 + .../datacollect/command/ExitCommand.java | 24 + .../datacollect/command/HelpCommand.java | 23 + .../datacollect/command/HistoryCommand.java | 36 + .../datacollect/command/ListCommand.java | 23 + .../controller/CrawlerController.java | 47 ++ .../example/datacollect/model/Article.java | 45 ++ .../example/datacollect/view/ConsoleView.java | 42 + .../target/W9工程架构 - 教案v3.md | 758 ++++++++++++++++++ .../target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 0 w9/java-cli/java-cli/target/w9-ppt.md | 530 ++++++++++++ w9/java-cli/pom.xml | 45 ++ .../java/com/example/datacollect/Main.java | 21 + .../example/datacollect/command/Command.java | 9 + .../datacollect/command/CrawlCommand.java | 27 + .../datacollect/command/ExitCommand.java | 24 + .../datacollect/command/HelpCommand.java | 23 + .../datacollect/command/HistoryCommand.java | 36 + .../datacollect/command/ListCommand.java | 23 + .../controller/CrawlerController.java | 55 ++ .../example/datacollect/model/Article.java | 65 ++ .../example/datacollect/view/ConsoleView.java | 42 + .../target/W9工程架构 - 教案v3.md | 758 ++++++++++++++++++ .../target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 0 w9/java-cli/target/w9-ppt.md | 530 ++++++++++++ w9/程序运行截图.png | Bin 0 -> 378159 bytes w9/越权行为提问.txt | 6 + w9/选做/List共享引用风险.txt | 4 + w9/选做/java-cli/.gitignore | 4 + w9/选做/java-cli/README.md | 17 + w9/选做/java-cli/java-cli/.gitignore | 4 + w9/选做/java-cli/java-cli/README.md | 17 + w9/选做/java-cli/java-cli/pom.xml | 45 ++ .../java/com/example/datacollect/Main.java | 21 + .../example/datacollect/command/Command.java | 9 + .../datacollect/command/CrawlCommand.java | 27 + .../datacollect/command/ExitCommand.java | 24 + .../datacollect/command/HelpCommand.java | 23 + .../datacollect/command/HistoryCommand.java | 36 + .../datacollect/command/ListCommand.java | 23 + .../controller/CrawlerController.java | 47 ++ .../example/datacollect/model/Article.java | 45 ++ .../example/datacollect/view/ConsoleView.java | 42 + .../target/W9工程架构 - 教案v3.md | 758 ++++++++++++++++++ .../target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 0 w9/选做/java-cli/java-cli/target/w9-ppt.md | 530 ++++++++++++ w9/选做/java-cli/pom.xml | 45 ++ .../java/com/example/datacollect/Main.java | 21 + .../example/datacollect/command/Command.java | 9 + .../datacollect/command/CrawlCommand.java | 40 + .../datacollect/command/ExitCommand.java | 24 + .../datacollect/command/HelpCommand.java | 23 + .../datacollect/command/HistoryCommand.java | 36 + .../datacollect/command/ListCommand.java | 23 + .../controller/CrawlerController.java | 58 ++ .../example/datacollect/model/Article.java | 65 ++ .../example/datacollect/view/ConsoleView.java | 42 + .../target/W9工程架构 - 教案v3.md | 758 ++++++++++++++++++ .../target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 0 .../compile/default-compile/inputFiles.lst | 10 + w9/选做/java-cli/target/w9-ppt.md | 530 ++++++++++++ 73 files changed, 6719 insertions(+) create mode 100644 w9/AI协助记录.txt create mode 100644 w9/java-cli/.gitignore create mode 100644 w9/java-cli/README.md create mode 100644 w9/java-cli/java-cli/.gitignore create mode 100644 w9/java-cli/java-cli/README.md create mode 100644 w9/java-cli/java-cli/pom.xml create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java create mode 100644 w9/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java create mode 100644 w9/java-cli/java-cli/target/W9工程架构 - 教案v3.md create mode 100644 w9/java-cli/java-cli/target/maven-archiver/pom.properties create mode 100644 w9/java-cli/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 w9/java-cli/java-cli/target/w9-ppt.md create mode 100644 w9/java-cli/pom.xml create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/Main.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/command/Command.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/model/Article.java create mode 100644 w9/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java create mode 100644 w9/java-cli/target/W9工程架构 - 教案v3.md create mode 100644 w9/java-cli/target/maven-archiver/pom.properties create mode 100644 w9/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 w9/java-cli/target/w9-ppt.md create mode 100644 w9/程序运行截图.png create mode 100644 w9/越权行为提问.txt create mode 100644 w9/选做/List共享引用风险.txt create mode 100644 w9/选做/java-cli/.gitignore create mode 100644 w9/选做/java-cli/README.md create mode 100644 w9/选做/java-cli/java-cli/.gitignore create mode 100644 w9/选做/java-cli/java-cli/README.md create mode 100644 w9/选做/java-cli/java-cli/pom.xml create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java create mode 100644 w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java create mode 100644 w9/选做/java-cli/java-cli/target/W9工程架构 - 教案v3.md create mode 100644 w9/选做/java-cli/java-cli/target/maven-archiver/pom.properties create mode 100644 w9/选做/java-cli/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 w9/选做/java-cli/java-cli/target/w9-ppt.md create mode 100644 w9/选做/java-cli/pom.xml create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/Main.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/command/Command.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/model/Article.java create mode 100644 w9/选做/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java create mode 100644 w9/选做/java-cli/target/W9工程架构 - 教案v3.md create mode 100644 w9/选做/java-cli/target/maven-archiver/pom.properties create mode 100644 w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 w9/选做/java-cli/target/w9-ppt.md diff --git a/w9/AI协助记录.txt b/w9/AI协助记录.txt new file mode 100644 index 0000000..1795942 --- /dev/null +++ b/w9/AI协助记录.txt @@ -0,0 +1,3 @@ +1.利用AI了解所给代码的结构和功能,解释代码含义。 +2.让AI给出完善建议 +3.用AI检测MVC三层划分是否存在越权行为 \ No newline at end of file diff --git a/w9/java-cli/.gitignore b/w9/java-cli/.gitignore new file mode 100644 index 0000000..0ebcf1a --- /dev/null +++ b/w9/java-cli/.gitignore @@ -0,0 +1,4 @@ +*.jar +*.jar +*.class +*.log \ No newline at end of file diff --git a/w9/java-cli/README.md b/w9/java-cli/README.md new file mode 100644 index 0000000..3ea02ec --- /dev/null +++ b/w9/java-cli/README.md @@ -0,0 +1,17 @@ +# DataCollect 教学项目 — 最小可运行版本 + +这是一个最小可用的 Java CLI 演示工程,目标:打印帮助信息以验证运行环境。 + +构建: +```bash +mvn -q package +``` + +运行(示例): +```bash +java -jar target/datacollect-cli-0.1.0-jar-with-dependencies.jar --help +``` + +项目结构(最小): +- `src/main/java/com/example/datacollect/Main.java` — CLI 入口,打印帮助 +- `pom.xml` — Maven 构建配置,生成可执行 jar diff --git a/w9/java-cli/java-cli/.gitignore b/w9/java-cli/java-cli/.gitignore new file mode 100644 index 0000000..0ebcf1a --- /dev/null +++ b/w9/java-cli/java-cli/.gitignore @@ -0,0 +1,4 @@ +*.jar +*.jar +*.class +*.log \ No newline at end of file diff --git a/w9/java-cli/java-cli/README.md b/w9/java-cli/java-cli/README.md new file mode 100644 index 0000000..3ea02ec --- /dev/null +++ b/w9/java-cli/java-cli/README.md @@ -0,0 +1,17 @@ +# DataCollect 教学项目 — 最小可运行版本 + +这是一个最小可用的 Java CLI 演示工程,目标:打印帮助信息以验证运行环境。 + +构建: +```bash +mvn -q package +``` + +运行(示例): +```bash +java -jar target/datacollect-cli-0.1.0-jar-with-dependencies.jar --help +``` + +项目结构(最小): +- `src/main/java/com/example/datacollect/Main.java` — CLI 入口,打印帮助 +- `pom.xml` — Maven 构建配置,生成可执行 jar diff --git a/w9/java-cli/java-cli/pom.xml b/w9/java-cli/java-cli/pom.xml new file mode 100644 index 0000000..01bc611 --- /dev/null +++ b/w9/java-cli/java-cli/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + com.example + datacollect-cli + 0.1.0 + + 11 + 11 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + + com.example.datacollect.Main + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java new file mode 100644 index 0000000..44d00aa --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java @@ -0,0 +1,21 @@ +package com.example.datacollect; + +import com.example.datacollect.controller.CrawlerController; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class Main { + + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler (w9_1)! Type help for commands."); + while (true) { + controller.handle(view.readLine()); + } + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java new file mode 100644 index 0000000..24e59a6 --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java @@ -0,0 +1,9 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java new file mode 100644 index 0000000..45baea1 --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java @@ -0,0 +1,27 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class CrawlCommand implements Command { + private final ConsoleView view; + + public CrawlCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "crawl"; + } + + @Override + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: would crawl " + args[1]); + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java new file mode 100644 index 0000000..6946d85 --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java @@ -0,0 +1,24 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ExitCommand implements Command { + private final ConsoleView view; + + public ExitCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "exit"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java new file mode 100644 index 0000000..4fde32f --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HelpCommand implements Command { + private final ConsoleView view; + + public HelpCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "help"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java new file mode 100644 index 0000000..2b79929 --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java @@ -0,0 +1,36 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HistoryCommand implements Command { + private final ConsoleView view; + private final List history; + + public HistoryCommand(ConsoleView view, List history) { + this.view = view; + this.history = history; + } + + @Override + public String getName() { + return "history"; + } + + @Override + public void execute(String[] args, List
articles) { + if (history.isEmpty()) { + view.printInfo("No command history."); + return; + } + view.printInfo("Command history:"); + for (int i = 0; i < history.size(); i++) { + view.printInfo((i + 1) + ". " + history.get(i)); + } + } + + public void addCommand(String command) { + history.add(command); + } +} \ No newline at end of file diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java new file mode 100644 index 0000000..8eba2cd --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ListCommand implements Command { + private final ConsoleView view; + + public ListCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "list"; + } + + @Override + public void execute(String[] args, List
articles) { + view.display(articles); + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java new file mode 100644 index 0000000..ad03ef4 --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java @@ -0,0 +1,47 @@ +package com.example.datacollect.controller; + +import com.example.datacollect.command.Command; +import com.example.datacollect.command.CrawlCommand; +import com.example.datacollect.command.ExitCommand; +import com.example.datacollect.command.HelpCommand; +import com.example.datacollect.command.ListCommand; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private final Map commands = new HashMap<>(); + private final ConsoleView view; + private final List
articles; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + register(new HelpCommand(view)); + register(new ListCommand(view)); + register(new CrawlCommand(view)); + register(new ExitCommand(view)); + } + + private void register(Command command) { + commands.put(command.getName(), command); + } + + public void handle(String input) { + String text = input == null ? "" : input.trim(); + if (text.isEmpty()) { + return; + } + + String[] args = text.split("\\s+"); + String cmdName = args[0].toLowerCase(); + Command command = commands.get(cmdName); + if (command == null) { + view.printError("Unknown command: " + cmdName); + return; + } + command.execute(args, articles); + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java new file mode 100644 index 0000000..147dbe6 --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java @@ -0,0 +1,45 @@ +package com.example.datacollect.model; + +public class Article { + private String title; + private String url; + private String content; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public String toString() { + return "Article{" + + "title='" + title + '\'' + + ", url='" + url + '\'' + + '}'; + } +} diff --git a/w9/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java new file mode 100644 index 0000000..3c1d47a --- /dev/null +++ b/w9/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java @@ -0,0 +1,42 @@ +package com.example.datacollect.view; + +import com.example.datacollect.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_BLUE = "\u001B[34m"; + + private final Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("> "); + return scanner.nextLine(); + } + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + System.out.println(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + System.out.println(ANSI_BLUE + msg + ANSI_RESET); + } + + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("暂无文章,请先执行 crawl。"); + return; + } + for (int i = 0; i < articles.size(); i++) { + Article a = articles.get(i); + System.out.println((i + 1) + ". " + a.getTitle() + " | " + a.getUrl()); + } + } +} diff --git a/w9/java-cli/java-cli/target/W9工程架构 - 教案v3.md b/w9/java-cli/java-cli/target/W9工程架构 - 教案v3.md new file mode 100644 index 0000000..09de868 --- /dev/null +++ b/w9/java-cli/java-cli/target/W9工程架构 - 教案v3.md @@ -0,0 +1,758 @@ +--- + +# 教案:《高级程序设计》第9周——工程架构:从"写代码"到"造系统" + +| 项目 | 内容 | +|------|------| +| **课程名称** | 高级程序设计 | +| **周次** | 第9周 | +| **主题** | 工程架构——从"写代码"到"造系统" | +| **学时** | 2学时(90分钟) | +| **授课对象** | 具备Python基础、已完成Java面向对象特性学习的学生 | +| **教学环境** | JDK 17+、IntelliJ IDEA、Maven(模板) | +| **前情提要** | 本课程原计划使用JavaFX GUI,后根据教学反馈转向CLI + MVC + 爬虫工程化 | + +--- + +## 教学调整说明:为什么选择CLI而不是GUI? + +> **原计划**:JavaFX桌面应用 → **新计划**:CLI命令行应用 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **学生痛点** | "窗口点击"与后端能力无关 | 真正锻炼工程思维 | +| **AI辅助** | AI生成FXML,学生看不懂 | AI辅助重构架构 | +| **工程化** | 脱离真实后端开发场景 | 模拟真实服务器/大数据开发 | +| **核心转型** | "视觉装饰"优先 | "逻辑架构"优先 | + +**决策理由**: +1. **985学生需要的是工程思维**,不是拖控件 +2. **接口抽象**是弱项,CLI + MVC更能暴露这个问题 +3. **彩色终端**足够酷炫,且代码量可控 + +**更深层的教育价值**: +> 在GUI框架中,架构已被框架强制划定,学生只是"遵守规矩";而CLI世界里没有任何框架告诉你模型在哪、视图在哪——**当外部约束消失,内部的工程纪律才真正建立**。这正是本节课要传递的核心精神。 + +--- + +## 一、教学目标 + +| 目标维度 | 具体描述 | +|----------|----------| +| **知识掌握** | 理解MVC架构的职责划分及其演化脉络;掌握Maven项目结构与pom.xml基础;理解Command模式的路由原理。 | +| **工程实践** | 能搭建规范的Maven项目包结构;能实现基于Scanner的控制台交互;能用Command接口实现可扩展的命令路由;能识别架构中的"越权行为"。 | +| **思维转型** | 从"一个类写全部"转向"分层解耦";从"修改现有代码"转向"新增类实现功能";从"满足功能"转向"代码的工程洁癖"。 | +| **工具应用** | 利用AI辅助审查MVC职责越权;让AI扮演"架构审计师"检查分层是否清晰;理解AI生成代码中的架构缺陷。 | + +--- + +## 二、教学重点与难点 + +| 项目 | 内容 | 突破方法 | +|------|------|----------| +| **重点** | MVC三层职责划分、CLI交互实现、Command接口解耦、代码中的工程细节(常量、输出归属) | 以"新增命令需要改什么"为切入点,展示Command模式的优势;通过现场"代码找茬"强化细节意识 | +| **难点** | Controller不写业务逻辑、Command接口的多态实现、共享数据模型的设计缺陷识别 | 现场演示:增加一个命令只需新建类,无需修改Controller;暴露`List
`共享引用的问题并预告解决方案 | + +--- + +## 三、教学过程设计(90分钟) + +| 环节 | 时间 | 教学内容 | 师生活动 | AI协同点 | +|------|------|----------|----------|----------| +| **1. 痛点引入:从脚本到工程的鸿沟** | 10' | 展示"意大利面"式爬虫代码,演示改一处需要动全身 | **教师演示**:现场展示一段混乱代码,让学生找问题 | 用AI分析代码耦合度 | +| **2. CLI vs GUI:架构选择的思考** | 10' | 对比两种方案的优缺点,解释为什么CLI更适合培养工程思维 | **教师讲解**:用对比表格说明选择CLI的理由 | — | +| **3. MVC分层设计** | 20' | 讲解Model/View/Controller三层职责,用"餐厅类比"强化理解,随后批判类比局限性 | **教师讲解**:配合架构图讲解三层交互,引导学生寻找类比破绽 | 用AI生成MVC职责对照表 | +| **4. Command模式:可扩展的命令路由** | 15' | 引入Command接口,解释"一个命令就是一个类" | **类比**:Command像酒店的服务部门,Controller是前台 | 让AI解释Command模式的多态原理 | +| **5. Maven模板与环境** | 5' | 直接使用提供的Maven模板,讲解目录结构 | **教师演示**:解压模板 → IDEA打开 → 运行 | — | +| **6. 三层代码落地** | 20' | **Model**:Article实体
**View**:ConsoleView(ANSI常量)
**Command接口**+实现
**Controller**:Map路由 | **教师演示**:分步写出代码,刻意埋入1~2个"越权细节"让学生找茬 | 学生用AI做"架构审计" | +| **7. 架构反思与展望** | 5' | 指出当前`List
`共享引用的问题,预告W10策略模式与仓库层 | **师生互动**:你发现这个设计有什么风险? | 让AI分析共享可变状态的危害 | +| **8. 实践任务:空壳程序** | 5' | 搭建完整包结构,实现CLI循环 | 学生现场编码,教师巡视 | 完成后用AI检查包结构 | +| **9. 总结与过渡** | 5' | 本周实现了"骨架+命令可扩展",下周填入"灵魂"——解析器,并解决数据安全问题 | 总结Command模式优势,预告策略模式 | — | + +--- + +## 四、核心教学内容脚本 + +### 4.1 痛点引入:从脚本到工程的鸿沟(10分钟) + +**教师口播**: +> "同学们,前8周我们学的是Java语法,从变量到类,从继承到接口。但有一个问题:代码写完之后,怎么组织?" +> +> "来看这段代码——这是某个同学写的'爬虫',他一个人完成了一个'完整'的项目。" + +**展示"脚本式"代码**: +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +**提问引导**: +1. "如果我想把标题保存到文件,要改哪里?" +2. "如果我想支持另一个网站,它的HTML结构不一样,要怎么办?" +3. "如果我想让输出变成彩色,要改哪里?" + +**痛点提炼**: +> "看到了吗?才60行代码,已经'牵一发而动全身'了。这就是一个'脚本'的宿命——功能全混在一起,改一个小需求,整个文件都要翻。" +> +> "这周我们要解决:**怎么让代码'改起来不疼'?**" + +--- + +### 4.2 CLI vs GUI:架构选择的思考(10分钟) + +**教师口播**: +> "既然要写一个'完整'的爬虫应用,我们有两个选择:图形界面(GUI)或命令行界面(CLI)。为什么我推荐CLI而不是GUI?" + +**对比表格** + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **代码量** | FXML + Controller + CSS,大量模板代码 | 纯Java,代码量可控 | +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **后端能力** | 几乎无关 | 模拟真实服务器开发 | +| **可测试性** | 难(需要UI测试框架) | 易(直接测试Command类) | +| **工程思维** | 弱(关注视觉) | 强(关注逻辑) | + +**核心观点**: +> **CLI更需要MVC!** GUI有现成的事件系统(点击按钮→触发事件),而CLI只有字符流。**没有架构,分分钟写成脚本**。MVC在CLI里是"刚需",不是"装饰"。 +> +> **更深一层**:在GUI里,框架已经硬塞给你一套架构,你只是在填空;但在CLI里,所有结构都必须由你亲手搭建。**当外部约束消失,内部的工程纪律才真正开始建立**——这才是本节课的真正目的。 + +**CLI也能很酷**: +- ANSI彩色输出(红/绿/黄/蓝) +- 表格展示数据 +- 进度条动画 +- 模拟真实大数据开发场景 + +--- + +### 4.3 MVC分层设计(20分钟) + +#### 4.3.1 MVC的起源与演进 + +**教师口播**: +> "MVC不是新东西,它是1970年代为桌面应用设计的架构思想。但它的核心——'职责分离'——在任何软件里都适用。" + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +#### 4.3.2 从GUI到CLI的映射 + +| GUI组件 | CLI对应 | 说明 | +|--------|--------|------| +| 窗口/按钮 | 命令行输入 | **View = 用户交互** | +| 数据模型 | Article实体类 | **Model = 数据结构** | +| 事件监听 | Command路由 | **Controller = 调度** | + +#### 4.3.3 MVC三层职责 + +**架构图示**: + +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ - 接收命令(crawl, help, exit) │ +│ - 分发给对应的Command │ +│ 【口诀】:Controller不管"怎么做", │ +│ 只管"派给谁" │ +└─────────┬───────────────┬───────────────┘ + │ │ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ - 数据实体 │ │ - 输入解析 │ +│ - 业务逻辑 │ │ - 输出格式化 │ +│ 【口诀】: │ │ 【口诀】: │ +│ Model管"数据" │ │ View管"呈现" │ +└─────────────────┘ └─────────────────┘ +``` + +**三层职责详解** + +| 层级 | 职责 | 典型代码 | 禁止做什么 | +|------|------|----------|------------| +| **Model** | 数据结构 + 业务逻辑 | `class Article { String title; String content; }` | 不能有`System.out.println`,不能有`Scanner` | +| **View** | 接收用户输入 + 格式化输出 | `class ConsoleView { String readInput(); void print(String); }` | 不能写爬虫逻辑,只做"传声筒" | +| **Controller** | 协调调度 | `class CrawlerController { void handle(String cmd) { ... } }` | 不能直接写业务细节,委托给Command | + +#### 4.3.4 类比强化:"餐厅类比" + +> "把MVC想象成一家餐厅: +> - **Model是后厨**:只管做菜(数据加工),不管谁来吃、怎么端 +> - **View是服务员**:只管端菜和收钱(输入输出),不管菜怎么做 +> - **Controller是前台**:只管把顾客的点单传给后厨,把做好的菜端给顾客 +> +> 如果后厨开始管'谁来吃饭',这餐厅就乱了。" + +#### 4.3.5 对"餐厅类比"的批判性思考(关键!) + +**教师导引**: +> "刚才的类比好理解吗?很好。但任何一个类比都有它的边界,如果把它当成真理,就会出问题。现在我们来给这个类比'找茬'。" + +**提问学生**: +1. "后厨真的完全不知道客人是谁吗?如果客人有忌口(比如不吃香菜),这个信息需不需要传到后厨?" +2. "服务员只是端菜吗?在真实餐厅里,服务员经常向后厨反馈'客人觉得今天的菜咸了',这属于View→Model的反向影响吗?" +3. "在这个类比里,我们把前台(Controller)和后厨(Model)的关系说成单向的。但实际上,后厨做完了菜,需要通知前台'菜好了',这不就是**观察者模式**吗?" + +**点明本质**: +> "实际MVC的数据流向常常是**双向**的:Controller调用Model的方法改变数据,Model变化后又通知View更新显示。只不过在本次CLI项目中,我们暂时使用'请求-响应'的单向简化模型——用户输入命令,系统处理,然后立即输出结果。这个简化版够用,但你要知道完整的MVC是更动态的。随着系统复杂,Model层需要一个专门的'仓库类'来管理数据,并通知视图刷新——这正是W10我们将要深入的内容。" + +#### 4.3.6 MVC的数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,目前暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +### 4.4 Command模式:可扩展的命令路由(15分钟) + +**教师口播**: +> "现在引入一个设计模式——Command(命令)模式。它的核心思想是:**一个命令就是一个类**。" + +#### 4.4.1 为什么需要Command模式? + +**演示:增加一个命令的代价(switch-case版)** +```java +// 现状代码 +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +**提问**: +- "如果我想增加10个命令,这个类要改多少次?" +- "如果我不小心删了一个case,整个程序还能跑吗?" + +**痛点提炼**: +> "每加一个功能,就要在这个类里戳一个洞。**这就是'肥控制器'陷阱**——所有的逻辑都堆在Controller里,它变成了新的'意大利面'。" + +#### 4.4.2 Command模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| **Command接口** | 抽象的"订单" | `Command` 接口 | +| **ConcreteCommand** | 具体的订单 | `HelpCommand`、`CrawlCommand` | +| **Invoker** | 接单的前台 | `CrawlerController` | +| **Receiver** | 执行者 | `ConsoleView`、`ArticleRepository` | + +#### 4.4.3 Command接口定义 + +```java +// src/main/java/com/crawler/command/Command.java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); // 命令名,如 "crawl" + void execute(String[] args, List
articles); // 执行逻辑 +} +``` + +#### 4.4.4 Controller的变革(从switch到Map) + +```java +// 修改后的Controller +public class CrawlerController { + private Map commands; // 用Map存命令 + private ConsoleView view; // 持有View以输出错误 + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.commands = new HashMap<>(); + // 增加命令无需改Controller代码,只需在这里注册 + commands.put("crawl", new CrawlCommand(view)); + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmd = parts[0].toLowerCase(); + + Command command = commands.get(cmd); + if (command == null) { + view.printError("Unknown command: " + cmd); // 通过View输出,而非直接System.out + return; + } + + // 执行命令,传入参数和文章列表 + command.execute(parts, articles); + } +} +``` + +**对比表格** + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改Controller | 新建一个类 | +| 多态体验 | 无 | execute()的多态调用 | +| 可测试性 | 难 | 每个Command可单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +**类比强化**: +> "Command模式就像**酒店的客房服务**:每个服务(清理、送餐、按摩)都是一个独立的部门。前台(Controller)只负责接电话,然后把请求'派发'给对应的部门。部门自己知道怎么干活,不需要前台教。" +> +> "如果想新增一个服务,前台只需要'登记'一下,不需要把现有部门重新装修。" + +--- + +### 4.5 Maven模板与环境(5分钟) + +**教师口播**: +> "这周我们不发愁pom.xml配置。我已经把 Maven 模板准备好了,你们只需要解压、打开、运行。" + +**模板使用流程**: +``` +1. 解压 [my-crawler-template.zip] +2. 用 IDEA 打开文件夹 +3. 右键 pom.xml → Maven → Reload Project +4. 运行 App.java +``` + +**标准目录结构**: +``` +src/main/java/com/crawler/ +├── model/ +│ └── Article.java +├── view/ +│ └── ConsoleView.java +├── command/ +│ ├── Command.java (接口) +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/ + └── CrawlerController.java +``` + +--- + +### 4.6 代码落地(20分钟) + +#### 4.6.1 Model层:Article实体 + +```java +// src/main/java/com/crawler/model/Article.java +package com.crawler.model; + +public class Article { + private String title; + private String url; + private String content; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { return title; } + public void setTitle(String title) { this.title = title; } + public String getUrl() { return url; } + public void setUrl(String url) { this.url = url; } + public String getContent() { return content; } + public void setContent(String content) { this.content = content; } + + @Override + public String toString() { + return "Article{title='" + title + "', url='" + url + "'}"; + } +} +``` + +#### 4.6.2 View层:ANSI常量集中管理(工程细节!) + +```java +// src/main/java/com/crawler/view/ConsoleView.java +package com.crawler.view; + +import com.crawler.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + // ANSI颜色常量——集中管理,避免散落各处 + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + private static final String ANSI_CYAN = "\033[36m"; + private static final String ANSI_RESET = "\033[0m"; + + private Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("crawler> "); + return scanner.nextLine().trim(); + } + + public void print(String msg) { + System.out.println(msg); + } + + public void printSuccess(String msg) { + print(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + print(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + print(ANSI_CYAN + msg + ANSI_RESET); + } + + // 展示文章列表 + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("No articles yet. Use 'crawl ' first."); + return; + } + print("+----------+--------------------------------+"); + print("| Title | URL |"); + print("+----------+--------------------------------+"); + for (Article a : articles) { + String title = a.getTitle(); + if (title.length() > 10) title = title.substring(0, 10) + ".."; + String url = a.getUrl(); + if (url.length() > 30) url = url.substring(0, 27) + "..."; + print("| " + String.format("%-10s", title) + " | " + url + " |"); + } + print("+----------+--------------------------------+"); + printInfo("Total: " + articles.size() + " articles"); + } +} +``` + +**教师提示**: +> "注意:所有ANSI转义码都被定义为`private static final`常量。如果把`\033[32m`散落在项目各处,一旦想调整颜色,就得满世界去改——这正是我们之前痛批的'意大利面'。**这就是工程细节**。" + +#### 4.6.3 Command接口与四个实现(全部通过View输出) + +```java +// Command.java +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} + +// HelpCommand.java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} + +// ListCommand.java +public class ListCommand implements Command { + private ConsoleView view; + public ListCommand(ConsoleView v) { this.view = v; } + public String getName() { return "list"; } + public void execute(String[] args, List
articles) { + view.display(articles); + } +} + +// CrawlCommand.java (存根) +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} + +// ExitCommand.java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); // 全部输出都通过View,绝不让System.out直接出现在这里 + System.exit(0); + } +} +``` + +**故意埋设的"找茬点"**: +> "我在刚才的代码里有没有隐藏违反MVC原则的地方?`CrawlCommand`的存根里,`view.printInfo("Stub: Would crawl " + args[1]);` —— 这个字符串拼接算是"业务逻辑"吗?留给大家用AI架构审计时讨论。 + +#### 4.6.4 Controller:Map路由(全部通过View输出) + +```java +// src/main/java/com/crawler/controller/CrawlerController.java +package com.crawler.controller; + +import com.crawler.command.*; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private Map commands = new HashMap<>(); + private ConsoleView view; // 持有View + private List
articles; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmdName = parts[0].toLowerCase(); + + Command cmd = commands.get(cmdName); + if (cmd == null) { + view.printError("Unknown command: " + cmdName); // 错误信息也走View! + return; + } + cmd.execute(parts, articles); + } +} +``` + +#### 4.6.5 main方法:组装 + +```java +// src/main/java/com/crawler/App.java +package com.crawler; + +import com.crawler.controller.CrawlerController; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class App { + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler!"); + view.printInfo("Type 'help' for commands."); + + while (true) { + controller.handle(view.readLine()); + } + } +} +``` + +#### 4.6.6 架构反思与展望:共享List
的隐患(关键!) + +**教师口播**: +> "现在这个架构已经可用了。但请大家审视一下:我们所有的Command都直接拿到了`List
`的引用。换句话说,任何一个命令都可以随意增、删、改这个列表。" +> +> "这就好像一家酒店,所有服务员、厨师、清洁工都能随意进出保险箱——**数据结构完全裸奔了**。" + +**提问**: +- "如果CrawlCommand不小心写错了代码,把一个null塞进articles,HelpCommand会不会受影响?" +- "如果未来我们要在添加文章时也写入日志文件,现在的设计能优雅实现吗?还是得在所有Command里分别加日志代码?" + +**预告解决方案**: +> "下周,我们将引入**策略模式**和一个真正的**Model仓库层(ArticleRepository)**。这个仓库会把`List`封装起来,对外只提供`add()`、`getAll()`等安全接口。任何命令想修改数据,都必须通过仓库。这就是从'数据结构'到'模型层'的进化——我们W9先搭骨架,W10给它装上盔甲。" + +--- + +### 4.7 实践任务(5分钟) + +**任务要求**: +1. 使用Maven模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现4个Command:help/list/crawl/exit +4. `list`命令能展示已抓取的文章 +5. 运行并测试循环 +6. **代码找茬(额外加分)**:找出你自己代码中是否存在`System.out`直接调用、硬编码ANSI字符串等"越权行为" + +**验收标准**: +- [x] Maven编译通过 +- [x] Command接口和4个实现分离在不同文件 +- [x] Controller里没有switch-case +- [x] 新增命令只需新建类,不改Controller +- [x] list命令能正确显示空列表 +- [x] 所有输出均通过ConsoleView完成,无直接System.out.println(main除外) +- [x] ANSI颜色码集中定义为View常量 + +--- + +## 五、课后作业 + +### 5.1 必做任务 + +1. **完善Article**:增加`author`、`publishDate`字段 +2. **★ HistoryCommand(强制作业)**: + - 实现`history`命令,记录用户输入过的所有命令 + - 使用`List`存储历史(复习W8集合) + - 示例输出: + ``` + crawler> history + 1. help + 2. list + 3. crawl https://example.com + ``` +3. **AI架构审计**:将类名和方法名发给AI,指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?Model层是否包含输入输出代码?View层是否越权写了业务逻辑?有没有地方直接使用了System.out或硬编码ANSI码?" + +### 5.2 选做任务 + +1. **命令别名**:给`crawl`增加别名`c`,`help`增加别名`h` +2. **URL验证**:检查URL格式是否以http://或https://开头 +3. **暗色主题**:实现不同的配色方案(利用View中的ANSI常量,只需修改一处即可) +4. **思考并回答**:分析`List
`共享引用的潜在风险,写一段200字的小结 + +### 5.3 思考题 + +1. **Command vs switch-case**:增加10个命令,哪种方式代码改动量更小? +2. **如果不用Command接口,直接用Map存命令类行不行?** 接口的意义是什么? +3. **Controller里的`commands.put()`能否减少?** 提示:思考"注册机制" +4. **为什么ExitCommand里的`view.printSuccess("Bye!")`比直接`System.out.println`更"MVC"?** 提示:回忆View的职责 + +--- + +## 六、AI协同升级 + +### 架构审计师任务(必做) + +**学生执行步骤**: +1. 列出项目中所有类名(不含方法实现) +2. 将类名列表发给AI +3. 输入指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否清晰。Model层是否包含了不应该有的代码(Scanner/System.out)?View层是否越权写了业务逻辑?请指出任何一处直接使用System.out.println的地方,并建议如何改正。" + +**预期AI输出**: +- 指出哪一层有越权行为 +- 建议如何整改 +- 评价整体架构健康度 + +### 进阶AI探究(选做) + +> "假设我的Command接口中execute方法接收了一个`List
`参数,请分析这种设计在工程上有什么隐患,并给出重构建议。" + +--- + +## 七、教学反思与调整记录 + +| 日期 | 事项 | 调整内容 | +|------|------|----------| +| 2026-04-28 | 首次编写 | 基于CLI+MVC重构 | +| 2026-04-30 | 教授反馈 | 引入Command模式、提供Maven模板、升级AI协同比 | +| 2026-04-30 | 逻辑重排 | 按"问题→选择→架构→模式"顺序重写 | +| 2026-05-01 | v2 vs V3合并 | 融合深度改进:增加教育哲学、批判性思考、ANSI常量、共享List隐患、故意埋坑 | + +--- + +## 附录1:Maven模板说明 + +> 老师提供`my-crawler-template.zip`压缩包,包含: +> - pom.xml(含Jsoup依赖) +> - 空的src/main/java结构 +> - .gitignore + +## 附录2:常见问题速查 + +| 问题 | 解答 | +|------|------| +| IDEA不识别pom.xml | 右键 pom.xml → Maven → Reload Project | +| 中文乱码 | Settings → Editor → File Encodings → UTF-8 | +| 包名大小写 | 包名全小写,类名首字母大写 | +| Command找不到 | 检查是否 implements Command,是否 @Override getName() | +| 命令不生效 | 检查 commands.put() 是否注册了该命令 | +| 输出颜色乱码 | IDEA控制台需支持ANSI,Windows下建议使用Windows Terminal或调整设置 | +| 我的System.out为什么被老师说越权 | View层才是与用户交互的唯一出口,所有输出都应通过View,这样将来改成GUI或日志时只需改View | + +## 附录3:教学逻辑说明 + +| 顺序 | 内容 | 设计理由 | +|------|------|----------| +| 1 | 痛点引入 | 从问题出发,让学生感受"为什么需要架构" | +| 2 | CLI vs GUI | 解释技术选型,建立"工程思维 > 视觉装饰"的认知 | +| 3 | MVC分层 | 核心架构概念,理解职责分离,通过类比及批判加深理解 | +| 4 | Command模式 | 具体实现方式,解决"肥控制器"问题 | +| 5 | Maven | 工具链支持 | +| 6 | 代码落地 | 实践验证,刻意植入细节规范,训练工程洁癖 | +| 7 | 架构反思 | 暴露共享可变状态隐患,为W10策略模式+仓库层做铺垫 | +| 8 | 实践任务 | 现场编码验证 | +| 9 | 总结 | 强化认知,预告下周 | + +--- + +## 版本说明 + +- **v1**:首次编写,CLI+MVC基础框架 +- **v2**:按"问题→选择→架构→模式"逻辑重排 +- **v3 (本版)**:融合v2结构 + V3深度改进,包含: + - 更深的CLI教育哲学 + - 餐厅类比批判性思考 + - ANSI常量集中管理工程细节 + - 全部输出走View + - 共享List架构隐患反思 + - 故意埋坑让学生找茬 + - W10铺垫(策略模式+仓库层) \ No newline at end of file diff --git a/w9/java-cli/java-cli/target/maven-archiver/pom.properties b/w9/java-cli/java-cli/target/maven-archiver/pom.properties new file mode 100644 index 0000000..08a8f9f --- /dev/null +++ b/w9/java-cli/java-cli/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 30 11:50:54 CST 2026 +artifactId=datacollect-cli +groupId=com.example +version=0.1.0 diff --git a/w9/java-cli/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/w9/java-cli/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/w9/java-cli/java-cli/target/w9-ppt.md b/w9/java-cli/java-cli/target/w9-ppt.md new file mode 100644 index 0000000..5ddd5ad --- /dev/null +++ b/w9/java-cli/java-cli/target/w9-ppt.md @@ -0,0 +1,530 @@ +## 高级程序设计 · 第9周 + +#### 工程架构:从"写代码"到"造系统" + +##### CLI + MVC + Command模式实战 + +--- + +### 📌 本周导航 + +- 痛点引入:脚本的宿命 +- CLI vs GUI:为什么选命令行? +- MVC分层:职责分离的艺术 +- Command模式:可扩展的路由 +- Maven模板:工程化第一步 +- 代码落地:从接口到实现 +- 架构反思:共享数据的隐患 +- 实践任务 + 课后作业 + +--- + +### 1️⃣ 痛点引入:从脚本到工程的鸿沟 + +#### 这是一段“意大利面”爬虫 + +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +--- + +### 脚本的三大痛点 + +| 需求 | 需要改哪里? | +|------|--------------| +| 保存标题到文件 | 改 main 内部逻辑 | +| 支持不同网站结构 | 全部重写解析代码 | +| 彩色输出 | 一个一个改 print | + +> 😫 **牵一发而动全身 → 改起来疼** + +### 本周目标:**让代码“改起来不疼”** + +--- + +## 2️⃣ CLI vs GUI:架构选择的思考 + +### 图形界面 vs 命令行 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| 学习重心 | 布局、控件、事件 | **架构、分层、路由** | +| 后端能力 | 弱 | 模拟真实服务器 | +| 工程思维 | 弱(关注视觉) | **强(关注逻辑)** | +| 可测试性 | 难 | 易 | + +--- + +## 核心观点 + +> **CLI 更需要 MVC!** + +- GUI 有现成事件系统,框架强塞给你一套架构 +- CLI 只有字符流 → **没有架构,分分钟写成脚本** + +> 🎯 **当外部约束消失,内部的工程纪律才真正开始建立** + +### CLI 也能很酷 + +- ANSI 彩色输出 +- 表格展示数据 +- 模拟大数据/后端开发 + +--- + +## 3️⃣ MVC 分层设计 + +### MVC 的起源与演进 + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +**核心不变:职责分离** + +--- + +## MVC 三层职责 + +![[mvc.png]] +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ 只管"派给谁",不管"怎么做" │ +└─────────┬───────────────┬───────────────┘ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ 管"数据" │ │ 管"呈现" │ +│ + 业务逻辑 │ │ + 输入输出 │ +└─────────────────┘ └─────────────────┘ +``` + +--- + +## 三层“禁止做什么” + +| 层级 | 禁止行为 | +| -------------- | -------------------------------------- | +| **Model** | 不能有 `System.out.println`,不能有 `Scanner` | +| **View** | 不能写爬虫逻辑,只做“传声筒” | +| **Controller** | 不能直接写业务细节,委托给 Command | + +> 🔴 **越权就是架构腐败的开始** + +--- + +## 🍽️ 餐厅类比(帮助理解) + +- **Model = 后厨**:只管做菜,不管谁来吃、怎么端 +- **View = 服务员**:只管端菜和收钱,不管菜怎么做 +- **Controller = 前台**:接单 → 派给后厨 → 叫服务员上菜 + +--- + +## 🤔 对类比的批判性思考(关键!) + +> 任何类比都有边界,不要当成真理 + +| 场景 | 暴露的问题 | +|------|------------| +| 客人有忌口(不吃香菜) | 信息需要传到后厨 → Model 可能需要知道 meta 信息 | +| 服务员反馈“今天的菜咸了” | View → Model 反向影响 | +| 后厨做完菜通知前台 | **观察者模式**,数据流可能是双向的 | + +**本课程简化模型**:请求-响应,单向流 + +--- + +## MVC 数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +## 4️⃣ Command 模式:可扩展的命令路由 + +### 为什么需要 Command 模式? + +```java +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +> 每加一个功能,就要在这个类里戳一个洞 → **肥控制器陷阱** + +--- + +## Command 模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| Command接口 | 抽象的“订单” | `Command` | +| ConcreteCommand | 具体的订单 | `HelpCommand` | +| Invoker | 接单的前台 | `CrawlerController` | +| Receiver | 执行者 | `ConsoleView`、`ArticleRepository` | + +--- + +## Command 接口定义 + +```java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} +``` + +--- + +## Controller 的变革:从 switch 到 Map + +```java +public class CrawlerController { + private Map commands = new HashMap<>(); + + public CrawlerController(ConsoleView view, List
articles) { + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + // 解析命令 → 从 Map 取 Command → 调用 execute + } +} +``` + +> **增加新命令:只需新建类,Controller 零改动!** + +--- + +## 对比:switch-case vs Command + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改 Controller | 新建一个类 | +| 多态体验 | 无 | `execute()` 多态 | +| 可测试性 | 难 | 每个 Command 单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +> 🏨 **类比:酒店客房服务,前台只负责派单** + +--- + +## 5️⃣ Maven 模板与环境(5分钟) + +### 直接使用模板,不折腾配置 + +``` +my-crawler-template.zip + ↓ 解压 + IDEA打开 + ↓ 右键 pom.xml → Maven → Reload Project + ↓ 运行 App.java +``` + +### 标准目录结构 + +``` +src/main/java/com/crawler/ +├── model/Article.java +├── view/ConsoleView.java +├── command/ +│ ├── Command.java +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/CrawlerController.java +``` + +--- + +## 6️⃣ 代码落地(分步实现) + +### Model:Article 实体 + +```java +public class Article { + private String title; + private String url; + private String content; + // 构造器、getter/setter、toString +} +``` + +> 📦 只存放数据,没有任何输入输出代码 + +--- + +## View:ConsoleView(ANSI常量集中管理) + +```java +public class ConsoleView { + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + // ... 其他常量 + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + public void printError(String msg) { ... } + public void display(List
articles) { ... } +} +``` + +> ✨ **所有颜色码集中定义 → 改主题只需改一处** + +--- + +## Command 实现示例(HelpCommand) + +```java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} +``` + +> ⚠️ 全部输出通过 `view`,绝不让 `System.out` 直接出现在这里 + +--- + +## CrawlCommand(存根,下周填坑) + +```java +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} +``` + +> 🔍 **找茬点**:这里拼接字符串算是“业务逻辑”吗?留给大家用 AI 审计。 + +--- + +## ExitCommand + +```java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} +``` + +> ✅ 所有输出都通过 View → 将来改 GUI 只需换 View 实现 + +--- + +## Controller + main 组装 + +```java +// Controller 中持有 Map +// App.java 中: +ConsoleView view = new ConsoleView(); +List
articles = new ArrayList<>(); +CrawlerController controller = new CrawlerController(view, articles); +view.printSuccess("Welcome to CLI Crawler!"); +while (true) { + controller.handle(view.readLine()); +} +``` + +> 🔁 完成交互循环 + +--- + +## 7️⃣ 架构反思:共享 List
的隐患 + +### 当前问题 + +- 所有 Command 都直接拿到 `List
` 引用 +- 任何一个命令都可以随意增、删、改列表 +- 数据完全“裸奔” + +> 🚨 就像酒店所有员工都能进保险箱 + +--- + +## 提问 + +- 如果 `CrawlCommand` 不小心把 `null` 塞进列表,`ListCommand` 会怎样? +- 如果我们要在添加文章时写日志,现在的设计能优雅实现吗? + +### 预告解决方案(W10) + +- **策略模式** + **仓库层(ArticleRepository)** +- 封装 `List`,对外只暴露 `add()`、`getAll()` 等安全接口 + +> W9 搭骨架,W10 装上盔甲 + +--- + +## 8️⃣ 实践任务(现场5分钟) + +### 必做项 + +1. 使用 Maven 模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现 4 个 Command:help / list / crawl / exit +4. `list` 能展示已抓取的文章(目前存根即可) +5. 运行并测试循环 + +### 额外加分:代码找茬 + +- 检查是否仍有 `System.out` 直接调用 +- 检查 ANSI 码是否硬编码在多个地方 + +--- + +## 验收标准 + +- [x] Maven 编译通过 +- [x] Command 接口和 4 个实现在不同文件 +- [x] Controller 里没有 switch-case +- [x] 新增命令只需新建类,不改 Controller +- [x] list 能正确显示空列表 +- [x] 所有输出均通过 `ConsoleView` +- [x] ANSI 颜色码集中定义为常量 + +--- + +## 9️⃣ 课后作业 + +### 必做 + +1. **完善 Article**:增加 `author`、`publishDate` 字段 +2. **★ HistoryCommand**:记录用户输入过的所有命令(用 `List`) +3. **AI 架构审计**:将类名发给 AI,指令: + > “作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?” + +### 选做 + +- 命令别名(c 代替 crawl) +- URL 格式验证 +- 暗色主题(修改一处常量) +- 思考题:分析 `List
` 共享引用的风险(200字小结) + +--- + +## 🤖 AI 协同升级 + +### 架构审计师任务(必做) + +**步骤**: +1. 列出所有类名(不含方法实现) +2. 发给 AI +3. 指令:“检查 MVC 分层是否清晰,是否有越权行为” + +### 进阶探究(选做) + +> “假设我的 Command 接口中 execute 方法接收了一个 `List
` 参数,请分析这种设计在工程上有什么隐患,并给出重构建议。” + +--- + +## 📚 总结与过渡 + +### 本周成果 + +- ✅ 工程化包结构 +- ✅ MVC 分层清晰 +- ✅ Command 模式实现可扩展路由 +- ✅ 所有输出走 View,常量集中管理 + +### 下周预告 + +- **策略模式**:封装爬取算法 +- **仓库层(Repository)**:武装 `List
`,解决共享隐患 + +> 🚀 从“写代码”到“造系统”,踏出坚实第一步! + +--- + +## Q&A + +### 常见问题 + +| 问题 | 解答 | +|------|------| +| IDEA 不识别 pom.xml | 右键 → Maven → Reload Project | +| 中文乱码 | Settings → File Encodings → UTF-8 | +| 输出颜色乱码 | Windows 建议使用 Windows Terminal | +| 我的 System.out 被批评 | View 才是唯一输出出口 | + +--- + +## 谢谢! + +### 课件已上传,模板在课程群 + +**保持工程洁癖,下周见!** \ No newline at end of file diff --git a/w9/java-cli/pom.xml b/w9/java-cli/pom.xml new file mode 100644 index 0000000..01bc611 --- /dev/null +++ b/w9/java-cli/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + com.example + datacollect-cli + 0.1.0 + + 11 + 11 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + + com.example.datacollect.Main + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + diff --git a/w9/java-cli/src/main/java/com/example/datacollect/Main.java b/w9/java-cli/src/main/java/com/example/datacollect/Main.java new file mode 100644 index 0000000..44d00aa --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/Main.java @@ -0,0 +1,21 @@ +package com.example.datacollect; + +import com.example.datacollect.controller.CrawlerController; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class Main { + + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler (w9_1)! Type help for commands."); + while (true) { + controller.handle(view.readLine()); + } + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/command/Command.java b/w9/java-cli/src/main/java/com/example/datacollect/command/Command.java new file mode 100644 index 0000000..24e59a6 --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/command/Command.java @@ -0,0 +1,9 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java b/w9/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java new file mode 100644 index 0000000..45baea1 --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java @@ -0,0 +1,27 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class CrawlCommand implements Command { + private final ConsoleView view; + + public CrawlCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "crawl"; + } + + @Override + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: would crawl " + args[1]); + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java b/w9/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java new file mode 100644 index 0000000..6946d85 --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java @@ -0,0 +1,24 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ExitCommand implements Command { + private final ConsoleView view; + + public ExitCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "exit"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java b/w9/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java new file mode 100644 index 0000000..a657f70 --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HelpCommand implements Command { + private final ConsoleView view; + + public HelpCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "help"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit, history"); + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java b/w9/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java new file mode 100644 index 0000000..2b79929 --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java @@ -0,0 +1,36 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HistoryCommand implements Command { + private final ConsoleView view; + private final List history; + + public HistoryCommand(ConsoleView view, List history) { + this.view = view; + this.history = history; + } + + @Override + public String getName() { + return "history"; + } + + @Override + public void execute(String[] args, List
articles) { + if (history.isEmpty()) { + view.printInfo("No command history."); + return; + } + view.printInfo("Command history:"); + for (int i = 0; i < history.size(); i++) { + view.printInfo((i + 1) + ". " + history.get(i)); + } + } + + public void addCommand(String command) { + history.add(command); + } +} \ No newline at end of file diff --git a/w9/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java b/w9/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java new file mode 100644 index 0000000..8eba2cd --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ListCommand implements Command { + private final ConsoleView view; + + public ListCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "list"; + } + + @Override + public void execute(String[] args, List
articles) { + view.display(articles); + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java b/w9/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java new file mode 100644 index 0000000..f73e4f6 --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java @@ -0,0 +1,55 @@ +package com.example.datacollect.controller; + +import com.example.datacollect.command.Command; +import com.example.datacollect.command.CrawlCommand; +import com.example.datacollect.command.ExitCommand; +import com.example.datacollect.command.HelpCommand; +import com.example.datacollect.command.HistoryCommand; +import com.example.datacollect.command.ListCommand; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private final Map commands = new HashMap<>(); + private final ConsoleView view; + private final List
articles; + private final List commandHistory = new ArrayList<>(); + private HistoryCommand historyCommand; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + historyCommand = new HistoryCommand(view, commandHistory); + register(new HelpCommand(view)); + register(new ListCommand(view)); + register(new CrawlCommand(view)); + register(new ExitCommand(view)); + register(historyCommand); + } + + private void register(Command command) { + commands.put(command.getName(), command); + } + + public void handle(String input) { + String text = input == null ? "" : input.trim(); + if (text.isEmpty()) { + return; + } + + historyCommand.addCommand(text); + + String[] args = text.split("\\s+"); + String cmdName = args[0].toLowerCase(); + Command command = commands.get(cmdName); + if (command == null) { + view.printError("Unknown command: " + cmdName); + return; + } + command.execute(args, articles); + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/model/Article.java b/w9/java-cli/src/main/java/com/example/datacollect/model/Article.java new file mode 100644 index 0000000..a19e3ed --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/model/Article.java @@ -0,0 +1,65 @@ +package com.example.datacollect.model; + +public class Article { + private String title; + private String url; + private String content; + private String author; + private String publishDate; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + 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 String getPublishDate() { + return publishDate; + } + + public void setPublishDate(String publishDate) { + this.publishDate = publishDate; + } + + @Override + public String toString() { + return "Article{" + + "title='" + title + '\'' + + ", url='" + url + '\'' + + ", author='" + author + '\'' + + ", publishDate='" + publishDate + '\'' + + '}'; + } +} diff --git a/w9/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java b/w9/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java new file mode 100644 index 0000000..3c1d47a --- /dev/null +++ b/w9/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java @@ -0,0 +1,42 @@ +package com.example.datacollect.view; + +import com.example.datacollect.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_BLUE = "\u001B[34m"; + + private final Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("> "); + return scanner.nextLine(); + } + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + System.out.println(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + System.out.println(ANSI_BLUE + msg + ANSI_RESET); + } + + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("暂无文章,请先执行 crawl。"); + return; + } + for (int i = 0; i < articles.size(); i++) { + Article a = articles.get(i); + System.out.println((i + 1) + ". " + a.getTitle() + " | " + a.getUrl()); + } + } +} diff --git a/w9/java-cli/target/W9工程架构 - 教案v3.md b/w9/java-cli/target/W9工程架构 - 教案v3.md new file mode 100644 index 0000000..09de868 --- /dev/null +++ b/w9/java-cli/target/W9工程架构 - 教案v3.md @@ -0,0 +1,758 @@ +--- + +# 教案:《高级程序设计》第9周——工程架构:从"写代码"到"造系统" + +| 项目 | 内容 | +|------|------| +| **课程名称** | 高级程序设计 | +| **周次** | 第9周 | +| **主题** | 工程架构——从"写代码"到"造系统" | +| **学时** | 2学时(90分钟) | +| **授课对象** | 具备Python基础、已完成Java面向对象特性学习的学生 | +| **教学环境** | JDK 17+、IntelliJ IDEA、Maven(模板) | +| **前情提要** | 本课程原计划使用JavaFX GUI,后根据教学反馈转向CLI + MVC + 爬虫工程化 | + +--- + +## 教学调整说明:为什么选择CLI而不是GUI? + +> **原计划**:JavaFX桌面应用 → **新计划**:CLI命令行应用 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **学生痛点** | "窗口点击"与后端能力无关 | 真正锻炼工程思维 | +| **AI辅助** | AI生成FXML,学生看不懂 | AI辅助重构架构 | +| **工程化** | 脱离真实后端开发场景 | 模拟真实服务器/大数据开发 | +| **核心转型** | "视觉装饰"优先 | "逻辑架构"优先 | + +**决策理由**: +1. **985学生需要的是工程思维**,不是拖控件 +2. **接口抽象**是弱项,CLI + MVC更能暴露这个问题 +3. **彩色终端**足够酷炫,且代码量可控 + +**更深层的教育价值**: +> 在GUI框架中,架构已被框架强制划定,学生只是"遵守规矩";而CLI世界里没有任何框架告诉你模型在哪、视图在哪——**当外部约束消失,内部的工程纪律才真正建立**。这正是本节课要传递的核心精神。 + +--- + +## 一、教学目标 + +| 目标维度 | 具体描述 | +|----------|----------| +| **知识掌握** | 理解MVC架构的职责划分及其演化脉络;掌握Maven项目结构与pom.xml基础;理解Command模式的路由原理。 | +| **工程实践** | 能搭建规范的Maven项目包结构;能实现基于Scanner的控制台交互;能用Command接口实现可扩展的命令路由;能识别架构中的"越权行为"。 | +| **思维转型** | 从"一个类写全部"转向"分层解耦";从"修改现有代码"转向"新增类实现功能";从"满足功能"转向"代码的工程洁癖"。 | +| **工具应用** | 利用AI辅助审查MVC职责越权;让AI扮演"架构审计师"检查分层是否清晰;理解AI生成代码中的架构缺陷。 | + +--- + +## 二、教学重点与难点 + +| 项目 | 内容 | 突破方法 | +|------|------|----------| +| **重点** | MVC三层职责划分、CLI交互实现、Command接口解耦、代码中的工程细节(常量、输出归属) | 以"新增命令需要改什么"为切入点,展示Command模式的优势;通过现场"代码找茬"强化细节意识 | +| **难点** | Controller不写业务逻辑、Command接口的多态实现、共享数据模型的设计缺陷识别 | 现场演示:增加一个命令只需新建类,无需修改Controller;暴露`List
`共享引用的问题并预告解决方案 | + +--- + +## 三、教学过程设计(90分钟) + +| 环节 | 时间 | 教学内容 | 师生活动 | AI协同点 | +|------|------|----------|----------|----------| +| **1. 痛点引入:从脚本到工程的鸿沟** | 10' | 展示"意大利面"式爬虫代码,演示改一处需要动全身 | **教师演示**:现场展示一段混乱代码,让学生找问题 | 用AI分析代码耦合度 | +| **2. CLI vs GUI:架构选择的思考** | 10' | 对比两种方案的优缺点,解释为什么CLI更适合培养工程思维 | **教师讲解**:用对比表格说明选择CLI的理由 | — | +| **3. MVC分层设计** | 20' | 讲解Model/View/Controller三层职责,用"餐厅类比"强化理解,随后批判类比局限性 | **教师讲解**:配合架构图讲解三层交互,引导学生寻找类比破绽 | 用AI生成MVC职责对照表 | +| **4. Command模式:可扩展的命令路由** | 15' | 引入Command接口,解释"一个命令就是一个类" | **类比**:Command像酒店的服务部门,Controller是前台 | 让AI解释Command模式的多态原理 | +| **5. Maven模板与环境** | 5' | 直接使用提供的Maven模板,讲解目录结构 | **教师演示**:解压模板 → IDEA打开 → 运行 | — | +| **6. 三层代码落地** | 20' | **Model**:Article实体
**View**:ConsoleView(ANSI常量)
**Command接口**+实现
**Controller**:Map路由 | **教师演示**:分步写出代码,刻意埋入1~2个"越权细节"让学生找茬 | 学生用AI做"架构审计" | +| **7. 架构反思与展望** | 5' | 指出当前`List
`共享引用的问题,预告W10策略模式与仓库层 | **师生互动**:你发现这个设计有什么风险? | 让AI分析共享可变状态的危害 | +| **8. 实践任务:空壳程序** | 5' | 搭建完整包结构,实现CLI循环 | 学生现场编码,教师巡视 | 完成后用AI检查包结构 | +| **9. 总结与过渡** | 5' | 本周实现了"骨架+命令可扩展",下周填入"灵魂"——解析器,并解决数据安全问题 | 总结Command模式优势,预告策略模式 | — | + +--- + +## 四、核心教学内容脚本 + +### 4.1 痛点引入:从脚本到工程的鸿沟(10分钟) + +**教师口播**: +> "同学们,前8周我们学的是Java语法,从变量到类,从继承到接口。但有一个问题:代码写完之后,怎么组织?" +> +> "来看这段代码——这是某个同学写的'爬虫',他一个人完成了一个'完整'的项目。" + +**展示"脚本式"代码**: +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +**提问引导**: +1. "如果我想把标题保存到文件,要改哪里?" +2. "如果我想支持另一个网站,它的HTML结构不一样,要怎么办?" +3. "如果我想让输出变成彩色,要改哪里?" + +**痛点提炼**: +> "看到了吗?才60行代码,已经'牵一发而动全身'了。这就是一个'脚本'的宿命——功能全混在一起,改一个小需求,整个文件都要翻。" +> +> "这周我们要解决:**怎么让代码'改起来不疼'?**" + +--- + +### 4.2 CLI vs GUI:架构选择的思考(10分钟) + +**教师口播**: +> "既然要写一个'完整'的爬虫应用,我们有两个选择:图形界面(GUI)或命令行界面(CLI)。为什么我推荐CLI而不是GUI?" + +**对比表格** + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **代码量** | FXML + Controller + CSS,大量模板代码 | 纯Java,代码量可控 | +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **后端能力** | 几乎无关 | 模拟真实服务器开发 | +| **可测试性** | 难(需要UI测试框架) | 易(直接测试Command类) | +| **工程思维** | 弱(关注视觉) | 强(关注逻辑) | + +**核心观点**: +> **CLI更需要MVC!** GUI有现成的事件系统(点击按钮→触发事件),而CLI只有字符流。**没有架构,分分钟写成脚本**。MVC在CLI里是"刚需",不是"装饰"。 +> +> **更深一层**:在GUI里,框架已经硬塞给你一套架构,你只是在填空;但在CLI里,所有结构都必须由你亲手搭建。**当外部约束消失,内部的工程纪律才真正开始建立**——这才是本节课的真正目的。 + +**CLI也能很酷**: +- ANSI彩色输出(红/绿/黄/蓝) +- 表格展示数据 +- 进度条动画 +- 模拟真实大数据开发场景 + +--- + +### 4.3 MVC分层设计(20分钟) + +#### 4.3.1 MVC的起源与演进 + +**教师口播**: +> "MVC不是新东西,它是1970年代为桌面应用设计的架构思想。但它的核心——'职责分离'——在任何软件里都适用。" + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +#### 4.3.2 从GUI到CLI的映射 + +| GUI组件 | CLI对应 | 说明 | +|--------|--------|------| +| 窗口/按钮 | 命令行输入 | **View = 用户交互** | +| 数据模型 | Article实体类 | **Model = 数据结构** | +| 事件监听 | Command路由 | **Controller = 调度** | + +#### 4.3.3 MVC三层职责 + +**架构图示**: + +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ - 接收命令(crawl, help, exit) │ +│ - 分发给对应的Command │ +│ 【口诀】:Controller不管"怎么做", │ +│ 只管"派给谁" │ +└─────────┬───────────────┬───────────────┘ + │ │ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ - 数据实体 │ │ - 输入解析 │ +│ - 业务逻辑 │ │ - 输出格式化 │ +│ 【口诀】: │ │ 【口诀】: │ +│ Model管"数据" │ │ View管"呈现" │ +└─────────────────┘ └─────────────────┘ +``` + +**三层职责详解** + +| 层级 | 职责 | 典型代码 | 禁止做什么 | +|------|------|----------|------------| +| **Model** | 数据结构 + 业务逻辑 | `class Article { String title; String content; }` | 不能有`System.out.println`,不能有`Scanner` | +| **View** | 接收用户输入 + 格式化输出 | `class ConsoleView { String readInput(); void print(String); }` | 不能写爬虫逻辑,只做"传声筒" | +| **Controller** | 协调调度 | `class CrawlerController { void handle(String cmd) { ... } }` | 不能直接写业务细节,委托给Command | + +#### 4.3.4 类比强化:"餐厅类比" + +> "把MVC想象成一家餐厅: +> - **Model是后厨**:只管做菜(数据加工),不管谁来吃、怎么端 +> - **View是服务员**:只管端菜和收钱(输入输出),不管菜怎么做 +> - **Controller是前台**:只管把顾客的点单传给后厨,把做好的菜端给顾客 +> +> 如果后厨开始管'谁来吃饭',这餐厅就乱了。" + +#### 4.3.5 对"餐厅类比"的批判性思考(关键!) + +**教师导引**: +> "刚才的类比好理解吗?很好。但任何一个类比都有它的边界,如果把它当成真理,就会出问题。现在我们来给这个类比'找茬'。" + +**提问学生**: +1. "后厨真的完全不知道客人是谁吗?如果客人有忌口(比如不吃香菜),这个信息需不需要传到后厨?" +2. "服务员只是端菜吗?在真实餐厅里,服务员经常向后厨反馈'客人觉得今天的菜咸了',这属于View→Model的反向影响吗?" +3. "在这个类比里,我们把前台(Controller)和后厨(Model)的关系说成单向的。但实际上,后厨做完了菜,需要通知前台'菜好了',这不就是**观察者模式**吗?" + +**点明本质**: +> "实际MVC的数据流向常常是**双向**的:Controller调用Model的方法改变数据,Model变化后又通知View更新显示。只不过在本次CLI项目中,我们暂时使用'请求-响应'的单向简化模型——用户输入命令,系统处理,然后立即输出结果。这个简化版够用,但你要知道完整的MVC是更动态的。随着系统复杂,Model层需要一个专门的'仓库类'来管理数据,并通知视图刷新——这正是W10我们将要深入的内容。" + +#### 4.3.6 MVC的数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,目前暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +### 4.4 Command模式:可扩展的命令路由(15分钟) + +**教师口播**: +> "现在引入一个设计模式——Command(命令)模式。它的核心思想是:**一个命令就是一个类**。" + +#### 4.4.1 为什么需要Command模式? + +**演示:增加一个命令的代价(switch-case版)** +```java +// 现状代码 +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +**提问**: +- "如果我想增加10个命令,这个类要改多少次?" +- "如果我不小心删了一个case,整个程序还能跑吗?" + +**痛点提炼**: +> "每加一个功能,就要在这个类里戳一个洞。**这就是'肥控制器'陷阱**——所有的逻辑都堆在Controller里,它变成了新的'意大利面'。" + +#### 4.4.2 Command模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| **Command接口** | 抽象的"订单" | `Command` 接口 | +| **ConcreteCommand** | 具体的订单 | `HelpCommand`、`CrawlCommand` | +| **Invoker** | 接单的前台 | `CrawlerController` | +| **Receiver** | 执行者 | `ConsoleView`、`ArticleRepository` | + +#### 4.4.3 Command接口定义 + +```java +// src/main/java/com/crawler/command/Command.java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); // 命令名,如 "crawl" + void execute(String[] args, List
articles); // 执行逻辑 +} +``` + +#### 4.4.4 Controller的变革(从switch到Map) + +```java +// 修改后的Controller +public class CrawlerController { + private Map commands; // 用Map存命令 + private ConsoleView view; // 持有View以输出错误 + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.commands = new HashMap<>(); + // 增加命令无需改Controller代码,只需在这里注册 + commands.put("crawl", new CrawlCommand(view)); + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmd = parts[0].toLowerCase(); + + Command command = commands.get(cmd); + if (command == null) { + view.printError("Unknown command: " + cmd); // 通过View输出,而非直接System.out + return; + } + + // 执行命令,传入参数和文章列表 + command.execute(parts, articles); + } +} +``` + +**对比表格** + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改Controller | 新建一个类 | +| 多态体验 | 无 | execute()的多态调用 | +| 可测试性 | 难 | 每个Command可单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +**类比强化**: +> "Command模式就像**酒店的客房服务**:每个服务(清理、送餐、按摩)都是一个独立的部门。前台(Controller)只负责接电话,然后把请求'派发'给对应的部门。部门自己知道怎么干活,不需要前台教。" +> +> "如果想新增一个服务,前台只需要'登记'一下,不需要把现有部门重新装修。" + +--- + +### 4.5 Maven模板与环境(5分钟) + +**教师口播**: +> "这周我们不发愁pom.xml配置。我已经把 Maven 模板准备好了,你们只需要解压、打开、运行。" + +**模板使用流程**: +``` +1. 解压 [my-crawler-template.zip] +2. 用 IDEA 打开文件夹 +3. 右键 pom.xml → Maven → Reload Project +4. 运行 App.java +``` + +**标准目录结构**: +``` +src/main/java/com/crawler/ +├── model/ +│ └── Article.java +├── view/ +│ └── ConsoleView.java +├── command/ +│ ├── Command.java (接口) +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/ + └── CrawlerController.java +``` + +--- + +### 4.6 代码落地(20分钟) + +#### 4.6.1 Model层:Article实体 + +```java +// src/main/java/com/crawler/model/Article.java +package com.crawler.model; + +public class Article { + private String title; + private String url; + private String content; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { return title; } + public void setTitle(String title) { this.title = title; } + public String getUrl() { return url; } + public void setUrl(String url) { this.url = url; } + public String getContent() { return content; } + public void setContent(String content) { this.content = content; } + + @Override + public String toString() { + return "Article{title='" + title + "', url='" + url + "'}"; + } +} +``` + +#### 4.6.2 View层:ANSI常量集中管理(工程细节!) + +```java +// src/main/java/com/crawler/view/ConsoleView.java +package com.crawler.view; + +import com.crawler.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + // ANSI颜色常量——集中管理,避免散落各处 + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + private static final String ANSI_CYAN = "\033[36m"; + private static final String ANSI_RESET = "\033[0m"; + + private Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("crawler> "); + return scanner.nextLine().trim(); + } + + public void print(String msg) { + System.out.println(msg); + } + + public void printSuccess(String msg) { + print(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + print(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + print(ANSI_CYAN + msg + ANSI_RESET); + } + + // 展示文章列表 + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("No articles yet. Use 'crawl ' first."); + return; + } + print("+----------+--------------------------------+"); + print("| Title | URL |"); + print("+----------+--------------------------------+"); + for (Article a : articles) { + String title = a.getTitle(); + if (title.length() > 10) title = title.substring(0, 10) + ".."; + String url = a.getUrl(); + if (url.length() > 30) url = url.substring(0, 27) + "..."; + print("| " + String.format("%-10s", title) + " | " + url + " |"); + } + print("+----------+--------------------------------+"); + printInfo("Total: " + articles.size() + " articles"); + } +} +``` + +**教师提示**: +> "注意:所有ANSI转义码都被定义为`private static final`常量。如果把`\033[32m`散落在项目各处,一旦想调整颜色,就得满世界去改——这正是我们之前痛批的'意大利面'。**这就是工程细节**。" + +#### 4.6.3 Command接口与四个实现(全部通过View输出) + +```java +// Command.java +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} + +// HelpCommand.java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} + +// ListCommand.java +public class ListCommand implements Command { + private ConsoleView view; + public ListCommand(ConsoleView v) { this.view = v; } + public String getName() { return "list"; } + public void execute(String[] args, List
articles) { + view.display(articles); + } +} + +// CrawlCommand.java (存根) +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} + +// ExitCommand.java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); // 全部输出都通过View,绝不让System.out直接出现在这里 + System.exit(0); + } +} +``` + +**故意埋设的"找茬点"**: +> "我在刚才的代码里有没有隐藏违反MVC原则的地方?`CrawlCommand`的存根里,`view.printInfo("Stub: Would crawl " + args[1]);` —— 这个字符串拼接算是"业务逻辑"吗?留给大家用AI架构审计时讨论。 + +#### 4.6.4 Controller:Map路由(全部通过View输出) + +```java +// src/main/java/com/crawler/controller/CrawlerController.java +package com.crawler.controller; + +import com.crawler.command.*; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private Map commands = new HashMap<>(); + private ConsoleView view; // 持有View + private List
articles; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmdName = parts[0].toLowerCase(); + + Command cmd = commands.get(cmdName); + if (cmd == null) { + view.printError("Unknown command: " + cmdName); // 错误信息也走View! + return; + } + cmd.execute(parts, articles); + } +} +``` + +#### 4.6.5 main方法:组装 + +```java +// src/main/java/com/crawler/App.java +package com.crawler; + +import com.crawler.controller.CrawlerController; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class App { + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler!"); + view.printInfo("Type 'help' for commands."); + + while (true) { + controller.handle(view.readLine()); + } + } +} +``` + +#### 4.6.6 架构反思与展望:共享List
的隐患(关键!) + +**教师口播**: +> "现在这个架构已经可用了。但请大家审视一下:我们所有的Command都直接拿到了`List
`的引用。换句话说,任何一个命令都可以随意增、删、改这个列表。" +> +> "这就好像一家酒店,所有服务员、厨师、清洁工都能随意进出保险箱——**数据结构完全裸奔了**。" + +**提问**: +- "如果CrawlCommand不小心写错了代码,把一个null塞进articles,HelpCommand会不会受影响?" +- "如果未来我们要在添加文章时也写入日志文件,现在的设计能优雅实现吗?还是得在所有Command里分别加日志代码?" + +**预告解决方案**: +> "下周,我们将引入**策略模式**和一个真正的**Model仓库层(ArticleRepository)**。这个仓库会把`List`封装起来,对外只提供`add()`、`getAll()`等安全接口。任何命令想修改数据,都必须通过仓库。这就是从'数据结构'到'模型层'的进化——我们W9先搭骨架,W10给它装上盔甲。" + +--- + +### 4.7 实践任务(5分钟) + +**任务要求**: +1. 使用Maven模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现4个Command:help/list/crawl/exit +4. `list`命令能展示已抓取的文章 +5. 运行并测试循环 +6. **代码找茬(额外加分)**:找出你自己代码中是否存在`System.out`直接调用、硬编码ANSI字符串等"越权行为" + +**验收标准**: +- [x] Maven编译通过 +- [x] Command接口和4个实现分离在不同文件 +- [x] Controller里没有switch-case +- [x] 新增命令只需新建类,不改Controller +- [x] list命令能正确显示空列表 +- [x] 所有输出均通过ConsoleView完成,无直接System.out.println(main除外) +- [x] ANSI颜色码集中定义为View常量 + +--- + +## 五、课后作业 + +### 5.1 必做任务 + +1. **完善Article**:增加`author`、`publishDate`字段 +2. **★ HistoryCommand(强制作业)**: + - 实现`history`命令,记录用户输入过的所有命令 + - 使用`List`存储历史(复习W8集合) + - 示例输出: + ``` + crawler> history + 1. help + 2. list + 3. crawl https://example.com + ``` +3. **AI架构审计**:将类名和方法名发给AI,指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?Model层是否包含输入输出代码?View层是否越权写了业务逻辑?有没有地方直接使用了System.out或硬编码ANSI码?" + +### 5.2 选做任务 + +1. **命令别名**:给`crawl`增加别名`c`,`help`增加别名`h` +2. **URL验证**:检查URL格式是否以http://或https://开头 +3. **暗色主题**:实现不同的配色方案(利用View中的ANSI常量,只需修改一处即可) +4. **思考并回答**:分析`List
`共享引用的潜在风险,写一段200字的小结 + +### 5.3 思考题 + +1. **Command vs switch-case**:增加10个命令,哪种方式代码改动量更小? +2. **如果不用Command接口,直接用Map存命令类行不行?** 接口的意义是什么? +3. **Controller里的`commands.put()`能否减少?** 提示:思考"注册机制" +4. **为什么ExitCommand里的`view.printSuccess("Bye!")`比直接`System.out.println`更"MVC"?** 提示:回忆View的职责 + +--- + +## 六、AI协同升级 + +### 架构审计师任务(必做) + +**学生执行步骤**: +1. 列出项目中所有类名(不含方法实现) +2. 将类名列表发给AI +3. 输入指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否清晰。Model层是否包含了不应该有的代码(Scanner/System.out)?View层是否越权写了业务逻辑?请指出任何一处直接使用System.out.println的地方,并建议如何改正。" + +**预期AI输出**: +- 指出哪一层有越权行为 +- 建议如何整改 +- 评价整体架构健康度 + +### 进阶AI探究(选做) + +> "假设我的Command接口中execute方法接收了一个`List
`参数,请分析这种设计在工程上有什么隐患,并给出重构建议。" + +--- + +## 七、教学反思与调整记录 + +| 日期 | 事项 | 调整内容 | +|------|------|----------| +| 2026-04-28 | 首次编写 | 基于CLI+MVC重构 | +| 2026-04-30 | 教授反馈 | 引入Command模式、提供Maven模板、升级AI协同比 | +| 2026-04-30 | 逻辑重排 | 按"问题→选择→架构→模式"顺序重写 | +| 2026-05-01 | v2 vs V3合并 | 融合深度改进:增加教育哲学、批判性思考、ANSI常量、共享List隐患、故意埋坑 | + +--- + +## 附录1:Maven模板说明 + +> 老师提供`my-crawler-template.zip`压缩包,包含: +> - pom.xml(含Jsoup依赖) +> - 空的src/main/java结构 +> - .gitignore + +## 附录2:常见问题速查 + +| 问题 | 解答 | +|------|------| +| IDEA不识别pom.xml | 右键 pom.xml → Maven → Reload Project | +| 中文乱码 | Settings → Editor → File Encodings → UTF-8 | +| 包名大小写 | 包名全小写,类名首字母大写 | +| Command找不到 | 检查是否 implements Command,是否 @Override getName() | +| 命令不生效 | 检查 commands.put() 是否注册了该命令 | +| 输出颜色乱码 | IDEA控制台需支持ANSI,Windows下建议使用Windows Terminal或调整设置 | +| 我的System.out为什么被老师说越权 | View层才是与用户交互的唯一出口,所有输出都应通过View,这样将来改成GUI或日志时只需改View | + +## 附录3:教学逻辑说明 + +| 顺序 | 内容 | 设计理由 | +|------|------|----------| +| 1 | 痛点引入 | 从问题出发,让学生感受"为什么需要架构" | +| 2 | CLI vs GUI | 解释技术选型,建立"工程思维 > 视觉装饰"的认知 | +| 3 | MVC分层 | 核心架构概念,理解职责分离,通过类比及批判加深理解 | +| 4 | Command模式 | 具体实现方式,解决"肥控制器"问题 | +| 5 | Maven | 工具链支持 | +| 6 | 代码落地 | 实践验证,刻意植入细节规范,训练工程洁癖 | +| 7 | 架构反思 | 暴露共享可变状态隐患,为W10策略模式+仓库层做铺垫 | +| 8 | 实践任务 | 现场编码验证 | +| 9 | 总结 | 强化认知,预告下周 | + +--- + +## 版本说明 + +- **v1**:首次编写,CLI+MVC基础框架 +- **v2**:按"问题→选择→架构→模式"逻辑重排 +- **v3 (本版)**:融合v2结构 + V3深度改进,包含: + - 更深的CLI教育哲学 + - 餐厅类比批判性思考 + - ANSI常量集中管理工程细节 + - 全部输出走View + - 共享List架构隐患反思 + - 故意埋坑让学生找茬 + - W10铺垫(策略模式+仓库层) \ No newline at end of file diff --git a/w9/java-cli/target/maven-archiver/pom.properties b/w9/java-cli/target/maven-archiver/pom.properties new file mode 100644 index 0000000..08a8f9f --- /dev/null +++ b/w9/java-cli/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 30 11:50:54 CST 2026 +artifactId=datacollect-cli +groupId=com.example +version=0.1.0 diff --git a/w9/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/w9/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/w9/java-cli/target/w9-ppt.md b/w9/java-cli/target/w9-ppt.md new file mode 100644 index 0000000..5ddd5ad --- /dev/null +++ b/w9/java-cli/target/w9-ppt.md @@ -0,0 +1,530 @@ +## 高级程序设计 · 第9周 + +#### 工程架构:从"写代码"到"造系统" + +##### CLI + MVC + Command模式实战 + +--- + +### 📌 本周导航 + +- 痛点引入:脚本的宿命 +- CLI vs GUI:为什么选命令行? +- MVC分层:职责分离的艺术 +- Command模式:可扩展的路由 +- Maven模板:工程化第一步 +- 代码落地:从接口到实现 +- 架构反思:共享数据的隐患 +- 实践任务 + 课后作业 + +--- + +### 1️⃣ 痛点引入:从脚本到工程的鸿沟 + +#### 这是一段“意大利面”爬虫 + +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +--- + +### 脚本的三大痛点 + +| 需求 | 需要改哪里? | +|------|--------------| +| 保存标题到文件 | 改 main 内部逻辑 | +| 支持不同网站结构 | 全部重写解析代码 | +| 彩色输出 | 一个一个改 print | + +> 😫 **牵一发而动全身 → 改起来疼** + +### 本周目标:**让代码“改起来不疼”** + +--- + +## 2️⃣ CLI vs GUI:架构选择的思考 + +### 图形界面 vs 命令行 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| 学习重心 | 布局、控件、事件 | **架构、分层、路由** | +| 后端能力 | 弱 | 模拟真实服务器 | +| 工程思维 | 弱(关注视觉) | **强(关注逻辑)** | +| 可测试性 | 难 | 易 | + +--- + +## 核心观点 + +> **CLI 更需要 MVC!** + +- GUI 有现成事件系统,框架强塞给你一套架构 +- CLI 只有字符流 → **没有架构,分分钟写成脚本** + +> 🎯 **当外部约束消失,内部的工程纪律才真正开始建立** + +### CLI 也能很酷 + +- ANSI 彩色输出 +- 表格展示数据 +- 模拟大数据/后端开发 + +--- + +## 3️⃣ MVC 分层设计 + +### MVC 的起源与演进 + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +**核心不变:职责分离** + +--- + +## MVC 三层职责 + +![[mvc.png]] +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ 只管"派给谁",不管"怎么做" │ +└─────────┬───────────────┬───────────────┘ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ 管"数据" │ │ 管"呈现" │ +│ + 业务逻辑 │ │ + 输入输出 │ +└─────────────────┘ └─────────────────┘ +``` + +--- + +## 三层“禁止做什么” + +| 层级 | 禁止行为 | +| -------------- | -------------------------------------- | +| **Model** | 不能有 `System.out.println`,不能有 `Scanner` | +| **View** | 不能写爬虫逻辑,只做“传声筒” | +| **Controller** | 不能直接写业务细节,委托给 Command | + +> 🔴 **越权就是架构腐败的开始** + +--- + +## 🍽️ 餐厅类比(帮助理解) + +- **Model = 后厨**:只管做菜,不管谁来吃、怎么端 +- **View = 服务员**:只管端菜和收钱,不管菜怎么做 +- **Controller = 前台**:接单 → 派给后厨 → 叫服务员上菜 + +--- + +## 🤔 对类比的批判性思考(关键!) + +> 任何类比都有边界,不要当成真理 + +| 场景 | 暴露的问题 | +|------|------------| +| 客人有忌口(不吃香菜) | 信息需要传到后厨 → Model 可能需要知道 meta 信息 | +| 服务员反馈“今天的菜咸了” | View → Model 反向影响 | +| 后厨做完菜通知前台 | **观察者模式**,数据流可能是双向的 | + +**本课程简化模型**:请求-响应,单向流 + +--- + +## MVC 数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +## 4️⃣ Command 模式:可扩展的命令路由 + +### 为什么需要 Command 模式? + +```java +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +> 每加一个功能,就要在这个类里戳一个洞 → **肥控制器陷阱** + +--- + +## Command 模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| Command接口 | 抽象的“订单” | `Command` | +| ConcreteCommand | 具体的订单 | `HelpCommand` | +| Invoker | 接单的前台 | `CrawlerController` | +| Receiver | 执行者 | `ConsoleView`、`ArticleRepository` | + +--- + +## Command 接口定义 + +```java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} +``` + +--- + +## Controller 的变革:从 switch 到 Map + +```java +public class CrawlerController { + private Map commands = new HashMap<>(); + + public CrawlerController(ConsoleView view, List
articles) { + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + // 解析命令 → 从 Map 取 Command → 调用 execute + } +} +``` + +> **增加新命令:只需新建类,Controller 零改动!** + +--- + +## 对比:switch-case vs Command + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改 Controller | 新建一个类 | +| 多态体验 | 无 | `execute()` 多态 | +| 可测试性 | 难 | 每个 Command 单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +> 🏨 **类比:酒店客房服务,前台只负责派单** + +--- + +## 5️⃣ Maven 模板与环境(5分钟) + +### 直接使用模板,不折腾配置 + +``` +my-crawler-template.zip + ↓ 解压 + IDEA打开 + ↓ 右键 pom.xml → Maven → Reload Project + ↓ 运行 App.java +``` + +### 标准目录结构 + +``` +src/main/java/com/crawler/ +├── model/Article.java +├── view/ConsoleView.java +├── command/ +│ ├── Command.java +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/CrawlerController.java +``` + +--- + +## 6️⃣ 代码落地(分步实现) + +### Model:Article 实体 + +```java +public class Article { + private String title; + private String url; + private String content; + // 构造器、getter/setter、toString +} +``` + +> 📦 只存放数据,没有任何输入输出代码 + +--- + +## View:ConsoleView(ANSI常量集中管理) + +```java +public class ConsoleView { + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + // ... 其他常量 + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + public void printError(String msg) { ... } + public void display(List
articles) { ... } +} +``` + +> ✨ **所有颜色码集中定义 → 改主题只需改一处** + +--- + +## Command 实现示例(HelpCommand) + +```java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} +``` + +> ⚠️ 全部输出通过 `view`,绝不让 `System.out` 直接出现在这里 + +--- + +## CrawlCommand(存根,下周填坑) + +```java +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} +``` + +> 🔍 **找茬点**:这里拼接字符串算是“业务逻辑”吗?留给大家用 AI 审计。 + +--- + +## ExitCommand + +```java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} +``` + +> ✅ 所有输出都通过 View → 将来改 GUI 只需换 View 实现 + +--- + +## Controller + main 组装 + +```java +// Controller 中持有 Map +// App.java 中: +ConsoleView view = new ConsoleView(); +List
articles = new ArrayList<>(); +CrawlerController controller = new CrawlerController(view, articles); +view.printSuccess("Welcome to CLI Crawler!"); +while (true) { + controller.handle(view.readLine()); +} +``` + +> 🔁 完成交互循环 + +--- + +## 7️⃣ 架构反思:共享 List
的隐患 + +### 当前问题 + +- 所有 Command 都直接拿到 `List
` 引用 +- 任何一个命令都可以随意增、删、改列表 +- 数据完全“裸奔” + +> 🚨 就像酒店所有员工都能进保险箱 + +--- + +## 提问 + +- 如果 `CrawlCommand` 不小心把 `null` 塞进列表,`ListCommand` 会怎样? +- 如果我们要在添加文章时写日志,现在的设计能优雅实现吗? + +### 预告解决方案(W10) + +- **策略模式** + **仓库层(ArticleRepository)** +- 封装 `List`,对外只暴露 `add()`、`getAll()` 等安全接口 + +> W9 搭骨架,W10 装上盔甲 + +--- + +## 8️⃣ 实践任务(现场5分钟) + +### 必做项 + +1. 使用 Maven 模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现 4 个 Command:help / list / crawl / exit +4. `list` 能展示已抓取的文章(目前存根即可) +5. 运行并测试循环 + +### 额外加分:代码找茬 + +- 检查是否仍有 `System.out` 直接调用 +- 检查 ANSI 码是否硬编码在多个地方 + +--- + +## 验收标准 + +- [x] Maven 编译通过 +- [x] Command 接口和 4 个实现在不同文件 +- [x] Controller 里没有 switch-case +- [x] 新增命令只需新建类,不改 Controller +- [x] list 能正确显示空列表 +- [x] 所有输出均通过 `ConsoleView` +- [x] ANSI 颜色码集中定义为常量 + +--- + +## 9️⃣ 课后作业 + +### 必做 + +1. **完善 Article**:增加 `author`、`publishDate` 字段 +2. **★ HistoryCommand**:记录用户输入过的所有命令(用 `List`) +3. **AI 架构审计**:将类名发给 AI,指令: + > “作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?” + +### 选做 + +- 命令别名(c 代替 crawl) +- URL 格式验证 +- 暗色主题(修改一处常量) +- 思考题:分析 `List
` 共享引用的风险(200字小结) + +--- + +## 🤖 AI 协同升级 + +### 架构审计师任务(必做) + +**步骤**: +1. 列出所有类名(不含方法实现) +2. 发给 AI +3. 指令:“检查 MVC 分层是否清晰,是否有越权行为” + +### 进阶探究(选做) + +> “假设我的 Command 接口中 execute 方法接收了一个 `List
` 参数,请分析这种设计在工程上有什么隐患,并给出重构建议。” + +--- + +## 📚 总结与过渡 + +### 本周成果 + +- ✅ 工程化包结构 +- ✅ MVC 分层清晰 +- ✅ Command 模式实现可扩展路由 +- ✅ 所有输出走 View,常量集中管理 + +### 下周预告 + +- **策略模式**:封装爬取算法 +- **仓库层(Repository)**:武装 `List
`,解决共享隐患 + +> 🚀 从“写代码”到“造系统”,踏出坚实第一步! + +--- + +## Q&A + +### 常见问题 + +| 问题 | 解答 | +|------|------| +| IDEA 不识别 pom.xml | 右键 → Maven → Reload Project | +| 中文乱码 | Settings → File Encodings → UTF-8 | +| 输出颜色乱码 | Windows 建议使用 Windows Terminal | +| 我的 System.out 被批评 | View 才是唯一输出出口 | + +--- + +## 谢谢! + +### 课件已上传,模板在课程群 + +**保持工程洁癖,下周见!** \ No newline at end of file diff --git a/w9/程序运行截图.png b/w9/程序运行截图.png new file mode 100644 index 0000000000000000000000000000000000000000..c98187556689b197becb6ed5572ba5ca29255f53 GIT binary patch literal 378159 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¬@(%}`%4Oh7)R58~7vOJ7;Pv<&n>@5V?fQm}c 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ᕡkl$Ghk#m{4i5E#4yP-7KUB76^z@1 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

?I;#>3gAxT}hojML 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 literal 0 HcmV?d00001 diff --git a/w9/越权行为提问.txt b/w9/越权行为提问.txt new file mode 100644 index 0000000..382eb87 --- /dev/null +++ b/w9/越权行为提问.txt @@ -0,0 +1,6 @@ +存在越权行为 +1.Command直接持有View引用(绕过Controller)。Command层本只负责业务逻辑,不应该直接访问view +2.Command直接操作Model(绕过Controller)。Controller将 articles 列表直接传递给Command,允许Command直接修改Model。 +3.HistoryCommand越权访问内部状态。addCommand() 是HistoryCommand的私有操作,不应暴露给Controller调用。 +优化建议: +引入Service层,使仅Controller持有View,并让Model操作经Service/Controller中转 \ No newline at end of file diff --git a/w9/选做/List共享引用风险.txt b/w9/选做/List共享引用风险.txt new file mode 100644 index 0000000..4c0b48e --- /dev/null +++ b/w9/选做/List共享引用风险.txt @@ -0,0 +1,4 @@ +1.有并发安全风险,多线程环境下,Command 执行时可能与其他操作产生竞态条件,导致数据不一致。 +2.封装性被破坏。Command 层直接获得列表的可变引用,可绕过 Controller 进行任意增删改操作,违反 MVC 分层原则。 +3. 状态不可追溯,任何持有引用的组件都可修改数据,导致状态变更难以追踪和审计。 +4.测试隔离困难,测试时难以 Mock 或隔离共享状态,增加测试复杂度。 \ No newline at end of file diff --git a/w9/选做/java-cli/.gitignore b/w9/选做/java-cli/.gitignore new file mode 100644 index 0000000..0ebcf1a --- /dev/null +++ b/w9/选做/java-cli/.gitignore @@ -0,0 +1,4 @@ +*.jar +*.jar +*.class +*.log \ No newline at end of file diff --git a/w9/选做/java-cli/README.md b/w9/选做/java-cli/README.md new file mode 100644 index 0000000..3ea02ec --- /dev/null +++ b/w9/选做/java-cli/README.md @@ -0,0 +1,17 @@ +# DataCollect 教学项目 — 最小可运行版本 + +这是一个最小可用的 Java CLI 演示工程,目标:打印帮助信息以验证运行环境。 + +构建: +```bash +mvn -q package +``` + +运行(示例): +```bash +java -jar target/datacollect-cli-0.1.0-jar-with-dependencies.jar --help +``` + +项目结构(最小): +- `src/main/java/com/example/datacollect/Main.java` — CLI 入口,打印帮助 +- `pom.xml` — Maven 构建配置,生成可执行 jar diff --git a/w9/选做/java-cli/java-cli/.gitignore b/w9/选做/java-cli/java-cli/.gitignore new file mode 100644 index 0000000..0ebcf1a --- /dev/null +++ b/w9/选做/java-cli/java-cli/.gitignore @@ -0,0 +1,4 @@ +*.jar +*.jar +*.class +*.log \ No newline at end of file diff --git a/w9/选做/java-cli/java-cli/README.md b/w9/选做/java-cli/java-cli/README.md new file mode 100644 index 0000000..3ea02ec --- /dev/null +++ b/w9/选做/java-cli/java-cli/README.md @@ -0,0 +1,17 @@ +# DataCollect 教学项目 — 最小可运行版本 + +这是一个最小可用的 Java CLI 演示工程,目标:打印帮助信息以验证运行环境。 + +构建: +```bash +mvn -q package +``` + +运行(示例): +```bash +java -jar target/datacollect-cli-0.1.0-jar-with-dependencies.jar --help +``` + +项目结构(最小): +- `src/main/java/com/example/datacollect/Main.java` — CLI 入口,打印帮助 +- `pom.xml` — Maven 构建配置,生成可执行 jar diff --git a/w9/选做/java-cli/java-cli/pom.xml b/w9/选做/java-cli/java-cli/pom.xml new file mode 100644 index 0000000..01bc611 --- /dev/null +++ b/w9/选做/java-cli/java-cli/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + com.example + datacollect-cli + 0.1.0 + + 11 + 11 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + + com.example.datacollect.Main + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java new file mode 100644 index 0000000..44d00aa --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/Main.java @@ -0,0 +1,21 @@ +package com.example.datacollect; + +import com.example.datacollect.controller.CrawlerController; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class Main { + + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List

articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler (w9_1)! Type help for commands."); + while (true) { + controller.handle(view.readLine()); + } + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java new file mode 100644 index 0000000..24e59a6 --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/Command.java @@ -0,0 +1,9 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java new file mode 100644 index 0000000..45baea1 --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java @@ -0,0 +1,27 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class CrawlCommand implements Command { + private final ConsoleView view; + + public CrawlCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "crawl"; + } + + @Override + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: would crawl " + args[1]); + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java new file mode 100644 index 0000000..6946d85 --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java @@ -0,0 +1,24 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ExitCommand implements Command { + private final ConsoleView view; + + public ExitCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "exit"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java new file mode 100644 index 0000000..4fde32f --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HelpCommand implements Command { + private final ConsoleView view; + + public HelpCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "help"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java new file mode 100644 index 0000000..2b79929 --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java @@ -0,0 +1,36 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HistoryCommand implements Command { + private final ConsoleView view; + private final List history; + + public HistoryCommand(ConsoleView view, List history) { + this.view = view; + this.history = history; + } + + @Override + public String getName() { + return "history"; + } + + @Override + public void execute(String[] args, List
articles) { + if (history.isEmpty()) { + view.printInfo("No command history."); + return; + } + view.printInfo("Command history:"); + for (int i = 0; i < history.size(); i++) { + view.printInfo((i + 1) + ". " + history.get(i)); + } + } + + public void addCommand(String command) { + history.add(command); + } +} \ No newline at end of file diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java new file mode 100644 index 0000000..8eba2cd --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ListCommand implements Command { + private final ConsoleView view; + + public ListCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "list"; + } + + @Override + public void execute(String[] args, List
articles) { + view.display(articles); + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java new file mode 100644 index 0000000..ad03ef4 --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java @@ -0,0 +1,47 @@ +package com.example.datacollect.controller; + +import com.example.datacollect.command.Command; +import com.example.datacollect.command.CrawlCommand; +import com.example.datacollect.command.ExitCommand; +import com.example.datacollect.command.HelpCommand; +import com.example.datacollect.command.ListCommand; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private final Map commands = new HashMap<>(); + private final ConsoleView view; + private final List
articles; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + register(new HelpCommand(view)); + register(new ListCommand(view)); + register(new CrawlCommand(view)); + register(new ExitCommand(view)); + } + + private void register(Command command) { + commands.put(command.getName(), command); + } + + public void handle(String input) { + String text = input == null ? "" : input.trim(); + if (text.isEmpty()) { + return; + } + + String[] args = text.split("\\s+"); + String cmdName = args[0].toLowerCase(); + Command command = commands.get(cmdName); + if (command == null) { + view.printError("Unknown command: " + cmdName); + return; + } + command.execute(args, articles); + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java new file mode 100644 index 0000000..147dbe6 --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/model/Article.java @@ -0,0 +1,45 @@ +package com.example.datacollect.model; + +public class Article { + private String title; + private String url; + private String content; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public String toString() { + return "Article{" + + "title='" + title + '\'' + + ", url='" + url + '\'' + + '}'; + } +} diff --git a/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java new file mode 100644 index 0000000..3c1d47a --- /dev/null +++ b/w9/选做/java-cli/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java @@ -0,0 +1,42 @@ +package com.example.datacollect.view; + +import com.example.datacollect.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_BLUE = "\u001B[34m"; + + private final Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("> "); + return scanner.nextLine(); + } + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + System.out.println(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + System.out.println(ANSI_BLUE + msg + ANSI_RESET); + } + + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("暂无文章,请先执行 crawl。"); + return; + } + for (int i = 0; i < articles.size(); i++) { + Article a = articles.get(i); + System.out.println((i + 1) + ". " + a.getTitle() + " | " + a.getUrl()); + } + } +} diff --git a/w9/选做/java-cli/java-cli/target/W9工程架构 - 教案v3.md b/w9/选做/java-cli/java-cli/target/W9工程架构 - 教案v3.md new file mode 100644 index 0000000..09de868 --- /dev/null +++ b/w9/选做/java-cli/java-cli/target/W9工程架构 - 教案v3.md @@ -0,0 +1,758 @@ +--- + +# 教案:《高级程序设计》第9周——工程架构:从"写代码"到"造系统" + +| 项目 | 内容 | +|------|------| +| **课程名称** | 高级程序设计 | +| **周次** | 第9周 | +| **主题** | 工程架构——从"写代码"到"造系统" | +| **学时** | 2学时(90分钟) | +| **授课对象** | 具备Python基础、已完成Java面向对象特性学习的学生 | +| **教学环境** | JDK 17+、IntelliJ IDEA、Maven(模板) | +| **前情提要** | 本课程原计划使用JavaFX GUI,后根据教学反馈转向CLI + MVC + 爬虫工程化 | + +--- + +## 教学调整说明:为什么选择CLI而不是GUI? + +> **原计划**:JavaFX桌面应用 → **新计划**:CLI命令行应用 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **学生痛点** | "窗口点击"与后端能力无关 | 真正锻炼工程思维 | +| **AI辅助** | AI生成FXML,学生看不懂 | AI辅助重构架构 | +| **工程化** | 脱离真实后端开发场景 | 模拟真实服务器/大数据开发 | +| **核心转型** | "视觉装饰"优先 | "逻辑架构"优先 | + +**决策理由**: +1. **985学生需要的是工程思维**,不是拖控件 +2. **接口抽象**是弱项,CLI + MVC更能暴露这个问题 +3. **彩色终端**足够酷炫,且代码量可控 + +**更深层的教育价值**: +> 在GUI框架中,架构已被框架强制划定,学生只是"遵守规矩";而CLI世界里没有任何框架告诉你模型在哪、视图在哪——**当外部约束消失,内部的工程纪律才真正建立**。这正是本节课要传递的核心精神。 + +--- + +## 一、教学目标 + +| 目标维度 | 具体描述 | +|----------|----------| +| **知识掌握** | 理解MVC架构的职责划分及其演化脉络;掌握Maven项目结构与pom.xml基础;理解Command模式的路由原理。 | +| **工程实践** | 能搭建规范的Maven项目包结构;能实现基于Scanner的控制台交互;能用Command接口实现可扩展的命令路由;能识别架构中的"越权行为"。 | +| **思维转型** | 从"一个类写全部"转向"分层解耦";从"修改现有代码"转向"新增类实现功能";从"满足功能"转向"代码的工程洁癖"。 | +| **工具应用** | 利用AI辅助审查MVC职责越权;让AI扮演"架构审计师"检查分层是否清晰;理解AI生成代码中的架构缺陷。 | + +--- + +## 二、教学重点与难点 + +| 项目 | 内容 | 突破方法 | +|------|------|----------| +| **重点** | MVC三层职责划分、CLI交互实现、Command接口解耦、代码中的工程细节(常量、输出归属) | 以"新增命令需要改什么"为切入点,展示Command模式的优势;通过现场"代码找茬"强化细节意识 | +| **难点** | Controller不写业务逻辑、Command接口的多态实现、共享数据模型的设计缺陷识别 | 现场演示:增加一个命令只需新建类,无需修改Controller;暴露`List
`共享引用的问题并预告解决方案 | + +--- + +## 三、教学过程设计(90分钟) + +| 环节 | 时间 | 教学内容 | 师生活动 | AI协同点 | +|------|------|----------|----------|----------| +| **1. 痛点引入:从脚本到工程的鸿沟** | 10' | 展示"意大利面"式爬虫代码,演示改一处需要动全身 | **教师演示**:现场展示一段混乱代码,让学生找问题 | 用AI分析代码耦合度 | +| **2. CLI vs GUI:架构选择的思考** | 10' | 对比两种方案的优缺点,解释为什么CLI更适合培养工程思维 | **教师讲解**:用对比表格说明选择CLI的理由 | — | +| **3. MVC分层设计** | 20' | 讲解Model/View/Controller三层职责,用"餐厅类比"强化理解,随后批判类比局限性 | **教师讲解**:配合架构图讲解三层交互,引导学生寻找类比破绽 | 用AI生成MVC职责对照表 | +| **4. Command模式:可扩展的命令路由** | 15' | 引入Command接口,解释"一个命令就是一个类" | **类比**:Command像酒店的服务部门,Controller是前台 | 让AI解释Command模式的多态原理 | +| **5. Maven模板与环境** | 5' | 直接使用提供的Maven模板,讲解目录结构 | **教师演示**:解压模板 → IDEA打开 → 运行 | — | +| **6. 三层代码落地** | 20' | **Model**:Article实体
**View**:ConsoleView(ANSI常量)
**Command接口**+实现
**Controller**:Map路由 | **教师演示**:分步写出代码,刻意埋入1~2个"越权细节"让学生找茬 | 学生用AI做"架构审计" | +| **7. 架构反思与展望** | 5' | 指出当前`List
`共享引用的问题,预告W10策略模式与仓库层 | **师生互动**:你发现这个设计有什么风险? | 让AI分析共享可变状态的危害 | +| **8. 实践任务:空壳程序** | 5' | 搭建完整包结构,实现CLI循环 | 学生现场编码,教师巡视 | 完成后用AI检查包结构 | +| **9. 总结与过渡** | 5' | 本周实现了"骨架+命令可扩展",下周填入"灵魂"——解析器,并解决数据安全问题 | 总结Command模式优势,预告策略模式 | — | + +--- + +## 四、核心教学内容脚本 + +### 4.1 痛点引入:从脚本到工程的鸿沟(10分钟) + +**教师口播**: +> "同学们,前8周我们学的是Java语法,从变量到类,从继承到接口。但有一个问题:代码写完之后,怎么组织?" +> +> "来看这段代码——这是某个同学写的'爬虫',他一个人完成了一个'完整'的项目。" + +**展示"脚本式"代码**: +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +**提问引导**: +1. "如果我想把标题保存到文件,要改哪里?" +2. "如果我想支持另一个网站,它的HTML结构不一样,要怎么办?" +3. "如果我想让输出变成彩色,要改哪里?" + +**痛点提炼**: +> "看到了吗?才60行代码,已经'牵一发而动全身'了。这就是一个'脚本'的宿命——功能全混在一起,改一个小需求,整个文件都要翻。" +> +> "这周我们要解决:**怎么让代码'改起来不疼'?**" + +--- + +### 4.2 CLI vs GUI:架构选择的思考(10分钟) + +**教师口播**: +> "既然要写一个'完整'的爬虫应用,我们有两个选择:图形界面(GUI)或命令行界面(CLI)。为什么我推荐CLI而不是GUI?" + +**对比表格** + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **代码量** | FXML + Controller + CSS,大量模板代码 | 纯Java,代码量可控 | +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **后端能力** | 几乎无关 | 模拟真实服务器开发 | +| **可测试性** | 难(需要UI测试框架) | 易(直接测试Command类) | +| **工程思维** | 弱(关注视觉) | 强(关注逻辑) | + +**核心观点**: +> **CLI更需要MVC!** GUI有现成的事件系统(点击按钮→触发事件),而CLI只有字符流。**没有架构,分分钟写成脚本**。MVC在CLI里是"刚需",不是"装饰"。 +> +> **更深一层**:在GUI里,框架已经硬塞给你一套架构,你只是在填空;但在CLI里,所有结构都必须由你亲手搭建。**当外部约束消失,内部的工程纪律才真正开始建立**——这才是本节课的真正目的。 + +**CLI也能很酷**: +- ANSI彩色输出(红/绿/黄/蓝) +- 表格展示数据 +- 进度条动画 +- 模拟真实大数据开发场景 + +--- + +### 4.3 MVC分层设计(20分钟) + +#### 4.3.1 MVC的起源与演进 + +**教师口播**: +> "MVC不是新东西,它是1970年代为桌面应用设计的架构思想。但它的核心——'职责分离'——在任何软件里都适用。" + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +#### 4.3.2 从GUI到CLI的映射 + +| GUI组件 | CLI对应 | 说明 | +|--------|--------|------| +| 窗口/按钮 | 命令行输入 | **View = 用户交互** | +| 数据模型 | Article实体类 | **Model = 数据结构** | +| 事件监听 | Command路由 | **Controller = 调度** | + +#### 4.3.3 MVC三层职责 + +**架构图示**: + +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ - 接收命令(crawl, help, exit) │ +│ - 分发给对应的Command │ +│ 【口诀】:Controller不管"怎么做", │ +│ 只管"派给谁" │ +└─────────┬───────────────┬───────────────┘ + │ │ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ - 数据实体 │ │ - 输入解析 │ +│ - 业务逻辑 │ │ - 输出格式化 │ +│ 【口诀】: │ │ 【口诀】: │ +│ Model管"数据" │ │ View管"呈现" │ +└─────────────────┘ └─────────────────┘ +``` + +**三层职责详解** + +| 层级 | 职责 | 典型代码 | 禁止做什么 | +|------|------|----------|------------| +| **Model** | 数据结构 + 业务逻辑 | `class Article { String title; String content; }` | 不能有`System.out.println`,不能有`Scanner` | +| **View** | 接收用户输入 + 格式化输出 | `class ConsoleView { String readInput(); void print(String); }` | 不能写爬虫逻辑,只做"传声筒" | +| **Controller** | 协调调度 | `class CrawlerController { void handle(String cmd) { ... } }` | 不能直接写业务细节,委托给Command | + +#### 4.3.4 类比强化:"餐厅类比" + +> "把MVC想象成一家餐厅: +> - **Model是后厨**:只管做菜(数据加工),不管谁来吃、怎么端 +> - **View是服务员**:只管端菜和收钱(输入输出),不管菜怎么做 +> - **Controller是前台**:只管把顾客的点单传给后厨,把做好的菜端给顾客 +> +> 如果后厨开始管'谁来吃饭',这餐厅就乱了。" + +#### 4.3.5 对"餐厅类比"的批判性思考(关键!) + +**教师导引**: +> "刚才的类比好理解吗?很好。但任何一个类比都有它的边界,如果把它当成真理,就会出问题。现在我们来给这个类比'找茬'。" + +**提问学生**: +1. "后厨真的完全不知道客人是谁吗?如果客人有忌口(比如不吃香菜),这个信息需不需要传到后厨?" +2. "服务员只是端菜吗?在真实餐厅里,服务员经常向后厨反馈'客人觉得今天的菜咸了',这属于View→Model的反向影响吗?" +3. "在这个类比里,我们把前台(Controller)和后厨(Model)的关系说成单向的。但实际上,后厨做完了菜,需要通知前台'菜好了',这不就是**观察者模式**吗?" + +**点明本质**: +> "实际MVC的数据流向常常是**双向**的:Controller调用Model的方法改变数据,Model变化后又通知View更新显示。只不过在本次CLI项目中,我们暂时使用'请求-响应'的单向简化模型——用户输入命令,系统处理,然后立即输出结果。这个简化版够用,但你要知道完整的MVC是更动态的。随着系统复杂,Model层需要一个专门的'仓库类'来管理数据,并通知视图刷新——这正是W10我们将要深入的内容。" + +#### 4.3.6 MVC的数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,目前暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +### 4.4 Command模式:可扩展的命令路由(15分钟) + +**教师口播**: +> "现在引入一个设计模式——Command(命令)模式。它的核心思想是:**一个命令就是一个类**。" + +#### 4.4.1 为什么需要Command模式? + +**演示:增加一个命令的代价(switch-case版)** +```java +// 现状代码 +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +**提问**: +- "如果我想增加10个命令,这个类要改多少次?" +- "如果我不小心删了一个case,整个程序还能跑吗?" + +**痛点提炼**: +> "每加一个功能,就要在这个类里戳一个洞。**这就是'肥控制器'陷阱**——所有的逻辑都堆在Controller里,它变成了新的'意大利面'。" + +#### 4.4.2 Command模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| **Command接口** | 抽象的"订单" | `Command` 接口 | +| **ConcreteCommand** | 具体的订单 | `HelpCommand`、`CrawlCommand` | +| **Invoker** | 接单的前台 | `CrawlerController` | +| **Receiver** | 执行者 | `ConsoleView`、`ArticleRepository` | + +#### 4.4.3 Command接口定义 + +```java +// src/main/java/com/crawler/command/Command.java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); // 命令名,如 "crawl" + void execute(String[] args, List
articles); // 执行逻辑 +} +``` + +#### 4.4.4 Controller的变革(从switch到Map) + +```java +// 修改后的Controller +public class CrawlerController { + private Map commands; // 用Map存命令 + private ConsoleView view; // 持有View以输出错误 + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.commands = new HashMap<>(); + // 增加命令无需改Controller代码,只需在这里注册 + commands.put("crawl", new CrawlCommand(view)); + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmd = parts[0].toLowerCase(); + + Command command = commands.get(cmd); + if (command == null) { + view.printError("Unknown command: " + cmd); // 通过View输出,而非直接System.out + return; + } + + // 执行命令,传入参数和文章列表 + command.execute(parts, articles); + } +} +``` + +**对比表格** + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改Controller | 新建一个类 | +| 多态体验 | 无 | execute()的多态调用 | +| 可测试性 | 难 | 每个Command可单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +**类比强化**: +> "Command模式就像**酒店的客房服务**:每个服务(清理、送餐、按摩)都是一个独立的部门。前台(Controller)只负责接电话,然后把请求'派发'给对应的部门。部门自己知道怎么干活,不需要前台教。" +> +> "如果想新增一个服务,前台只需要'登记'一下,不需要把现有部门重新装修。" + +--- + +### 4.5 Maven模板与环境(5分钟) + +**教师口播**: +> "这周我们不发愁pom.xml配置。我已经把 Maven 模板准备好了,你们只需要解压、打开、运行。" + +**模板使用流程**: +``` +1. 解压 [my-crawler-template.zip] +2. 用 IDEA 打开文件夹 +3. 右键 pom.xml → Maven → Reload Project +4. 运行 App.java +``` + +**标准目录结构**: +``` +src/main/java/com/crawler/ +├── model/ +│ └── Article.java +├── view/ +│ └── ConsoleView.java +├── command/ +│ ├── Command.java (接口) +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/ + └── CrawlerController.java +``` + +--- + +### 4.6 代码落地(20分钟) + +#### 4.6.1 Model层:Article实体 + +```java +// src/main/java/com/crawler/model/Article.java +package com.crawler.model; + +public class Article { + private String title; + private String url; + private String content; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { return title; } + public void setTitle(String title) { this.title = title; } + public String getUrl() { return url; } + public void setUrl(String url) { this.url = url; } + public String getContent() { return content; } + public void setContent(String content) { this.content = content; } + + @Override + public String toString() { + return "Article{title='" + title + "', url='" + url + "'}"; + } +} +``` + +#### 4.6.2 View层:ANSI常量集中管理(工程细节!) + +```java +// src/main/java/com/crawler/view/ConsoleView.java +package com.crawler.view; + +import com.crawler.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + // ANSI颜色常量——集中管理,避免散落各处 + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + private static final String ANSI_CYAN = "\033[36m"; + private static final String ANSI_RESET = "\033[0m"; + + private Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("crawler> "); + return scanner.nextLine().trim(); + } + + public void print(String msg) { + System.out.println(msg); + } + + public void printSuccess(String msg) { + print(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + print(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + print(ANSI_CYAN + msg + ANSI_RESET); + } + + // 展示文章列表 + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("No articles yet. Use 'crawl ' first."); + return; + } + print("+----------+--------------------------------+"); + print("| Title | URL |"); + print("+----------+--------------------------------+"); + for (Article a : articles) { + String title = a.getTitle(); + if (title.length() > 10) title = title.substring(0, 10) + ".."; + String url = a.getUrl(); + if (url.length() > 30) url = url.substring(0, 27) + "..."; + print("| " + String.format("%-10s", title) + " | " + url + " |"); + } + print("+----------+--------------------------------+"); + printInfo("Total: " + articles.size() + " articles"); + } +} +``` + +**教师提示**: +> "注意:所有ANSI转义码都被定义为`private static final`常量。如果把`\033[32m`散落在项目各处,一旦想调整颜色,就得满世界去改——这正是我们之前痛批的'意大利面'。**这就是工程细节**。" + +#### 4.6.3 Command接口与四个实现(全部通过View输出) + +```java +// Command.java +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} + +// HelpCommand.java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} + +// ListCommand.java +public class ListCommand implements Command { + private ConsoleView view; + public ListCommand(ConsoleView v) { this.view = v; } + public String getName() { return "list"; } + public void execute(String[] args, List
articles) { + view.display(articles); + } +} + +// CrawlCommand.java (存根) +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} + +// ExitCommand.java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); // 全部输出都通过View,绝不让System.out直接出现在这里 + System.exit(0); + } +} +``` + +**故意埋设的"找茬点"**: +> "我在刚才的代码里有没有隐藏违反MVC原则的地方?`CrawlCommand`的存根里,`view.printInfo("Stub: Would crawl " + args[1]);` —— 这个字符串拼接算是"业务逻辑"吗?留给大家用AI架构审计时讨论。 + +#### 4.6.4 Controller:Map路由(全部通过View输出) + +```java +// src/main/java/com/crawler/controller/CrawlerController.java +package com.crawler.controller; + +import com.crawler.command.*; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private Map commands = new HashMap<>(); + private ConsoleView view; // 持有View + private List
articles; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmdName = parts[0].toLowerCase(); + + Command cmd = commands.get(cmdName); + if (cmd == null) { + view.printError("Unknown command: " + cmdName); // 错误信息也走View! + return; + } + cmd.execute(parts, articles); + } +} +``` + +#### 4.6.5 main方法:组装 + +```java +// src/main/java/com/crawler/App.java +package com.crawler; + +import com.crawler.controller.CrawlerController; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class App { + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler!"); + view.printInfo("Type 'help' for commands."); + + while (true) { + controller.handle(view.readLine()); + } + } +} +``` + +#### 4.6.6 架构反思与展望:共享List
的隐患(关键!) + +**教师口播**: +> "现在这个架构已经可用了。但请大家审视一下:我们所有的Command都直接拿到了`List
`的引用。换句话说,任何一个命令都可以随意增、删、改这个列表。" +> +> "这就好像一家酒店,所有服务员、厨师、清洁工都能随意进出保险箱——**数据结构完全裸奔了**。" + +**提问**: +- "如果CrawlCommand不小心写错了代码,把一个null塞进articles,HelpCommand会不会受影响?" +- "如果未来我们要在添加文章时也写入日志文件,现在的设计能优雅实现吗?还是得在所有Command里分别加日志代码?" + +**预告解决方案**: +> "下周,我们将引入**策略模式**和一个真正的**Model仓库层(ArticleRepository)**。这个仓库会把`List`封装起来,对外只提供`add()`、`getAll()`等安全接口。任何命令想修改数据,都必须通过仓库。这就是从'数据结构'到'模型层'的进化——我们W9先搭骨架,W10给它装上盔甲。" + +--- + +### 4.7 实践任务(5分钟) + +**任务要求**: +1. 使用Maven模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现4个Command:help/list/crawl/exit +4. `list`命令能展示已抓取的文章 +5. 运行并测试循环 +6. **代码找茬(额外加分)**:找出你自己代码中是否存在`System.out`直接调用、硬编码ANSI字符串等"越权行为" + +**验收标准**: +- [x] Maven编译通过 +- [x] Command接口和4个实现分离在不同文件 +- [x] Controller里没有switch-case +- [x] 新增命令只需新建类,不改Controller +- [x] list命令能正确显示空列表 +- [x] 所有输出均通过ConsoleView完成,无直接System.out.println(main除外) +- [x] ANSI颜色码集中定义为View常量 + +--- + +## 五、课后作业 + +### 5.1 必做任务 + +1. **完善Article**:增加`author`、`publishDate`字段 +2. **★ HistoryCommand(强制作业)**: + - 实现`history`命令,记录用户输入过的所有命令 + - 使用`List`存储历史(复习W8集合) + - 示例输出: + ``` + crawler> history + 1. help + 2. list + 3. crawl https://example.com + ``` +3. **AI架构审计**:将类名和方法名发给AI,指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?Model层是否包含输入输出代码?View层是否越权写了业务逻辑?有没有地方直接使用了System.out或硬编码ANSI码?" + +### 5.2 选做任务 + +1. **命令别名**:给`crawl`增加别名`c`,`help`增加别名`h` +2. **URL验证**:检查URL格式是否以http://或https://开头 +3. **暗色主题**:实现不同的配色方案(利用View中的ANSI常量,只需修改一处即可) +4. **思考并回答**:分析`List
`共享引用的潜在风险,写一段200字的小结 + +### 5.3 思考题 + +1. **Command vs switch-case**:增加10个命令,哪种方式代码改动量更小? +2. **如果不用Command接口,直接用Map存命令类行不行?** 接口的意义是什么? +3. **Controller里的`commands.put()`能否减少?** 提示:思考"注册机制" +4. **为什么ExitCommand里的`view.printSuccess("Bye!")`比直接`System.out.println`更"MVC"?** 提示:回忆View的职责 + +--- + +## 六、AI协同升级 + +### 架构审计师任务(必做) + +**学生执行步骤**: +1. 列出项目中所有类名(不含方法实现) +2. 将类名列表发给AI +3. 输入指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否清晰。Model层是否包含了不应该有的代码(Scanner/System.out)?View层是否越权写了业务逻辑?请指出任何一处直接使用System.out.println的地方,并建议如何改正。" + +**预期AI输出**: +- 指出哪一层有越权行为 +- 建议如何整改 +- 评价整体架构健康度 + +### 进阶AI探究(选做) + +> "假设我的Command接口中execute方法接收了一个`List
`参数,请分析这种设计在工程上有什么隐患,并给出重构建议。" + +--- + +## 七、教学反思与调整记录 + +| 日期 | 事项 | 调整内容 | +|------|------|----------| +| 2026-04-28 | 首次编写 | 基于CLI+MVC重构 | +| 2026-04-30 | 教授反馈 | 引入Command模式、提供Maven模板、升级AI协同比 | +| 2026-04-30 | 逻辑重排 | 按"问题→选择→架构→模式"顺序重写 | +| 2026-05-01 | v2 vs V3合并 | 融合深度改进:增加教育哲学、批判性思考、ANSI常量、共享List隐患、故意埋坑 | + +--- + +## 附录1:Maven模板说明 + +> 老师提供`my-crawler-template.zip`压缩包,包含: +> - pom.xml(含Jsoup依赖) +> - 空的src/main/java结构 +> - .gitignore + +## 附录2:常见问题速查 + +| 问题 | 解答 | +|------|------| +| IDEA不识别pom.xml | 右键 pom.xml → Maven → Reload Project | +| 中文乱码 | Settings → Editor → File Encodings → UTF-8 | +| 包名大小写 | 包名全小写,类名首字母大写 | +| Command找不到 | 检查是否 implements Command,是否 @Override getName() | +| 命令不生效 | 检查 commands.put() 是否注册了该命令 | +| 输出颜色乱码 | IDEA控制台需支持ANSI,Windows下建议使用Windows Terminal或调整设置 | +| 我的System.out为什么被老师说越权 | View层才是与用户交互的唯一出口,所有输出都应通过View,这样将来改成GUI或日志时只需改View | + +## 附录3:教学逻辑说明 + +| 顺序 | 内容 | 设计理由 | +|------|------|----------| +| 1 | 痛点引入 | 从问题出发,让学生感受"为什么需要架构" | +| 2 | CLI vs GUI | 解释技术选型,建立"工程思维 > 视觉装饰"的认知 | +| 3 | MVC分层 | 核心架构概念,理解职责分离,通过类比及批判加深理解 | +| 4 | Command模式 | 具体实现方式,解决"肥控制器"问题 | +| 5 | Maven | 工具链支持 | +| 6 | 代码落地 | 实践验证,刻意植入细节规范,训练工程洁癖 | +| 7 | 架构反思 | 暴露共享可变状态隐患,为W10策略模式+仓库层做铺垫 | +| 8 | 实践任务 | 现场编码验证 | +| 9 | 总结 | 强化认知,预告下周 | + +--- + +## 版本说明 + +- **v1**:首次编写,CLI+MVC基础框架 +- **v2**:按"问题→选择→架构→模式"逻辑重排 +- **v3 (本版)**:融合v2结构 + V3深度改进,包含: + - 更深的CLI教育哲学 + - 餐厅类比批判性思考 + - ANSI常量集中管理工程细节 + - 全部输出走View + - 共享List架构隐患反思 + - 故意埋坑让学生找茬 + - W10铺垫(策略模式+仓库层) \ No newline at end of file diff --git a/w9/选做/java-cli/java-cli/target/maven-archiver/pom.properties b/w9/选做/java-cli/java-cli/target/maven-archiver/pom.properties new file mode 100644 index 0000000..08a8f9f --- /dev/null +++ b/w9/选做/java-cli/java-cli/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 30 11:50:54 CST 2026 +artifactId=datacollect-cli +groupId=com.example +version=0.1.0 diff --git a/w9/选做/java-cli/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/w9/选做/java-cli/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/w9/选做/java-cli/java-cli/target/w9-ppt.md b/w9/选做/java-cli/java-cli/target/w9-ppt.md new file mode 100644 index 0000000..5ddd5ad --- /dev/null +++ b/w9/选做/java-cli/java-cli/target/w9-ppt.md @@ -0,0 +1,530 @@ +## 高级程序设计 · 第9周 + +#### 工程架构:从"写代码"到"造系统" + +##### CLI + MVC + Command模式实战 + +--- + +### 📌 本周导航 + +- 痛点引入:脚本的宿命 +- CLI vs GUI:为什么选命令行? +- MVC分层:职责分离的艺术 +- Command模式:可扩展的路由 +- Maven模板:工程化第一步 +- 代码落地:从接口到实现 +- 架构反思:共享数据的隐患 +- 实践任务 + 课后作业 + +--- + +### 1️⃣ 痛点引入:从脚本到工程的鸿沟 + +#### 这是一段“意大利面”爬虫 + +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +--- + +### 脚本的三大痛点 + +| 需求 | 需要改哪里? | +|------|--------------| +| 保存标题到文件 | 改 main 内部逻辑 | +| 支持不同网站结构 | 全部重写解析代码 | +| 彩色输出 | 一个一个改 print | + +> 😫 **牵一发而动全身 → 改起来疼** + +### 本周目标:**让代码“改起来不疼”** + +--- + +## 2️⃣ CLI vs GUI:架构选择的思考 + +### 图形界面 vs 命令行 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| 学习重心 | 布局、控件、事件 | **架构、分层、路由** | +| 后端能力 | 弱 | 模拟真实服务器 | +| 工程思维 | 弱(关注视觉) | **强(关注逻辑)** | +| 可测试性 | 难 | 易 | + +--- + +## 核心观点 + +> **CLI 更需要 MVC!** + +- GUI 有现成事件系统,框架强塞给你一套架构 +- CLI 只有字符流 → **没有架构,分分钟写成脚本** + +> 🎯 **当外部约束消失,内部的工程纪律才真正开始建立** + +### CLI 也能很酷 + +- ANSI 彩色输出 +- 表格展示数据 +- 模拟大数据/后端开发 + +--- + +## 3️⃣ MVC 分层设计 + +### MVC 的起源与演进 + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +**核心不变:职责分离** + +--- + +## MVC 三层职责 + +![[mvc.png]] +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ 只管"派给谁",不管"怎么做" │ +└─────────┬───────────────┬───────────────┘ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ 管"数据" │ │ 管"呈现" │ +│ + 业务逻辑 │ │ + 输入输出 │ +└─────────────────┘ └─────────────────┘ +``` + +--- + +## 三层“禁止做什么” + +| 层级 | 禁止行为 | +| -------------- | -------------------------------------- | +| **Model** | 不能有 `System.out.println`,不能有 `Scanner` | +| **View** | 不能写爬虫逻辑,只做“传声筒” | +| **Controller** | 不能直接写业务细节,委托给 Command | + +> 🔴 **越权就是架构腐败的开始** + +--- + +## 🍽️ 餐厅类比(帮助理解) + +- **Model = 后厨**:只管做菜,不管谁来吃、怎么端 +- **View = 服务员**:只管端菜和收钱,不管菜怎么做 +- **Controller = 前台**:接单 → 派给后厨 → 叫服务员上菜 + +--- + +## 🤔 对类比的批判性思考(关键!) + +> 任何类比都有边界,不要当成真理 + +| 场景 | 暴露的问题 | +|------|------------| +| 客人有忌口(不吃香菜) | 信息需要传到后厨 → Model 可能需要知道 meta 信息 | +| 服务员反馈“今天的菜咸了” | View → Model 反向影响 | +| 后厨做完菜通知前台 | **观察者模式**,数据流可能是双向的 | + +**本课程简化模型**:请求-响应,单向流 + +--- + +## MVC 数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +## 4️⃣ Command 模式:可扩展的命令路由 + +### 为什么需要 Command 模式? + +```java +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +> 每加一个功能,就要在这个类里戳一个洞 → **肥控制器陷阱** + +--- + +## Command 模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| Command接口 | 抽象的“订单” | `Command` | +| ConcreteCommand | 具体的订单 | `HelpCommand` | +| Invoker | 接单的前台 | `CrawlerController` | +| Receiver | 执行者 | `ConsoleView`、`ArticleRepository` | + +--- + +## Command 接口定义 + +```java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} +``` + +--- + +## Controller 的变革:从 switch 到 Map + +```java +public class CrawlerController { + private Map commands = new HashMap<>(); + + public CrawlerController(ConsoleView view, List
articles) { + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + // 解析命令 → 从 Map 取 Command → 调用 execute + } +} +``` + +> **增加新命令:只需新建类,Controller 零改动!** + +--- + +## 对比:switch-case vs Command + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改 Controller | 新建一个类 | +| 多态体验 | 无 | `execute()` 多态 | +| 可测试性 | 难 | 每个 Command 单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +> 🏨 **类比:酒店客房服务,前台只负责派单** + +--- + +## 5️⃣ Maven 模板与环境(5分钟) + +### 直接使用模板,不折腾配置 + +``` +my-crawler-template.zip + ↓ 解压 + IDEA打开 + ↓ 右键 pom.xml → Maven → Reload Project + ↓ 运行 App.java +``` + +### 标准目录结构 + +``` +src/main/java/com/crawler/ +├── model/Article.java +├── view/ConsoleView.java +├── command/ +│ ├── Command.java +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/CrawlerController.java +``` + +--- + +## 6️⃣ 代码落地(分步实现) + +### Model:Article 实体 + +```java +public class Article { + private String title; + private String url; + private String content; + // 构造器、getter/setter、toString +} +``` + +> 📦 只存放数据,没有任何输入输出代码 + +--- + +## View:ConsoleView(ANSI常量集中管理) + +```java +public class ConsoleView { + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + // ... 其他常量 + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + public void printError(String msg) { ... } + public void display(List
articles) { ... } +} +``` + +> ✨ **所有颜色码集中定义 → 改主题只需改一处** + +--- + +## Command 实现示例(HelpCommand) + +```java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} +``` + +> ⚠️ 全部输出通过 `view`,绝不让 `System.out` 直接出现在这里 + +--- + +## CrawlCommand(存根,下周填坑) + +```java +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} +``` + +> 🔍 **找茬点**:这里拼接字符串算是“业务逻辑”吗?留给大家用 AI 审计。 + +--- + +## ExitCommand + +```java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} +``` + +> ✅ 所有输出都通过 View → 将来改 GUI 只需换 View 实现 + +--- + +## Controller + main 组装 + +```java +// Controller 中持有 Map +// App.java 中: +ConsoleView view = new ConsoleView(); +List
articles = new ArrayList<>(); +CrawlerController controller = new CrawlerController(view, articles); +view.printSuccess("Welcome to CLI Crawler!"); +while (true) { + controller.handle(view.readLine()); +} +``` + +> 🔁 完成交互循环 + +--- + +## 7️⃣ 架构反思:共享 List
的隐患 + +### 当前问题 + +- 所有 Command 都直接拿到 `List
` 引用 +- 任何一个命令都可以随意增、删、改列表 +- 数据完全“裸奔” + +> 🚨 就像酒店所有员工都能进保险箱 + +--- + +## 提问 + +- 如果 `CrawlCommand` 不小心把 `null` 塞进列表,`ListCommand` 会怎样? +- 如果我们要在添加文章时写日志,现在的设计能优雅实现吗? + +### 预告解决方案(W10) + +- **策略模式** + **仓库层(ArticleRepository)** +- 封装 `List`,对外只暴露 `add()`、`getAll()` 等安全接口 + +> W9 搭骨架,W10 装上盔甲 + +--- + +## 8️⃣ 实践任务(现场5分钟) + +### 必做项 + +1. 使用 Maven 模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现 4 个 Command:help / list / crawl / exit +4. `list` 能展示已抓取的文章(目前存根即可) +5. 运行并测试循环 + +### 额外加分:代码找茬 + +- 检查是否仍有 `System.out` 直接调用 +- 检查 ANSI 码是否硬编码在多个地方 + +--- + +## 验收标准 + +- [x] Maven 编译通过 +- [x] Command 接口和 4 个实现在不同文件 +- [x] Controller 里没有 switch-case +- [x] 新增命令只需新建类,不改 Controller +- [x] list 能正确显示空列表 +- [x] 所有输出均通过 `ConsoleView` +- [x] ANSI 颜色码集中定义为常量 + +--- + +## 9️⃣ 课后作业 + +### 必做 + +1. **完善 Article**:增加 `author`、`publishDate` 字段 +2. **★ HistoryCommand**:记录用户输入过的所有命令(用 `List`) +3. **AI 架构审计**:将类名发给 AI,指令: + > “作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?” + +### 选做 + +- 命令别名(c 代替 crawl) +- URL 格式验证 +- 暗色主题(修改一处常量) +- 思考题:分析 `List
` 共享引用的风险(200字小结) + +--- + +## 🤖 AI 协同升级 + +### 架构审计师任务(必做) + +**步骤**: +1. 列出所有类名(不含方法实现) +2. 发给 AI +3. 指令:“检查 MVC 分层是否清晰,是否有越权行为” + +### 进阶探究(选做) + +> “假设我的 Command 接口中 execute 方法接收了一个 `List
` 参数,请分析这种设计在工程上有什么隐患,并给出重构建议。” + +--- + +## 📚 总结与过渡 + +### 本周成果 + +- ✅ 工程化包结构 +- ✅ MVC 分层清晰 +- ✅ Command 模式实现可扩展路由 +- ✅ 所有输出走 View,常量集中管理 + +### 下周预告 + +- **策略模式**:封装爬取算法 +- **仓库层(Repository)**:武装 `List
`,解决共享隐患 + +> 🚀 从“写代码”到“造系统”,踏出坚实第一步! + +--- + +## Q&A + +### 常见问题 + +| 问题 | 解答 | +|------|------| +| IDEA 不识别 pom.xml | 右键 → Maven → Reload Project | +| 中文乱码 | Settings → File Encodings → UTF-8 | +| 输出颜色乱码 | Windows 建议使用 Windows Terminal | +| 我的 System.out 被批评 | View 才是唯一输出出口 | + +--- + +## 谢谢! + +### 课件已上传,模板在课程群 + +**保持工程洁癖,下周见!** \ No newline at end of file diff --git a/w9/选做/java-cli/pom.xml b/w9/选做/java-cli/pom.xml new file mode 100644 index 0000000..01bc611 --- /dev/null +++ b/w9/选做/java-cli/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + com.example + datacollect-cli + 0.1.0 + + 11 + 11 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + + com.example.datacollect.Main + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/Main.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/Main.java new file mode 100644 index 0000000..44d00aa --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/Main.java @@ -0,0 +1,21 @@ +package com.example.datacollect; + +import com.example.datacollect.controller.CrawlerController; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class Main { + + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler (w9_1)! Type help for commands."); + while (true) { + controller.handle(view.readLine()); + } + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/command/Command.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/Command.java new file mode 100644 index 0000000..24e59a6 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/Command.java @@ -0,0 +1,9 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java new file mode 100644 index 0000000..c448754 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/CrawlCommand.java @@ -0,0 +1,40 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; +import java.util.regex.Pattern; + +public class CrawlCommand implements Command { + private final ConsoleView view; + private static final Pattern URL_PATTERN = Pattern.compile( + "^https?://[\\w\\-]+(\\.[\\w\\-]+)+([\\w\\-.,@?^=%&:/~+#]*[\\w\\-@?^=%&/~+#])?$" + ); + + public CrawlCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "crawl"; + } + + @Override + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + String url = args[1]; + if (!isValidUrl(url)) { + view.printError("Invalid URL format: " + url); + return; + } + view.printInfo("Stub: would crawl " + url); + } + + private boolean isValidUrl(String url) { + return url != null && URL_PATTERN.matcher(url).matches(); + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java new file mode 100644 index 0000000..6946d85 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/ExitCommand.java @@ -0,0 +1,24 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ExitCommand implements Command { + private final ConsoleView view; + + public ExitCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "exit"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java new file mode 100644 index 0000000..a657f70 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/HelpCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HelpCommand implements Command { + private final ConsoleView view; + + public HelpCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "help"; + } + + @Override + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit, history"); + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java new file mode 100644 index 0000000..2b79929 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/HistoryCommand.java @@ -0,0 +1,36 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class HistoryCommand implements Command { + private final ConsoleView view; + private final List history; + + public HistoryCommand(ConsoleView view, List history) { + this.view = view; + this.history = history; + } + + @Override + public String getName() { + return "history"; + } + + @Override + public void execute(String[] args, List
articles) { + if (history.isEmpty()) { + view.printInfo("No command history."); + return; + } + view.printInfo("Command history:"); + for (int i = 0; i < history.size(); i++) { + view.printInfo((i + 1) + ". " + history.get(i)); + } + } + + public void addCommand(String command) { + history.add(command); + } +} \ No newline at end of file diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java new file mode 100644 index 0000000..8eba2cd --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/command/ListCommand.java @@ -0,0 +1,23 @@ +package com.example.datacollect.command; + +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.List; + +public class ListCommand implements Command { + private final ConsoleView view; + + public ListCommand(ConsoleView view) { + this.view = view; + } + + @Override + public String getName() { + return "list"; + } + + @Override + public void execute(String[] args, List
articles) { + view.display(articles); + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java new file mode 100644 index 0000000..e8fd711 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/controller/CrawlerController.java @@ -0,0 +1,58 @@ +package com.example.datacollect.controller; + +import com.example.datacollect.command.Command; +import com.example.datacollect.command.CrawlCommand; +import com.example.datacollect.command.ExitCommand; +import com.example.datacollect.command.HelpCommand; +import com.example.datacollect.command.HistoryCommand; +import com.example.datacollect.command.ListCommand; +import com.example.datacollect.model.Article; +import com.example.datacollect.view.ConsoleView; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private final Map commands = new HashMap<>(); + private final ConsoleView view; + private final List
articles; + private final List commandHistory = new ArrayList<>(); + private HistoryCommand historyCommand; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + historyCommand = new HistoryCommand(view, commandHistory); + register(new HelpCommand(view)); + register(new ListCommand(view)); + register(new CrawlCommand(view)); + register(new ExitCommand(view)); + register(historyCommand); + } + + private void register(Command command) { + commands.put(command.getName(), command); + if (command.getName().equals("crawl")) { + commands.put("c", command); + } + } + + public void handle(String input) { + String text = input == null ? "" : input.trim(); + if (text.isEmpty()) { + return; + } + + historyCommand.addCommand(text); + + String[] args = text.split("\\s+"); + String cmdName = args[0].toLowerCase(); + Command command = commands.get(cmdName); + if (command == null) { + view.printError("Unknown command: " + cmdName); + return; + } + command.execute(args, articles); + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/model/Article.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/model/Article.java new file mode 100644 index 0000000..a19e3ed --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/model/Article.java @@ -0,0 +1,65 @@ +package com.example.datacollect.model; + +public class Article { + private String title; + private String url; + private String content; + private String author; + private String publishDate; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + 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 String getPublishDate() { + return publishDate; + } + + public void setPublishDate(String publishDate) { + this.publishDate = publishDate; + } + + @Override + public String toString() { + return "Article{" + + "title='" + title + '\'' + + ", url='" + url + '\'' + + ", author='" + author + '\'' + + ", publishDate='" + publishDate + '\'' + + '}'; + } +} diff --git a/w9/选做/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java b/w9/选做/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java new file mode 100644 index 0000000..59b3ad5 --- /dev/null +++ b/w9/选做/java-cli/src/main/java/com/example/datacollect/view/ConsoleView.java @@ -0,0 +1,42 @@ +package com.example.datacollect.view; + +import com.example.datacollect.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_BLUE = "\u001B[94m"; + + private final Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("> "); + return scanner.nextLine(); + } + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + System.out.println(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + System.out.println(ANSI_BLUE + msg + ANSI_RESET); + } + + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("暂无文章,请先执行 crawl。"); + return; + } + for (int i = 0; i < articles.size(); i++) { + Article a = articles.get(i); + System.out.println((i + 1) + ". " + a.getTitle() + " | " + a.getUrl()); + } + } +} diff --git a/w9/选做/java-cli/target/W9工程架构 - 教案v3.md b/w9/选做/java-cli/target/W9工程架构 - 教案v3.md new file mode 100644 index 0000000..09de868 --- /dev/null +++ b/w9/选做/java-cli/target/W9工程架构 - 教案v3.md @@ -0,0 +1,758 @@ +--- + +# 教案:《高级程序设计》第9周——工程架构:从"写代码"到"造系统" + +| 项目 | 内容 | +|------|------| +| **课程名称** | 高级程序设计 | +| **周次** | 第9周 | +| **主题** | 工程架构——从"写代码"到"造系统" | +| **学时** | 2学时(90分钟) | +| **授课对象** | 具备Python基础、已完成Java面向对象特性学习的学生 | +| **教学环境** | JDK 17+、IntelliJ IDEA、Maven(模板) | +| **前情提要** | 本课程原计划使用JavaFX GUI,后根据教学反馈转向CLI + MVC + 爬虫工程化 | + +--- + +## 教学调整说明:为什么选择CLI而不是GUI? + +> **原计划**:JavaFX桌面应用 → **新计划**:CLI命令行应用 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **学生痛点** | "窗口点击"与后端能力无关 | 真正锻炼工程思维 | +| **AI辅助** | AI生成FXML,学生看不懂 | AI辅助重构架构 | +| **工程化** | 脱离真实后端开发场景 | 模拟真实服务器/大数据开发 | +| **核心转型** | "视觉装饰"优先 | "逻辑架构"优先 | + +**决策理由**: +1. **985学生需要的是工程思维**,不是拖控件 +2. **接口抽象**是弱项,CLI + MVC更能暴露这个问题 +3. **彩色终端**足够酷炫,且代码量可控 + +**更深层的教育价值**: +> 在GUI框架中,架构已被框架强制划定,学生只是"遵守规矩";而CLI世界里没有任何框架告诉你模型在哪、视图在哪——**当外部约束消失,内部的工程纪律才真正建立**。这正是本节课要传递的核心精神。 + +--- + +## 一、教学目标 + +| 目标维度 | 具体描述 | +|----------|----------| +| **知识掌握** | 理解MVC架构的职责划分及其演化脉络;掌握Maven项目结构与pom.xml基础;理解Command模式的路由原理。 | +| **工程实践** | 能搭建规范的Maven项目包结构;能实现基于Scanner的控制台交互;能用Command接口实现可扩展的命令路由;能识别架构中的"越权行为"。 | +| **思维转型** | 从"一个类写全部"转向"分层解耦";从"修改现有代码"转向"新增类实现功能";从"满足功能"转向"代码的工程洁癖"。 | +| **工具应用** | 利用AI辅助审查MVC职责越权;让AI扮演"架构审计师"检查分层是否清晰;理解AI生成代码中的架构缺陷。 | + +--- + +## 二、教学重点与难点 + +| 项目 | 内容 | 突破方法 | +|------|------|----------| +| **重点** | MVC三层职责划分、CLI交互实现、Command接口解耦、代码中的工程细节(常量、输出归属) | 以"新增命令需要改什么"为切入点,展示Command模式的优势;通过现场"代码找茬"强化细节意识 | +| **难点** | Controller不写业务逻辑、Command接口的多态实现、共享数据模型的设计缺陷识别 | 现场演示:增加一个命令只需新建类,无需修改Controller;暴露`List
`共享引用的问题并预告解决方案 | + +--- + +## 三、教学过程设计(90分钟) + +| 环节 | 时间 | 教学内容 | 师生活动 | AI协同点 | +|------|------|----------|----------|----------| +| **1. 痛点引入:从脚本到工程的鸿沟** | 10' | 展示"意大利面"式爬虫代码,演示改一处需要动全身 | **教师演示**:现场展示一段混乱代码,让学生找问题 | 用AI分析代码耦合度 | +| **2. CLI vs GUI:架构选择的思考** | 10' | 对比两种方案的优缺点,解释为什么CLI更适合培养工程思维 | **教师讲解**:用对比表格说明选择CLI的理由 | — | +| **3. MVC分层设计** | 20' | 讲解Model/View/Controller三层职责,用"餐厅类比"强化理解,随后批判类比局限性 | **教师讲解**:配合架构图讲解三层交互,引导学生寻找类比破绽 | 用AI生成MVC职责对照表 | +| **4. Command模式:可扩展的命令路由** | 15' | 引入Command接口,解释"一个命令就是一个类" | **类比**:Command像酒店的服务部门,Controller是前台 | 让AI解释Command模式的多态原理 | +| **5. Maven模板与环境** | 5' | 直接使用提供的Maven模板,讲解目录结构 | **教师演示**:解压模板 → IDEA打开 → 运行 | — | +| **6. 三层代码落地** | 20' | **Model**:Article实体
**View**:ConsoleView(ANSI常量)
**Command接口**+实现
**Controller**:Map路由 | **教师演示**:分步写出代码,刻意埋入1~2个"越权细节"让学生找茬 | 学生用AI做"架构审计" | +| **7. 架构反思与展望** | 5' | 指出当前`List
`共享引用的问题,预告W10策略模式与仓库层 | **师生互动**:你发现这个设计有什么风险? | 让AI分析共享可变状态的危害 | +| **8. 实践任务:空壳程序** | 5' | 搭建完整包结构,实现CLI循环 | 学生现场编码,教师巡视 | 完成后用AI检查包结构 | +| **9. 总结与过渡** | 5' | 本周实现了"骨架+命令可扩展",下周填入"灵魂"——解析器,并解决数据安全问题 | 总结Command模式优势,预告策略模式 | — | + +--- + +## 四、核心教学内容脚本 + +### 4.1 痛点引入:从脚本到工程的鸿沟(10分钟) + +**教师口播**: +> "同学们,前8周我们学的是Java语法,从变量到类,从继承到接口。但有一个问题:代码写完之后,怎么组织?" +> +> "来看这段代码——这是某个同学写的'爬虫',他一个人完成了一个'完整'的项目。" + +**展示"脚本式"代码**: +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +**提问引导**: +1. "如果我想把标题保存到文件,要改哪里?" +2. "如果我想支持另一个网站,它的HTML结构不一样,要怎么办?" +3. "如果我想让输出变成彩色,要改哪里?" + +**痛点提炼**: +> "看到了吗?才60行代码,已经'牵一发而动全身'了。这就是一个'脚本'的宿命——功能全混在一起,改一个小需求,整个文件都要翻。" +> +> "这周我们要解决:**怎么让代码'改起来不疼'?**" + +--- + +### 4.2 CLI vs GUI:架构选择的思考(10分钟) + +**教师口播**: +> "既然要写一个'完整'的爬虫应用,我们有两个选择:图形界面(GUI)或命令行界面(CLI)。为什么我推荐CLI而不是GUI?" + +**对比表格** + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| **代码量** | FXML + Controller + CSS,大量模板代码 | 纯Java,代码量可控 | +| **学习重心** | 布局、控件、事件监听 | 架构、分层、命令路由 | +| **后端能力** | 几乎无关 | 模拟真实服务器开发 | +| **可测试性** | 难(需要UI测试框架) | 易(直接测试Command类) | +| **工程思维** | 弱(关注视觉) | 强(关注逻辑) | + +**核心观点**: +> **CLI更需要MVC!** GUI有现成的事件系统(点击按钮→触发事件),而CLI只有字符流。**没有架构,分分钟写成脚本**。MVC在CLI里是"刚需",不是"装饰"。 +> +> **更深一层**:在GUI里,框架已经硬塞给你一套架构,你只是在填空;但在CLI里,所有结构都必须由你亲手搭建。**当外部约束消失,内部的工程纪律才真正开始建立**——这才是本节课的真正目的。 + +**CLI也能很酷**: +- ANSI彩色输出(红/绿/黄/蓝) +- 表格展示数据 +- 进度条动画 +- 模拟真实大数据开发场景 + +--- + +### 4.3 MVC分层设计(20分钟) + +#### 4.3.1 MVC的起源与演进 + +**教师口播**: +> "MVC不是新东西,它是1970年代为桌面应用设计的架构思想。但它的核心——'职责分离'——在任何软件里都适用。" + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +#### 4.3.2 从GUI到CLI的映射 + +| GUI组件 | CLI对应 | 说明 | +|--------|--------|------| +| 窗口/按钮 | 命令行输入 | **View = 用户交互** | +| 数据模型 | Article实体类 | **Model = 数据结构** | +| 事件监听 | Command路由 | **Controller = 调度** | + +#### 4.3.3 MVC三层职责 + +**架构图示**: + +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ - 接收命令(crawl, help, exit) │ +│ - 分发给对应的Command │ +│ 【口诀】:Controller不管"怎么做", │ +│ 只管"派给谁" │ +└─────────┬───────────────┬───────────────┘ + │ │ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ - 数据实体 │ │ - 输入解析 │ +│ - 业务逻辑 │ │ - 输出格式化 │ +│ 【口诀】: │ │ 【口诀】: │ +│ Model管"数据" │ │ View管"呈现" │ +└─────────────────┘ └─────────────────┘ +``` + +**三层职责详解** + +| 层级 | 职责 | 典型代码 | 禁止做什么 | +|------|------|----------|------------| +| **Model** | 数据结构 + 业务逻辑 | `class Article { String title; String content; }` | 不能有`System.out.println`,不能有`Scanner` | +| **View** | 接收用户输入 + 格式化输出 | `class ConsoleView { String readInput(); void print(String); }` | 不能写爬虫逻辑,只做"传声筒" | +| **Controller** | 协调调度 | `class CrawlerController { void handle(String cmd) { ... } }` | 不能直接写业务细节,委托给Command | + +#### 4.3.4 类比强化:"餐厅类比" + +> "把MVC想象成一家餐厅: +> - **Model是后厨**:只管做菜(数据加工),不管谁来吃、怎么端 +> - **View是服务员**:只管端菜和收钱(输入输出),不管菜怎么做 +> - **Controller是前台**:只管把顾客的点单传给后厨,把做好的菜端给顾客 +> +> 如果后厨开始管'谁来吃饭',这餐厅就乱了。" + +#### 4.3.5 对"餐厅类比"的批判性思考(关键!) + +**教师导引**: +> "刚才的类比好理解吗?很好。但任何一个类比都有它的边界,如果把它当成真理,就会出问题。现在我们来给这个类比'找茬'。" + +**提问学生**: +1. "后厨真的完全不知道客人是谁吗?如果客人有忌口(比如不吃香菜),这个信息需不需要传到后厨?" +2. "服务员只是端菜吗?在真实餐厅里,服务员经常向后厨反馈'客人觉得今天的菜咸了',这属于View→Model的反向影响吗?" +3. "在这个类比里,我们把前台(Controller)和后厨(Model)的关系说成单向的。但实际上,后厨做完了菜,需要通知前台'菜好了',这不就是**观察者模式**吗?" + +**点明本质**: +> "实际MVC的数据流向常常是**双向**的:Controller调用Model的方法改变数据,Model变化后又通知View更新显示。只不过在本次CLI项目中,我们暂时使用'请求-响应'的单向简化模型——用户输入命令,系统处理,然后立即输出结果。这个简化版够用,但你要知道完整的MVC是更动态的。随着系统复杂,Model层需要一个专门的'仓库类'来管理数据,并通知视图刷新——这正是W10我们将要深入的内容。" + +#### 4.3.6 MVC的数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,目前暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +### 4.4 Command模式:可扩展的命令路由(15分钟) + +**教师口播**: +> "现在引入一个设计模式——Command(命令)模式。它的核心思想是:**一个命令就是一个类**。" + +#### 4.4.1 为什么需要Command模式? + +**演示:增加一个命令的代价(switch-case版)** +```java +// 现状代码 +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +**提问**: +- "如果我想增加10个命令,这个类要改多少次?" +- "如果我不小心删了一个case,整个程序还能跑吗?" + +**痛点提炼**: +> "每加一个功能,就要在这个类里戳一个洞。**这就是'肥控制器'陷阱**——所有的逻辑都堆在Controller里,它变成了新的'意大利面'。" + +#### 4.4.2 Command模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| **Command接口** | 抽象的"订单" | `Command` 接口 | +| **ConcreteCommand** | 具体的订单 | `HelpCommand`、`CrawlCommand` | +| **Invoker** | 接单的前台 | `CrawlerController` | +| **Receiver** | 执行者 | `ConsoleView`、`ArticleRepository` | + +#### 4.4.3 Command接口定义 + +```java +// src/main/java/com/crawler/command/Command.java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); // 命令名,如 "crawl" + void execute(String[] args, List
articles); // 执行逻辑 +} +``` + +#### 4.4.4 Controller的变革(从switch到Map) + +```java +// 修改后的Controller +public class CrawlerController { + private Map commands; // 用Map存命令 + private ConsoleView view; // 持有View以输出错误 + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.commands = new HashMap<>(); + // 增加命令无需改Controller代码,只需在这里注册 + commands.put("crawl", new CrawlCommand(view)); + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmd = parts[0].toLowerCase(); + + Command command = commands.get(cmd); + if (command == null) { + view.printError("Unknown command: " + cmd); // 通过View输出,而非直接System.out + return; + } + + // 执行命令,传入参数和文章列表 + command.execute(parts, articles); + } +} +``` + +**对比表格** + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改Controller | 新建一个类 | +| 多态体验 | 无 | execute()的多态调用 | +| 可测试性 | 难 | 每个Command可单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +**类比强化**: +> "Command模式就像**酒店的客房服务**:每个服务(清理、送餐、按摩)都是一个独立的部门。前台(Controller)只负责接电话,然后把请求'派发'给对应的部门。部门自己知道怎么干活,不需要前台教。" +> +> "如果想新增一个服务,前台只需要'登记'一下,不需要把现有部门重新装修。" + +--- + +### 4.5 Maven模板与环境(5分钟) + +**教师口播**: +> "这周我们不发愁pom.xml配置。我已经把 Maven 模板准备好了,你们只需要解压、打开、运行。" + +**模板使用流程**: +``` +1. 解压 [my-crawler-template.zip] +2. 用 IDEA 打开文件夹 +3. 右键 pom.xml → Maven → Reload Project +4. 运行 App.java +``` + +**标准目录结构**: +``` +src/main/java/com/crawler/ +├── model/ +│ └── Article.java +├── view/ +│ └── ConsoleView.java +├── command/ +│ ├── Command.java (接口) +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/ + └── CrawlerController.java +``` + +--- + +### 4.6 代码落地(20分钟) + +#### 4.6.1 Model层:Article实体 + +```java +// src/main/java/com/crawler/model/Article.java +package com.crawler.model; + +public class Article { + private String title; + private String url; + private String content; + + public Article(String title, String url, String content) { + this.title = title; + this.url = url; + this.content = content; + } + + public String getTitle() { return title; } + public void setTitle(String title) { this.title = title; } + public String getUrl() { return url; } + public void setUrl(String url) { this.url = url; } + public String getContent() { return content; } + public void setContent(String content) { this.content = content; } + + @Override + public String toString() { + return "Article{title='" + title + "', url='" + url + "'}"; + } +} +``` + +#### 4.6.2 View层:ANSI常量集中管理(工程细节!) + +```java +// src/main/java/com/crawler/view/ConsoleView.java +package com.crawler.view; + +import com.crawler.model.Article; +import java.util.List; +import java.util.Scanner; + +public class ConsoleView { + // ANSI颜色常量——集中管理,避免散落各处 + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + private static final String ANSI_CYAN = "\033[36m"; + private static final String ANSI_RESET = "\033[0m"; + + private Scanner scanner = new Scanner(System.in); + + public String readLine() { + System.out.print("crawler> "); + return scanner.nextLine().trim(); + } + + public void print(String msg) { + System.out.println(msg); + } + + public void printSuccess(String msg) { + print(ANSI_GREEN + msg + ANSI_RESET); + } + + public void printError(String msg) { + print(ANSI_RED + msg + ANSI_RESET); + } + + public void printInfo(String msg) { + print(ANSI_CYAN + msg + ANSI_RESET); + } + + // 展示文章列表 + public void display(List
articles) { + if (articles.isEmpty()) { + printInfo("No articles yet. Use 'crawl ' first."); + return; + } + print("+----------+--------------------------------+"); + print("| Title | URL |"); + print("+----------+--------------------------------+"); + for (Article a : articles) { + String title = a.getTitle(); + if (title.length() > 10) title = title.substring(0, 10) + ".."; + String url = a.getUrl(); + if (url.length() > 30) url = url.substring(0, 27) + "..."; + print("| " + String.format("%-10s", title) + " | " + url + " |"); + } + print("+----------+--------------------------------+"); + printInfo("Total: " + articles.size() + " articles"); + } +} +``` + +**教师提示**: +> "注意:所有ANSI转义码都被定义为`private static final`常量。如果把`\033[32m`散落在项目各处,一旦想调整颜色,就得满世界去改——这正是我们之前痛批的'意大利面'。**这就是工程细节**。" + +#### 4.6.3 Command接口与四个实现(全部通过View输出) + +```java +// Command.java +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} + +// HelpCommand.java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} + +// ListCommand.java +public class ListCommand implements Command { + private ConsoleView view; + public ListCommand(ConsoleView v) { this.view = v; } + public String getName() { return "list"; } + public void execute(String[] args, List
articles) { + view.display(articles); + } +} + +// CrawlCommand.java (存根) +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} + +// ExitCommand.java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); // 全部输出都通过View,绝不让System.out直接出现在这里 + System.exit(0); + } +} +``` + +**故意埋设的"找茬点"**: +> "我在刚才的代码里有没有隐藏违反MVC原则的地方?`CrawlCommand`的存根里,`view.printInfo("Stub: Would crawl " + args[1]);` —— 这个字符串拼接算是"业务逻辑"吗?留给大家用AI架构审计时讨论。 + +#### 4.6.4 Controller:Map路由(全部通过View输出) + +```java +// src/main/java/com/crawler/controller/CrawlerController.java +package com.crawler.controller; + +import com.crawler.command.*; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CrawlerController { + private Map commands = new HashMap<>(); + private ConsoleView view; // 持有View + private List
articles; + + public CrawlerController(ConsoleView view, List
articles) { + this.view = view; + this.articles = articles; + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + if (input.isEmpty()) return; + String[] parts = input.split("\\s+"); + String cmdName = parts[0].toLowerCase(); + + Command cmd = commands.get(cmdName); + if (cmd == null) { + view.printError("Unknown command: " + cmdName); // 错误信息也走View! + return; + } + cmd.execute(parts, articles); + } +} +``` + +#### 4.6.5 main方法:组装 + +```java +// src/main/java/com/crawler/App.java +package com.crawler; + +import com.crawler.controller.CrawlerController; +import com.crawler.model.Article; +import com.crawler.view.ConsoleView; +import java.util.ArrayList; +import java.util.List; + +public class App { + public static void main(String[] args) { + ConsoleView view = new ConsoleView(); + List
articles = new ArrayList<>(); + CrawlerController controller = new CrawlerController(view, articles); + + view.printSuccess("Welcome to CLI Crawler!"); + view.printInfo("Type 'help' for commands."); + + while (true) { + controller.handle(view.readLine()); + } + } +} +``` + +#### 4.6.6 架构反思与展望:共享List
的隐患(关键!) + +**教师口播**: +> "现在这个架构已经可用了。但请大家审视一下:我们所有的Command都直接拿到了`List
`的引用。换句话说,任何一个命令都可以随意增、删、改这个列表。" +> +> "这就好像一家酒店,所有服务员、厨师、清洁工都能随意进出保险箱——**数据结构完全裸奔了**。" + +**提问**: +- "如果CrawlCommand不小心写错了代码,把一个null塞进articles,HelpCommand会不会受影响?" +- "如果未来我们要在添加文章时也写入日志文件,现在的设计能优雅实现吗?还是得在所有Command里分别加日志代码?" + +**预告解决方案**: +> "下周,我们将引入**策略模式**和一个真正的**Model仓库层(ArticleRepository)**。这个仓库会把`List`封装起来,对外只提供`add()`、`getAll()`等安全接口。任何命令想修改数据,都必须通过仓库。这就是从'数据结构'到'模型层'的进化——我们W9先搭骨架,W10给它装上盔甲。" + +--- + +### 4.7 实践任务(5分钟) + +**任务要求**: +1. 使用Maven模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现4个Command:help/list/crawl/exit +4. `list`命令能展示已抓取的文章 +5. 运行并测试循环 +6. **代码找茬(额外加分)**:找出你自己代码中是否存在`System.out`直接调用、硬编码ANSI字符串等"越权行为" + +**验收标准**: +- [x] Maven编译通过 +- [x] Command接口和4个实现分离在不同文件 +- [x] Controller里没有switch-case +- [x] 新增命令只需新建类,不改Controller +- [x] list命令能正确显示空列表 +- [x] 所有输出均通过ConsoleView完成,无直接System.out.println(main除外) +- [x] ANSI颜色码集中定义为View常量 + +--- + +## 五、课后作业 + +### 5.1 必做任务 + +1. **完善Article**:增加`author`、`publishDate`字段 +2. **★ HistoryCommand(强制作业)**: + - 实现`history`命令,记录用户输入过的所有命令 + - 使用`List`存储历史(复习W8集合) + - 示例输出: + ``` + crawler> history + 1. help + 2. list + 3. crawl https://example.com + ``` +3. **AI架构审计**:将类名和方法名发给AI,指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?Model层是否包含输入输出代码?View层是否越权写了业务逻辑?有没有地方直接使用了System.out或硬编码ANSI码?" + +### 5.2 选做任务 + +1. **命令别名**:给`crawl`增加别名`c`,`help`增加别名`h` +2. **URL验证**:检查URL格式是否以http://或https://开头 +3. **暗色主题**:实现不同的配色方案(利用View中的ANSI常量,只需修改一处即可) +4. **思考并回答**:分析`List
`共享引用的潜在风险,写一段200字的小结 + +### 5.3 思考题 + +1. **Command vs switch-case**:增加10个命令,哪种方式代码改动量更小? +2. **如果不用Command接口,直接用Map存命令类行不行?** 接口的意义是什么? +3. **Controller里的`commands.put()`能否减少?** 提示:思考"注册机制" +4. **为什么ExitCommand里的`view.printSuccess("Bye!")`比直接`System.out.println`更"MVC"?** 提示:回忆View的职责 + +--- + +## 六、AI协同升级 + +### 架构审计师任务(必做) + +**学生执行步骤**: +1. 列出项目中所有类名(不含方法实现) +2. 将类名列表发给AI +3. 输入指令: + > "作为Java架构审计师,请检查我的MVC三层划分是否清晰。Model层是否包含了不应该有的代码(Scanner/System.out)?View层是否越权写了业务逻辑?请指出任何一处直接使用System.out.println的地方,并建议如何改正。" + +**预期AI输出**: +- 指出哪一层有越权行为 +- 建议如何整改 +- 评价整体架构健康度 + +### 进阶AI探究(选做) + +> "假设我的Command接口中execute方法接收了一个`List
`参数,请分析这种设计在工程上有什么隐患,并给出重构建议。" + +--- + +## 七、教学反思与调整记录 + +| 日期 | 事项 | 调整内容 | +|------|------|----------| +| 2026-04-28 | 首次编写 | 基于CLI+MVC重构 | +| 2026-04-30 | 教授反馈 | 引入Command模式、提供Maven模板、升级AI协同比 | +| 2026-04-30 | 逻辑重排 | 按"问题→选择→架构→模式"顺序重写 | +| 2026-05-01 | v2 vs V3合并 | 融合深度改进:增加教育哲学、批判性思考、ANSI常量、共享List隐患、故意埋坑 | + +--- + +## 附录1:Maven模板说明 + +> 老师提供`my-crawler-template.zip`压缩包,包含: +> - pom.xml(含Jsoup依赖) +> - 空的src/main/java结构 +> - .gitignore + +## 附录2:常见问题速查 + +| 问题 | 解答 | +|------|------| +| IDEA不识别pom.xml | 右键 pom.xml → Maven → Reload Project | +| 中文乱码 | Settings → Editor → File Encodings → UTF-8 | +| 包名大小写 | 包名全小写,类名首字母大写 | +| Command找不到 | 检查是否 implements Command,是否 @Override getName() | +| 命令不生效 | 检查 commands.put() 是否注册了该命令 | +| 输出颜色乱码 | IDEA控制台需支持ANSI,Windows下建议使用Windows Terminal或调整设置 | +| 我的System.out为什么被老师说越权 | View层才是与用户交互的唯一出口,所有输出都应通过View,这样将来改成GUI或日志时只需改View | + +## 附录3:教学逻辑说明 + +| 顺序 | 内容 | 设计理由 | +|------|------|----------| +| 1 | 痛点引入 | 从问题出发,让学生感受"为什么需要架构" | +| 2 | CLI vs GUI | 解释技术选型,建立"工程思维 > 视觉装饰"的认知 | +| 3 | MVC分层 | 核心架构概念,理解职责分离,通过类比及批判加深理解 | +| 4 | Command模式 | 具体实现方式,解决"肥控制器"问题 | +| 5 | Maven | 工具链支持 | +| 6 | 代码落地 | 实践验证,刻意植入细节规范,训练工程洁癖 | +| 7 | 架构反思 | 暴露共享可变状态隐患,为W10策略模式+仓库层做铺垫 | +| 8 | 实践任务 | 现场编码验证 | +| 9 | 总结 | 强化认知,预告下周 | + +--- + +## 版本说明 + +- **v1**:首次编写,CLI+MVC基础框架 +- **v2**:按"问题→选择→架构→模式"逻辑重排 +- **v3 (本版)**:融合v2结构 + V3深度改进,包含: + - 更深的CLI教育哲学 + - 餐厅类比批判性思考 + - ANSI常量集中管理工程细节 + - 全部输出走View + - 共享List架构隐患反思 + - 故意埋坑让学生找茬 + - W10铺垫(策略模式+仓库层) \ No newline at end of file diff --git a/w9/选做/java-cli/target/maven-archiver/pom.properties b/w9/选做/java-cli/target/maven-archiver/pom.properties new file mode 100644 index 0000000..08a8f9f --- /dev/null +++ b/w9/选做/java-cli/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 30 11:50:54 CST 2026 +artifactId=datacollect-cli +groupId=com.example +version=0.1.0 diff --git a/w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..7a31545 --- /dev/null +++ b/w9/选做/java-cli/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,10 @@ +D:\java-cli\src\main\java\com\example\datacollect\controller\CrawlerController.java +D:\java-cli\src\main\java\com\example\datacollect\Main.java +D:\java-cli\src\main\java\com\example\datacollect\command\Command.java +D:\java-cli\src\main\java\com\example\datacollect\command\CrawlCommand.java +D:\java-cli\src\main\java\com\example\datacollect\command\ListCommand.java +D:\java-cli\src\main\java\com\example\datacollect\command\ExitCommand.java +D:\java-cli\src\main\java\com\example\datacollect\model\Article.java +D:\java-cli\src\main\java\com\example\datacollect\view\ConsoleView.java +D:\java-cli\src\main\java\com\example\datacollect\command\HistoryCommand.java +D:\java-cli\src\main\java\com\example\datacollect\command\HelpCommand.java diff --git a/w9/选做/java-cli/target/w9-ppt.md b/w9/选做/java-cli/target/w9-ppt.md new file mode 100644 index 0000000..5ddd5ad --- /dev/null +++ b/w9/选做/java-cli/target/w9-ppt.md @@ -0,0 +1,530 @@ +## 高级程序设计 · 第9周 + +#### 工程架构:从"写代码"到"造系统" + +##### CLI + MVC + Command模式实战 + +--- + +### 📌 本周导航 + +- 痛点引入:脚本的宿命 +- CLI vs GUI:为什么选命令行? +- MVC分层:职责分离的艺术 +- Command模式:可扩展的路由 +- Maven模板:工程化第一步 +- 代码落地:从接口到实现 +- 架构反思:共享数据的隐患 +- 实践任务 + 课后作业 + +--- + +### 1️⃣ 痛点引入:从脚本到工程的鸿沟 + +#### 这是一段“意大利面”爬虫 + +```java +public class Crawler { + public static void main(String[] args) { + System.out.print("请输入URL: "); + Scanner scanner = new Scanner(System.in); + String url = scanner.nextLine(); + List titles = new ArrayList(); + try { + Document doc = Jsoup.connect(url).get(); + Elements elements = doc.select(".post-title"); + for (Element e : elements) { + String title = e.text(); + System.out.println("标题: " + title); + titles.add(title); + } + } catch (Exception ex) { + System.out.println("出错啦: " + ex.getMessage()); + } + } +} +``` + +--- + +### 脚本的三大痛点 + +| 需求 | 需要改哪里? | +|------|--------------| +| 保存标题到文件 | 改 main 内部逻辑 | +| 支持不同网站结构 | 全部重写解析代码 | +| 彩色输出 | 一个一个改 print | + +> 😫 **牵一发而动全身 → 改起来疼** + +### 本周目标:**让代码“改起来不疼”** + +--- + +## 2️⃣ CLI vs GUI:架构选择的思考 + +### 图形界面 vs 命令行 + +| 维度 | GUI (JavaFX) | CLI (命令行) | +|------|--------------|-------------| +| 学习重心 | 布局、控件、事件 | **架构、分层、路由** | +| 后端能力 | 弱 | 模拟真实服务器 | +| 工程思维 | 弱(关注视觉) | **强(关注逻辑)** | +| 可测试性 | 难 | 易 | + +--- + +## 核心观点 + +> **CLI 更需要 MVC!** + +- GUI 有现成事件系统,框架强塞给你一套架构 +- CLI 只有字符流 → **没有架构,分分钟写成脚本** + +> 🎯 **当外部约束消失,内部的工程纪律才真正开始建立** + +### CLI 也能很酷 + +- ANSI 彩色输出 +- 表格展示数据 +- 模拟大数据/后端开发 + +--- + +## 3️⃣ MVC 分层设计 + +### MVC 的起源与演进 + +| 年代 | 场景 | MVC的角色 | +|------|------|----------| +| 1970s | Smalltalk-72 GUI | 最早的用户界面架构 | +| 1990s | Web开发 (Struts) | 后端模板引擎 | +| 2000s | ASP.NET MVC | 现代Web框架 | +| 2020s | CLI + API | 解耦业务逻辑与表现层 | + +**核心不变:职责分离** + +--- + +## MVC 三层职责 + +![[mvc.png]] +``` +┌─────────────────────────────────────────┐ +│ 入口 │ +│ (main方法) │ +└─────────────────┬───────────────────────┘ + ▼ +┌─────────────────────────────────────────┐ +│ Controller │ +│ 只管"派给谁",不管"怎么做" │ +└─────────┬───────────────┬───────────────┘ + ▼ ▼ +┌─────────────────┐ ┌─────────────────┐ +│ Model │ │ View │ +│ 管"数据" │ │ 管"呈现" │ +│ + 业务逻辑 │ │ + 输入输出 │ +└─────────────────┘ └─────────────────┘ +``` + +--- + +## 三层“禁止做什么” + +| 层级 | 禁止行为 | +| -------------- | -------------------------------------- | +| **Model** | 不能有 `System.out.println`,不能有 `Scanner` | +| **View** | 不能写爬虫逻辑,只做“传声筒” | +| **Controller** | 不能直接写业务细节,委托给 Command | + +> 🔴 **越权就是架构腐败的开始** + +--- + +## 🍽️ 餐厅类比(帮助理解) + +- **Model = 后厨**:只管做菜,不管谁来吃、怎么端 +- **View = 服务员**:只管端菜和收钱,不管菜怎么做 +- **Controller = 前台**:接单 → 派给后厨 → 叫服务员上菜 + +--- + +## 🤔 对类比的批判性思考(关键!) + +> 任何类比都有边界,不要当成真理 + +| 场景 | 暴露的问题 | +|------|------------| +| 客人有忌口(不吃香菜) | 信息需要传到后厨 → Model 可能需要知道 meta 信息 | +| 服务员反馈“今天的菜咸了” | View → Model 反向影响 | +| 后厨做完菜通知前台 | **观察者模式**,数据流可能是双向的 | + +**本课程简化模型**:请求-响应,单向流 + +--- + +## MVC 数据流向(本课程简化版) + +``` +CLI用户输入 + ↓ +View(解析命令字符串) + ↓ +Controller(找到对应Command) + ↓ +Command.execute()(执行业务逻辑) + ↓ +Model(Article数据,暂存于List) + ↓ +View(display()展示数据) + ↓ +CLI终端显示 +``` + +--- + +## 4️⃣ Command 模式:可扩展的命令路由 + +### 为什么需要 Command 模式? + +```java +switch (cmd) { + case "crawl": handleCrawl(); break; + case "help": showHelp(); break; + // 如果要增加 list 命令? + // 1. 加 case "list" + // 2. 加 handleList() 方法 + // 3. 可能还要改其他地方... +} +``` + +> 每加一个功能,就要在这个类里戳一个洞 → **肥控制器陷阱** + +--- + +## Command 模式的四个要素 + +| 要素 | 角色 | 示例 | +|------|------|------| +| Command接口 | 抽象的“订单” | `Command` | +| ConcreteCommand | 具体的订单 | `HelpCommand` | +| Invoker | 接单的前台 | `CrawlerController` | +| Receiver | 执行者 | `ConsoleView`、`ArticleRepository` | + +--- + +## Command 接口定义 + +```java +package com.crawler.command; + +import com.crawler.model.Article; +import java.util.List; + +public interface Command { + String getName(); + void execute(String[] args, List
articles); +} +``` + +--- + +## Controller 的变革:从 switch 到 Map + +```java +public class CrawlerController { + private Map commands = new HashMap<>(); + + public CrawlerController(ConsoleView view, List
articles) { + commands.put("help", new HelpCommand(view)); + commands.put("list", new ListCommand(view)); + commands.put("crawl", new CrawlCommand(view)); + commands.put("exit", new ExitCommand(view)); + } + + public void handle(String input) { + // 解析命令 → 从 Map 取 Command → 调用 execute + } +} +``` + +> **增加新命令:只需新建类,Controller 零改动!** + +--- + +## 对比:switch-case vs Command + +| 维度 | switch-case | Command模式 | +|------|-------------|-------------| +| 增加命令 | 要改 Controller | 新建一个类 | +| 多态体验 | 无 | `execute()` 多态 | +| 可测试性 | 难 | 每个 Command 单独测试 | +| 代码量 | 少 | 多,但更清晰 | + +> 🏨 **类比:酒店客房服务,前台只负责派单** + +--- + +## 5️⃣ Maven 模板与环境(5分钟) + +### 直接使用模板,不折腾配置 + +``` +my-crawler-template.zip + ↓ 解压 + IDEA打开 + ↓ 右键 pom.xml → Maven → Reload Project + ↓ 运行 App.java +``` + +### 标准目录结构 + +``` +src/main/java/com/crawler/ +├── model/Article.java +├── view/ConsoleView.java +├── command/ +│ ├── Command.java +│ ├── CrawlCommand.java +│ ├── HelpCommand.java +│ ├── ListCommand.java +│ └── ExitCommand.java +└── controller/CrawlerController.java +``` + +--- + +## 6️⃣ 代码落地(分步实现) + +### Model:Article 实体 + +```java +public class Article { + private String title; + private String url; + private String content; + // 构造器、getter/setter、toString +} +``` + +> 📦 只存放数据,没有任何输入输出代码 + +--- + +## View:ConsoleView(ANSI常量集中管理) + +```java +public class ConsoleView { + private static final String ANSI_GREEN = "\033[32m"; + private static final String ANSI_RED = "\033[31m"; + // ... 其他常量 + + public void printSuccess(String msg) { + System.out.println(ANSI_GREEN + msg + ANSI_RESET); + } + public void printError(String msg) { ... } + public void display(List
articles) { ... } +} +``` + +> ✨ **所有颜色码集中定义 → 改主题只需改一处** + +--- + +## Command 实现示例(HelpCommand) + +```java +public class HelpCommand implements Command { + private ConsoleView view; + public HelpCommand(ConsoleView v) { this.view = v; } + public String getName() { return "help"; } + public void execute(String[] args, List
articles) { + view.printInfo("Commands: crawl , list, help, exit"); + } +} +``` + +> ⚠️ 全部输出通过 `view`,绝不让 `System.out` 直接出现在这里 + +--- + +## CrawlCommand(存根,下周填坑) + +```java +public class CrawlCommand implements Command { + private ConsoleView view; + public CrawlCommand(ConsoleView v) { this.view = v; } + public String getName() { return "crawl"; } + public void execute(String[] args, List
articles) { + if (args.length < 2) { + view.printError("Usage: crawl "); + return; + } + view.printInfo("Stub: Would crawl " + args[1]); + } +} +``` + +> 🔍 **找茬点**:这里拼接字符串算是“业务逻辑”吗?留给大家用 AI 审计。 + +--- + +## ExitCommand + +```java +public class ExitCommand implements Command { + private ConsoleView view; + public ExitCommand(ConsoleView v) { this.view = v; } + public String getName() { return "exit"; } + public void execute(String[] args, List
articles) { + view.printSuccess("Bye!"); + System.exit(0); + } +} +``` + +> ✅ 所有输出都通过 View → 将来改 GUI 只需换 View 实现 + +--- + +## Controller + main 组装 + +```java +// Controller 中持有 Map +// App.java 中: +ConsoleView view = new ConsoleView(); +List
articles = new ArrayList<>(); +CrawlerController controller = new CrawlerController(view, articles); +view.printSuccess("Welcome to CLI Crawler!"); +while (true) { + controller.handle(view.readLine()); +} +``` + +> 🔁 完成交互循环 + +--- + +## 7️⃣ 架构反思:共享 List
的隐患 + +### 当前问题 + +- 所有 Command 都直接拿到 `List
` 引用 +- 任何一个命令都可以随意增、删、改列表 +- 数据完全“裸奔” + +> 🚨 就像酒店所有员工都能进保险箱 + +--- + +## 提问 + +- 如果 `CrawlCommand` 不小心把 `null` 塞进列表,`ListCommand` 会怎样? +- 如果我们要在添加文章时写日志,现在的设计能优雅实现吗? + +### 预告解决方案(W10) + +- **策略模式** + **仓库层(ArticleRepository)** +- 封装 `List`,对外只暴露 `add()`、`getAll()` 等安全接口 + +> W9 搭骨架,W10 装上盔甲 + +--- + +## 8️⃣ 实践任务(现场5分钟) + +### 必做项 + +1. 使用 Maven 模板创建项目 +2. 实现完整包结构(model/view/command/controller) +3. 实现 4 个 Command:help / list / crawl / exit +4. `list` 能展示已抓取的文章(目前存根即可) +5. 运行并测试循环 + +### 额外加分:代码找茬 + +- 检查是否仍有 `System.out` 直接调用 +- 检查 ANSI 码是否硬编码在多个地方 + +--- + +## 验收标准 + +- [x] Maven 编译通过 +- [x] Command 接口和 4 个实现在不同文件 +- [x] Controller 里没有 switch-case +- [x] 新增命令只需新建类,不改 Controller +- [x] list 能正确显示空列表 +- [x] 所有输出均通过 `ConsoleView` +- [x] ANSI 颜色码集中定义为常量 + +--- + +## 9️⃣ 课后作业 + +### 必做 + +1. **完善 Article**:增加 `author`、`publishDate` 字段 +2. **★ HistoryCommand**:记录用户输入过的所有命令(用 `List`) +3. **AI 架构审计**:将类名发给 AI,指令: + > “作为Java架构审计师,请检查我的MVC三层划分是否存在越权行为?” + +### 选做 + +- 命令别名(c 代替 crawl) +- URL 格式验证 +- 暗色主题(修改一处常量) +- 思考题:分析 `List
` 共享引用的风险(200字小结) + +--- + +## 🤖 AI 协同升级 + +### 架构审计师任务(必做) + +**步骤**: +1. 列出所有类名(不含方法实现) +2. 发给 AI +3. 指令:“检查 MVC 分层是否清晰,是否有越权行为” + +### 进阶探究(选做) + +> “假设我的 Command 接口中 execute 方法接收了一个 `List
` 参数,请分析这种设计在工程上有什么隐患,并给出重构建议。” + +--- + +## 📚 总结与过渡 + +### 本周成果 + +- ✅ 工程化包结构 +- ✅ MVC 分层清晰 +- ✅ Command 模式实现可扩展路由 +- ✅ 所有输出走 View,常量集中管理 + +### 下周预告 + +- **策略模式**:封装爬取算法 +- **仓库层(Repository)**:武装 `List
`,解决共享隐患 + +> 🚀 从“写代码”到“造系统”,踏出坚实第一步! + +--- + +## Q&A + +### 常见问题 + +| 问题 | 解答 | +|------|------| +| IDEA 不识别 pom.xml | 右键 → Maven → Reload Project | +| 中文乱码 | Settings → File Encodings → UTF-8 | +| 输出颜色乱码 | Windows 建议使用 Windows Terminal | +| 我的 System.out 被批评 | View 才是唯一输出出口 | + +--- + +## 谢谢! + +### 课件已上传,模板在课程群 + +**保持工程洁癖,下周见!** \ No newline at end of file