工厂模式:使用者不用创建使用对象,直接从工厂取出对象进行使用。
示例:子宫(工厂)创造各种动物
工厂模式的优势:在添加动物的时候不需要修改客户端(TestFactoryPattern),只需要直接添加动物就可以,工厂会自动(这时需要一个标示告诉工厂你需要那种动物,也就是type)返回需要的动物。
工厂模式类图:
直接代码:
定义一个抽象类Animal,定义动物的共同属性 name,speed,共同行为:say(),run();,子类可进行覆写方法实现自己特有的行为。
package com.zpj.designMode; /** * @author PerKins Zhu * @date:2016年8月27日 下午5:11:07 * @version :1.1 * */ public abstract class Animal { public String name; public int speed; public abstract void run(); public abstract void say(); public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } }
下面添加三个动物:Person Tiger ,Panda
package com.zpj.designMode; /** * @author PerKins Zhu * @date:2016年8月27日 下午5:13:48 * @version :1.1 * */ public class Person extends Animal { public Person() { } public Person(String name, int speed) { this.name = name; this.speed = speed; } @Override public void run() { System.out.println(name + "--两条腿跑---speed:" + speed + "KM/h"); } @Override public void say() { System.out.println(name + "--嘴说--- hello , i am " + name); } }
package com.zpj.designMode; /** * @author PerKins Zhu * @date:2016年8月27日 下午5:18:45 * @version :1.1 * */ public class Tiger extends Animal { public Tiger() { super(); // TODO Auto-generated constructor stub } public Tiger(String name, int speed) { super(); this.name = name; this.speed = speed; } public void run() { System.out.println(name + "--四条腿窜---speed:" + speed); } public void say() { System.out.println(name + "--吼--- hello , i am " + name); } }
package com.zpj.designMode; /** * @author PerKins Zhu * @date:2016年8月27日 下午5:17:45 * @version :1.1 * */ public class Panda extends Animal{ public Panda() { super(); // TODO Auto-generated constructor stub } public Panda(String name,int speed) { this.name = name; this.speed = speed; } public void run() { System.out.println(name + "--四条腿爬---speed:" + speed); } public void say() { System.out.println(name + "--不知道--- hello , i am " + name); } }
创建个子宫(工厂)生产动物
package com.zpj.designMode; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.Properties; /** * @author PerKins Zhu * @date:2016年8月27日 下午5:21:38 * @version :1.1 * */ public class Uterus { public static Animal createAnimal(int type) {//type 类型告诉工厂客户端需要什么动物 switch (type) { case 1: return new Person("所谓的高级动物", 30); case 2: return new Tiger("老虎", 100); case 3: return new Panda("黑白猫", 10); } return null; } public static Animal createAnimal() throws Exception { //从配置文件中读出客户端需要什么动物 Properties prop = new Properties(); InputStream in = Object.class.getResourceAsStream("/com/zpj/designMode/animal.properties"); try { prop.load(in); String type = prop.getProperty("type").trim(); String name = prop.getProperty("name").trim(); String speed = prop.getProperty("speed").trim(); //使用反射机制生成客户端需要的动物 Class classs = Class.forName(type); Animal animal = (Animal) classs.newInstance(); animal.setName(name); animal.setSpeed(Integer.parseInt(speed)); return animal; } catch (IOException e) { e.printStackTrace(); } return null; } }
测试类:
package com.zpj.designMode; import org.junit.Test; /** * @author PerKins Zhu * @date:2016年8月27日 下午5:39:35 * @version :1.1 * */ public class TestFactoryPattern { @Test public void test01() throws Exception { Animal animal; for (int i = 1; i < 4; i++) { System.out.println("-----------------test:" + i + " -------------------"); animal = Uterus.createAnimal(i); animal.say(); animal.run(); } } //使用配置文件告诉工厂需要什么动物 @Test public void test02() throws Exception { Animal animal; animal = Uterus.createAnimal(); animal.say(); animal.run(); } }
说明一下:
test01()是普通的工厂模式,这里有一个缺陷,就是在增加动物的时候需要更改工厂,在 public static Animal createAnimal(int type)方法中需要添加一种新类型。
test02()是优化后的测试方法,此时调用public static Animal createAnimal() throws Exception (),从配置文件中读取客户端需要的对象,此时如果需要添加动物,只需要修改配置问价就可以了,不需要再对
createAnimal()方法进行修改。
配置文件内容:
type=com.zpj.designMode.Person
name=所谓的高级动物
speed=30
注意:
注意读取配置文件的路径问题
反射机制使用的时候类中必须有空的构造方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!