定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
我的理解:
工厂模式的精髓就是对象的创建是由工厂代理的,工厂会给你一个对象,你只用提供类的个人信息就行。
那么在Java中如何具体的实现呢:
public abstract class Product {
//产品类的公共方法 public void method1(){
//业务逻辑处理 } //抽象方法 public abstract void method2(); } 具体的产品类可以有多个,都继承于抽象产品类,其源代码如代码清单8-9所示。 代码清单8-9 具体产品类 public class ConcreteProduct1 extends Product {
public void method2() {
//业务逻辑处理 } } //具体的子类实现类产品 public class ConcreteProduct2 extends Product {
public void method2() {
//业务逻辑处理 } }
讯享网
讯享网代码清单8-10 抽象工厂类 public abstract class Creator {
/* * 创建一个产品对象,其输入参数类型可以自行设置 * 通常为String、Enum、Class等,当然也可以为空 */ public abstract <T extends Product> T createProduct(Class<T> c); } 具体如何产生一个产品的对象,是由具体的工厂类实现的,如代码清单8-11所示。 代码清单8-11 具体工厂类 public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c){
Product product=null; try {
product = (Product)Class.forName(c.getName()).newInstance(); } catch (Exception e) {
//异常处理 } return (T)product; } }
我们们为啥使用的抽象的工厂类应为还是产品未定所以我们使用的还是抽象的,注意具体的实现,我们是通过反射机制来创建的对象的,得到类的个人信息就可以创建对应的实例化对象了
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator(); Product product = creator.createProduct(ConcreteProduct1.class); /* * 继续业务处理 */ } }
- 首先,工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以
使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度。
2.一个产品对象具体由哪一个产品生成是由工厂类
决定的。在数据库开发中,大家应该能够深刻体会到工厂方法模式的好处:如果使用JDBC
连接数据库,数据库从MySQL切换到Oracle,需要改动的地方就是切换一下驱动名称(前提
条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接
案例。
工厂方法模式的扩展
- 缩小为简单工厂模式
当我们使用工厂类,没必要把工厂类new 来的时候,我们就是用静态方法就可以的

中去掉了AbstractHumanFactory抽象类,同时把createHuman方法设置为静态
类型
讯享网代码清单8-13 简单工厂模式中的工厂类 public class HumanFactory {
public static <T extends Human> T createHuman(Class<T> c){
//定义一个生产出的人种 Human human=null; try {
//产生一个人种 human = (Human)Class.forName(c.getName()).newInstance(); } catch (Exception e) {
System.out.println("人种生成错误!"); } return (T)human; } }
测试:
代码清单8-14 简单工厂模式中的场景类 public class NvWa {
public static void main(String[] args) {
//女娲第一次造人,火候不足,于是白色人种产生了 System.out.println("--造出的第一批人是白色人种--"); Human whiteHuman = HumanFactory.createHuman(WhiteHuman.class); whiteHuman.getColor(); whiteHuman.talk(); //女娲第二次造人,火候过足,于是黑色人种产生了 System.out.println("\n--造出的第二批人是黑色人种--"); Human blackHuman = HumanFactory.createHuman(BlackHuman.class); blackHuman.getColor(); blackHuman.talk(); //第三次造人,火候刚刚好,于是黄色人种产生了 System.out.println("\n--造出的第三批人是黄色人种--"); Human yellowHuman = HumanFactory.createHuman(YellowHuman.class); yellowHuman.getColor(); yellowHuman.talk(); } }
升级为多个工厂类
我们的工厂可以是多个具体的,特定生产出特定的产品出来的
每一个工厂可以生产出一种产品

讯享网代码清单8-15 多工厂模式的抽象工厂类 public abstract class AbstractHumanFactory {
public abstract Human createHuman(); }

不同的工厂
黑色人种的创建工厂如代码清单8-16所示。 代码清单8-16 黑色人种的创建工厂实现 public class BlackHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new BlackHuman(); } } 黄色人种的创建工厂如代码清单8-17所示。 代码清单8-17 黄色人种的创建类 public class YellowHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new YellowHuman(); } } 白色人种的创建工厂如代码清单8-18所示。 代码清单8-18 白色人种的创建类 public class whiteHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new WhiteHuman(); } }
测试类
讯享网public class NvWa {
public static void main(String[] args) {
//女娲第一次造人,火候不足,于是白色人种产生了 System.out.println("--造出的第一批人是白色人种--"); Human whiteHuman = (new WhiteHumanFactory()).createHuman(); whiteHuman.getColor(); whiteHuman.talk(); //女娲第二次造人,火候过足,于是黑色人种产生了 System.out.println("\n--造出的第二批人是黑色人种--"); Human blackHuman = (new BlackHumanFactory()).createHuman(); blackHuman.getColor(); blackHuman.talk(); //第三次造人,火候刚刚好,于是黄色人种产生了 System.out.println("\n--造出的第三批人是黄色人种--"); Human yellowHuman = (new YellowHumanFactory()).createHuman(); yellowHuman.getColor(); yellowHuman.talk(); } }
替代单例模式

定义一个private的构造函数的额类目的是不允许通过new的
方式创建一个对象,如代码清单8-20所示。
代码清单8-20 单例类 public class Singleton {
//不允许通过new产生一个对象 private Singleton(){
} public void doSomething(){
//业务处理 } }
讯享网代码清单8-21 负责生成单例的工厂类 public class SingletonFactory {
private static Singleton singleton; static{
try {
Class cl= Class.forName(Singleton.class.getName()); //获得无参构造 Constructor constructor=cl.getDeclaredConstructor(); //设置无参构造是可访问的 constructor.setAccessible(true); //产生一个实例对象 singleton = (Singleton)constructor.newInstance(); } catch (Exception e) {
//异常处理 } } public static Singleton getSingleton(){
return singleton; } }
抽象工厂模式
定义:(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们
的具体类。)
说人话就是,当我们要创建一组对象,是同一个父类的时候,就使用抽象接口创造它

代码清单9-11 抽象产品类
public abstract class AbstractProductA {
//每个产品共有的方法 public void shareMethod(){
} //每个产品相同方法,不同实现 public abstract void doSomething(); }
讯享网两个具体的产品实现类如代码清单9-12、代码清单9-13所示。 代码清单9-12 产品A1的实现类 public class ProductA1 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A1的实现方法"); } } 代码清单9-13 产品A2的实现类 public class ProductA2 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A2的实现方法"); } }
产品B与此类似,不再赘述
抽象工厂类AbstractCreator的职责是定义每个工厂要实现的
功能,定义着不同的生产不同的产品
public abstract class AbstractCreator {
//创建A产品家族 public abstract AbstractProductA createProductA(); //创建B产品家族 public abstract AbstractProductB createProductB(); }
讯享网代码清单9-15 产品等级1的实现类 public class Creator1 extends AbstractCreator {
//只生产产品等级为1的A产品 public AbstractProductA createProductA() {
return new ProductA1(); } //只生产产品等级为1的B产品 public AbstractProductB createProductB() {
return new ProductB1(); } } 代码清单9-16 产品等级2的实现类 public class Creator2 extends AbstractCreator {
//只生产产品等级为2的A产品 public AbstractProductA createProductA() {
return new ProductA2(); } //只生产产品等级为2的B产品 public AbstractProductB createProductB() {
return new ProductB2(); } }
有M个产品等级就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族
的生产任务。
在具体的业务中如何产生一个与实现无关的对象呢
代码清单9-17 场景类 public class Client {
public static void main(String[] args) {
//定义出两个工厂 AbstractCreator creator1 = new Creator1(); AbstractCreator creator2 = new Creator2(); //产生A1对象 AbstractProductA a1 = creator1.createProductA(); //产生A2对象 AbstractProductA a2 = creator2.createProductA(); //产生B1对象 AbstractProductB b1 = creator1.createProductB(); //产生B2对象 AbstractProductB b2 = creator2.createProductB(); /* * 然后在这里就可以为所欲为了... */ } }


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/13248.html