diff --git a/README.md b/README.md deleted file mode 100644 index b07114c..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# jdgcms - diff --git a/src/123/README.md b/src/123/README.md new file mode 100644 index 0000000..d18411a --- /dev/null +++ b/src/123/README.md @@ -0,0 +1,61 @@ +# 简单工厂模式Java实现 + +这是一个符合SOLID原则的简单工厂模式Java应用。 + +## 项目结构 + +``` +src/ +├── main/ +│ └── java/ +│ ├── Product.java # 抽象产品类 +│ ├── ConcreteProductA.java # 具体产品类A +│ ├── ConcreteProductB.java # 具体产品类B +│ ├── Factory.java # 工厂类 +│ └── Main.java # 主类,用于演示 +└── test/ + └── java/ + ├── ProductTest.java # 抽象产品测试类 + ├── ConcreteProductATest.java # 具体产品A测试类 + ├── ConcreteProductBTest.java # 具体产品B测试类 + └── FactoryTest.java # 工厂类测试类 +``` + +## 功能说明 + +1. **抽象产品类 (Product)**:定义产品的公共接口和抽象方法 +2. **具体产品类 (ConcreteProductA, ConcreteProductB)**:实现产品的具体功能 +3. **工厂类 (Factory)**:负责创建不同类型的产品实例 +4. **主类 (Main)**:演示工厂模式的使用方法 + +## 运行方法 + +### 运行主程序 + +```bash +cd src +javac -encoding UTF-8 main/java/*.java +java main.java.Main +``` + +### 运行测试 + +使用JUnit框架运行测试: + +```bash +# 需要将JUnit库添加到classpath +java -cp .:junit.jar:hamcrest-core.jar org.junit.runner.JUnitCore main.java.FactoryTest main.java.ProductTest main.java.ConcreteProductATest main.java.ConcreteProductBTest +``` + +## SOLID原则应用 + +- **单一职责原则 (SRP)**:每个类都有明确的职责 +- **开闭原则 (OCP)**:系统对扩展开放,对修改关闭 +- **里氏替换原则 (LSP)**:子类可以替换父类使用 +- **依赖倒置原则 (DIP)**:依赖于抽象而非具体实现 +- **接口隔离原则 (ISP)**:产品接口简洁,只包含必要的方法 + +## 注意事项 + +- 本项目使用Java标准库实现,无需额外依赖 +- 测试类使用JUnit框架,运行测试需要JUnit库 \ No newline at end of file diff --git a/src/123/images/屏幕截图 2025-10-26 130910.png b/src/123/images/屏幕截图 2025-10-26 130910.png new file mode 100644 index 0000000..b775394 Binary files /dev/null and b/src/123/images/屏幕截图 2025-10-26 130910.png differ diff --git a/src/123/images/屏幕截图 2025-10-26 140213.png b/src/123/images/屏幕截图 2025-10-26 140213.png new file mode 100644 index 0000000..4b9aaac Binary files /dev/null and b/src/123/images/屏幕截图 2025-10-26 140213.png differ diff --git a/src/123/images/屏幕截图 2025-10-26 140347.png b/src/123/images/屏幕截图 2025-10-26 140347.png new file mode 100644 index 0000000..e8b04d5 Binary files /dev/null and b/src/123/images/屏幕截图 2025-10-26 140347.png differ diff --git a/src/123/images/屏幕截图 2025-10-26 142512.png b/src/123/images/屏幕截图 2025-10-26 142512.png new file mode 100644 index 0000000..5e501e4 Binary files /dev/null and b/src/123/images/屏幕截图 2025-10-26 142512.png differ diff --git a/src/123/src/main/java/ConcreteProductA.class b/src/123/src/main/java/ConcreteProductA.class new file mode 100644 index 0000000..c33851b Binary files /dev/null and b/src/123/src/main/java/ConcreteProductA.class differ diff --git a/src/123/src/main/java/ConcreteProductA.java b/src/123/src/main/java/ConcreteProductA.java new file mode 100644 index 0000000..6420d80 --- /dev/null +++ b/src/123/src/main/java/ConcreteProductA.java @@ -0,0 +1,25 @@ +package main.java; + +/** + * 具体产品类A - 遵循里氏替换原则(LSP) + * 继承自抽象产品类Product,实现其定义的抽象方法 + */ +public class ConcreteProductA extends Product { + /** + * 实现Product抽象类的use方法 + * @return 使用产品A的结果字符串 + */ + @Override + public String use() { + return "Using Concrete Product A"; + } + + /** + * 实现Product抽象类的getName方法 + * @return 产品A的名称 + */ + @Override + public String getName() { + return "ConcreteProductA"; + } +} \ No newline at end of file diff --git a/src/123/src/main/java/ConcreteProductB.class b/src/123/src/main/java/ConcreteProductB.class new file mode 100644 index 0000000..cce906a Binary files /dev/null and b/src/123/src/main/java/ConcreteProductB.class differ diff --git a/src/123/src/main/java/ConcreteProductB.java b/src/123/src/main/java/ConcreteProductB.java new file mode 100644 index 0000000..1b2180d --- /dev/null +++ b/src/123/src/main/java/ConcreteProductB.java @@ -0,0 +1,25 @@ +package main.java; + +/** + * 具体产品类B - 遵循里氏替换原则(LSP) + * 继承自抽象产品类Product,实现其定义的抽象方法 + */ +public class ConcreteProductB extends Product { + /** + * 实现Product抽象类的use方法 + * @return 使用产品B的结果字符串 + */ + @Override + public String use() { + return "Using Concrete Product B"; + } + + /** + * 实现Product抽象类的getName方法 + * @return 产品B的名称 + */ + @Override + public String getName() { + return "ConcreteProductB"; + } +} \ No newline at end of file diff --git a/src/123/src/main/java/Factory.class b/src/123/src/main/java/Factory.class new file mode 100644 index 0000000..70a8676 Binary files /dev/null and b/src/123/src/main/java/Factory.class differ diff --git a/src/123/src/main/java/Factory.java b/src/123/src/main/java/Factory.java new file mode 100644 index 0000000..8618685 --- /dev/null +++ b/src/123/src/main/java/Factory.java @@ -0,0 +1,55 @@ +package main.java; + +/** + * 工厂类 - 遵循开闭原则(OCP)和依赖倒置原则(DIP) + * 对扩展开放,对修改关闭;依赖于抽象而非具体实现 + * 此类负责创建不同类型的产品实例 + */ +public class Factory { + // 使用常量定义产品类型,避免魔法字符串 + public static final String PRODUCT_TYPE_A = "A"; + public static final String PRODUCT_TYPE_B = "B"; + + /** + * 创建产品实例的工厂方法 + * @param type 产品类型 + * @return Product抽象类的具体实现实例 + * @throws IllegalArgumentException 当提供无效的产品类型时抛出 + */ + public static Product createProduct(String type) { + if (type == null) { + throw new IllegalArgumentException("Product type cannot be null"); + } + + if (PRODUCT_TYPE_A.equalsIgnoreCase(type)) { + return new ConcreteProductA(); + } else if (PRODUCT_TYPE_B.equalsIgnoreCase(type)) { + return new ConcreteProductB(); + } else { + throw new IllegalArgumentException("Invalid product type: " + type); + } + } + + /** + * 带参数检查的安全工厂方法,遵循健壮性原则 + * @param type 产品类型 + * @return Product抽象类的具体实现实例,如果类型无效则返回null + */ + public static Product createProductSafe(String type) { + try { + return createProduct(type); + } catch (IllegalArgumentException e) { + System.err.println("Error creating product: " + e.getMessage()); + return null; + } + } + + /** + * 验证产品是否有效 + * @param product 需要验证的产品实例 + * @return 如果产品有效返回true,否则返回false + */ + public static boolean isValidProduct(Product product) { + return product != null; + } +} \ No newline at end of file diff --git a/src/123/src/main/java/Main.class b/src/123/src/main/java/Main.class new file mode 100644 index 0000000..61544ef Binary files /dev/null and b/src/123/src/main/java/Main.class differ diff --git a/src/123/src/main/java/Main.java b/src/123/src/main/java/Main.java new file mode 100644 index 0000000..b9dc5e9 --- /dev/null +++ b/src/123/src/main/java/Main.java @@ -0,0 +1,80 @@ +package main.java; + +/** + * 主类 - 演示简单工厂模式的使用 + * 遵循最少知道原则,只与工厂类和产品抽象类交互 + */ +public class Main { + /** + * 主方法,程序入口点 + * @param args 命令行参数 + */ + public static void main(String[] args) { + System.out.println("===== 简单工厂模式演示 ====="); + + // 使用工厂创建产品A + try { + System.out.println("\n1. 创建并使用产品A:"); + Product productA = Factory.createProduct(Factory.PRODUCT_TYPE_A); + displayProductInfo(productA); + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + } + + // 使用工厂创建产品B + try { + System.out.println("\n2. 创建并使用产品B:"); + Product productB = Factory.createProduct(Factory.PRODUCT_TYPE_B); + displayProductInfo(productB); + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + } + + // 测试无效产品类型 + try { + System.out.println("\n3. 测试无效产品类型:"); + Product invalidProduct = Factory.createProduct("C"); + displayProductInfo(invalidProduct); + } catch (Exception e) { + System.err.println("Expected exception: " + e.getMessage()); + } + + // 测试安全工厂方法 + System.out.println("\n4. 测试安全工厂方法:"); + Product safeProduct = Factory.createProductSafe("D"); + if (safeProduct == null) { + System.out.println("安全工厂正确处理了无效产品类型"); + } + + // 新增测试用例:测试产品类型大小写不敏感性 + try { + System.out.println("\n5. 测试产品类型大小写不敏感性:"); + // 测试小写产品类型 + Product productALower = Factory.createProduct("a"); + System.out.println("使用小写'a'创建产品:"); + displayProductInfo(productALower); + + // 测试混合大小写产品类型 + Product productBMixed = Factory.createProduct("B"); + System.out.println("使用大写'B'创建产品:"); + displayProductInfo(productBMixed); + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + } + + System.out.println("\n===== 演示结束 ====="); + } + + /** + * 显示产品信息 + * @param product 产品实例 + */ + private static void displayProductInfo(Product product) { + if (Factory.isValidProduct(product)) { + System.out.println("产品名称: " + product.getName()); + System.out.println("使用结果: " + product.use()); + } else { + System.out.println("无效产品"); + } + } +} \ No newline at end of file diff --git a/src/123/src/main/java/Product.class b/src/123/src/main/java/Product.class new file mode 100644 index 0000000..cc22ed8 Binary files /dev/null and b/src/123/src/main/java/Product.class differ diff --git a/src/123/src/main/java/Product.java b/src/123/src/main/java/Product.java new file mode 100644 index 0000000..818c85e --- /dev/null +++ b/src/123/src/main/java/Product.java @@ -0,0 +1,19 @@ +package main.java; + +/** + * 抽象产品类 - 遵循单一职责原则(SRP) + * 定义产品的公共接口和抽象方法,作为所有具体产品的共同父类 + */ +public abstract class Product { + /** + * 产品的抽象方法,由具体产品类实现 + * @return 产品使用的结果字符串 + */ + public abstract String use(); + + /** + * 获取产品的名称 + * @return 产品名称 + */ + public abstract String getName(); +} \ No newline at end of file