设计模式—工厂方法模式

定义

定义一个用于创建对象的接口,让子类决定实例化哪个类

使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复合对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。

关键点

一个抽象工厂—定义创建对象的接口

抽象工厂的实现类—可以是一个实现或多个实现,用于生产需要的具体对象

一个抽象产品—工厂方法模式所创建的产品的父类

抽象产品的实现类—需要被创建的具体产品

实现

/**
 * 抽象工厂类—定义生产抽象对象的接口
 */
public abstract class AbstractFactory {

    public abstract AbstractProduct createProduct();

}
/**
 * 抽象产品类—工厂模式的抽象接口需要创建返回的类型
 */
public abstract class AbstractProduct {

    /**
     * 抽象产品内的抽象方法
     */
    public abstract void showProductName();

}
/**
 * 抽象工厂的实现类—创建具体需要的产品
 */
public class ProductFactory extends AbstractFactory {

    @Override
    public AbstractProduct createProduct() {
        //根据需要创建具体的产品,这里我们创建产品A
        return new ProductA();
    }
}
/**
 * 具体的产品A
 */
public class ProductA extends AbstractProduct {

    @Override
    public void showProductName() {
        Log.i("Product:", "A");
    }
}
/**
 * 具体的产品B
 */
public class ProductB extends AbstractProduct {

    @Override
    public void showProductName() {
        Log.i("Product:", "B");
    }
}

使用

AbstractFactory factory = new ProductFactory();
AbstractProduct product = factory.createProduct();
product.showProductName();

输出

01-01 00:05:58.728 2840-2840/com.example.admin.singleinstancedemo I/Product:: A

当然我们也可以在具体创建产品的工厂类里面创建B产品。上面这种方式是最常见的需要哪一个产品就生产哪一个。除此之外,我们还可以利用反射的方式去更加简洁的生产具体的产品对象,修改抽象工厂类和具体工厂类如下:

/**
 * 抽象接口类—定义生产抽象对象的接口
 */
public abstract class AbstractFactory {

    public abstract <T extends AbstractProduct> T  createProduct(Class<T> clz);

}
/**
 * 抽象工厂的实现类—创建具体需要的产品
 */
public class ProductFactory extends AbstractFactory {
    @Override
    public <T extends AbstractProduct> T createProduct(Class<T> clz) {
        AbstractProduct product = null;
        try {
            product = (AbstractProduct) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) product;
    }

}

使用

AbstractFactory factory = new ProductFactory();
AbstractProduct product = factory.createProduct(ProductB.class);
product.showProductName();

输出结果

01-01 00:26:19.950 16938-16938/com.example.admin.singleinstancedemo I/Product:: B

需要哪一个类的对象就传入哪一个类的类型即可,这种方式比较简介、动态,当然我们也可以为每个具体的产品定义一个具体的工厂类,比如在第一种方式基础上多增加一个专门用于生产ProductB的工厂

/**
 * 抽象工厂的实现类—创建具体需要的产品B
 */
public class ProductFactoryB extends AbstractFactory {

    @Override
    public AbstractProduct createProduct() {
        return new ProductB();
    }
}

然后需要A的时候使用ProductFactory工厂创建A实例,需要B的时候使用ProductFactoryB工厂创建B实例,各司其职。这样拥有多个工厂的方式我们称为多工厂方法模式。

当只有一个工厂的时候,我们还是为工厂提供了一个抽象类,是否可以将其简化掉呢?当然是可以的:

/**
 * 直接提供静态方法—向外创建对象
 */
public class ProductFactory {

    public static AbstractProduct createProduct(){
        return new ProductA();
    }
}

像这样的方式又称之为简单工厂模式或静态工厂模式

小结

工厂方法模式降低了对象之间的耦合度,依赖于抽象的架构,将实例化的任务交由子类去完成,有非常好的扩展性,符合软件设计原则。

优点:

1.在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。
2.在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。

缺点:

1.每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值