文章目录
什么是工厂模式?
工厂模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
简单工厂
简单工厂又称为静态工厂,定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类或接口
简单工厂模式核心角色
简单工厂模式需要有三种角色
- 一个抽象产品。通常是接口或抽象类 。 比如Animal接口
- 多个具体产品。接口或抽象类的具体实现产品,实现了接口或继承了抽象类。比如Dog类
- 一个工厂类,提供了获取对象实例的静态方法,返回对象的接口类型。在方法内部,根据参数动态创建实际类型的对象。比如AnimalFactory类中Animal getAnimal(String animalName)方法
简单工厂模式示例
定义一个Animal 接口
public interface Animal{
}
定义一个猫类,实现了动物接口
public class Cat implements Animal{
}
定义一个狗类,实现了动物接口
public class Dog implements Animal{
}
定义一个工厂类,用于获取上面所定义的类的实例。
public class AnimalFactory {
public static Animal getAnimal(String className){
Animal animal= null;
switch (className) {
case "cat":
animal = new Cat();
break;
case "dog":
animal = new Dog();
break;
default:
System.out.println("类型有误:"+ name);
}
return cal;
}
}
使用方式:
Animal cat = AnimalFactory.getAnimal("cat");
简单工厂模式特点:
隐藏了对象创建的细节和具体类型,只需要传入相应的参数即可。
因为所有对象的创建都在一个工厂类中进行,导致扩展性较差
工厂方法模式
工厂方法模式是对简单工厂的延伸。他为每一种产品都提供了一个工厂。
工厂方法模式核心角色
工厂方法模式需要有四种角色
- 一个抽象产品,接口或抽象类。比如Animal接口
- 多个具体产品。接口或抽象类的具体实现产品,实现了产品接口或继承了抽象类。比如Cat 类
- 一个抽象工厂,通常是接口或抽象类。比如 AnimalFactory 接口,定义产生Animal的抽象方法。
- 多个具体工厂,实现了抽象工厂。在实现方法中返回所负责生产的产品的具体实例。比如CatFactory工厂类,实现AnimalFactory接口,返回Cat实例。
工厂方法模式示例
首先还是定义动物接口、猫、狗类
// 抽象产品 Animal
public interface Animal{
}
// 具体产品 Cat
class Cat implements Animal{
}
// 具体产品 Dog
class Dog implements Animal{
}
定义抽象工厂:
public interface AnimalFactory{
Animal getObject();
}
定义生产猫的具体工厂:
// 猫工厂
public class CatFactory implements AnimalFactory{
Animal getObject(){
return new Cat();
}
}
定义生产狗的具体工厂:
// 狗工厂
public class DogFactory implements AnimalFactory{
Animal getObject(){
return new Dog();
}
}
使用方式:
AnimalFactory factory= new CatFactory();
// 得到猫的对象实例,用Animal接收。
Animal animal = factory.getObject();
工厂方法模式特点:
- 相对于简单工厂来说,扩展性更强。新增一个具体产品,只需要新增一个对应的工厂即可。
- 如果有很多具体产品,会导致工厂类过多,系统较为庞大
- 只能生产一种抽象产品。
- 没有隐藏工厂的创建。
抽象工厂模式
由上面的例子看出,工厂方法模式,没有隐藏工厂的创建,还需要手动创建某种类型的工厂。而抽象工厂模式是将工厂方法和简单工厂模式结合起来。将工厂类进一步工厂化。提供一个可以生产工厂的工厂类。隐藏了工厂的创建细节。同时该工厂类可以创建多种不同类型的工厂,也说明了该模式可以支持创建多种抽象产品。
抽象工厂模式核心角色
抽象工厂模式需要有五种角色
- 多个抽象产品
- 每个抽象产品有多个具体产品
- 一个抽象工厂
- 多个具体工厂,分别生产各自类型的具体产品
- 一个工厂生产类,用来获取不同类型的工厂。
抽象工厂模式示例
定义一个Animal 接口 和猫、狗类
public interface Animal{
}
class Cat implements Animal{
}
class Dog implements Animal{
}
定义一个植物接口 和 花、草类
public interface Plant{
}
// 花类
class Flower implements Plant{
}
// 草类
class grass implements Plant{
}
定义一个抽象工厂,工厂里定义了产生对象的方法,这里可以通过泛型来动态返回不同类型的具体产品
public interface IFactory<T>{
T getObject(String name);
}
定义一个动物工厂,实现抽象工厂,返回动物类型的具体产品
public calss AnimalFactory implements IFactory<Animal>{
Animal getObject(String name){
Animal result = null;
if(name.equals("cat")){
result = new Cat();
}else if(name.equals("dog")){
result = new Dog();
}
return result;
}
}
定义一个植物工厂,实现抽象工厂,返回植物类型的具体产品
public calss PlantFactory implements IFactory<Plant>{
Plant getObject(String name){
Plant result = null;
if(name.equals("flower")){
result = new Flower();
}else if(name.equals("grass")){
result = new Grass ();
}
return result;
}
}
可以看到,两个具体工厂的实现方法中,用来生产各自抽象产品的具体产品。动物工厂负责生产动物,植物工厂用来生产植物。
现在在以上基础上,编写一个生产工厂的类,也就是工厂的工厂,可以根据参数动态创建不同的工厂:
public class FactoryProducer{
public static IFactory getFactory(String name) {
IFactory factory = null;
if ("animal".equals(name)) {
factory = new AnimalFactory();
}
if ("plant".equals(name)) {
factory = new PlantFactory();
}
return factory;
}
}
测试:
// 获取植物工厂
IFactory f1 = FactoryProducer.getFactory("plant");
// 获取植物具体产品,花
Plant flower = (Plant)f1.getObject("flower');
// 获取植物具体产品,草
Plant grass = (Plant)f1.getObject("grass');
// 获取动物工厂
IFactory f2 = FactoryProducer.getFactory("animal");
// 获取动物具体产品,猫
Animal cat = (Animal)f2.getObject("cat');
// 获取动物具体产品,狗
Animal dog = (Animal)f2.getObject("dog');
抽象工厂模式特点
扩展性强
隐藏了工厂和具体产品的创建细节
可以生产多种类型的产品