更多关于设计模式的文章请点击设计模式之禅(0)-目录页


工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一、简单工厂模式

1.1、单一new方式

我们在开发项目时如果需要获取对象,通常会使用单一new的方式去获取它:

	Object object1 = new Object1();
	Object object2 = new Object2();
	Object object3 = new Object3();

我们或许还会在创建出来后进行一些处理:

	Object object1 = new Object1();
	object1.setA(A);
	object1.setB(B);
	Object object2 = new Object2();
	object2.setA(A);
	object2.setB(B);
	Object object3 = new Object3();
	object3.setA(A);
	object3.setB(B);

这会暴露出一个问题:
所有的创建过程和固定的操作都需要写出来,并且在本地代码中将其暴露。这不符合写入不变的、封装变化的代码的设计模式,所以说,我们需要一个类似于工厂的角色去产生这些对象,并且对它们进行一些固定的操作。这样就自然而然地引出了简单工厂模式(Simple Factory Pattern)。

1.2、简单工厂模式

简单工厂模式(Simple Factory Pattern)的使用很简单,再拿我们的动物简单工厂来举例子:

public class SimpleAnimalFactory{
    public Animal getAnimal(String type){
        if(type.equals("Dog")){
      		Animal dog =  new Dog();
      		//处理dog
            return  dog ;
        }else if(type.equals("Cat")){
            Animal cat=  new Cat();
      		//处理cat
            return  cat;
        }
    }
}

当我们需要Dog时,只需要创建SimpleAnimalFactory,再用其调用getAnimal(“Dog”)即可获得一只"经过处理的狗",而且这些创建和处理对"调用者"来说是"不可见"的,调用者并不在乎工厂内部到底做了什么,只需要获得经过处理的对象。

那么,工厂模式就这样讲完了吗?当然不是。其实,简单工厂模式并不算是一种设计模式,工厂模式也远没那么简单。

二、抽象工厂及工厂方法

2.1、将简单工厂改造成抽象工厂

在上面的简单工厂中,我们所实现的SimpleAnimalFactory已经能帮助我们获得简单的动物了,但是当我们需要动物园的动物时,我们需要制造一个ZooAnimalFactory;同理,当我们需要野生动物时,我们需要WildAnimalFactory,我们可以这样写:

  • ZooAnimalFactory
public class ZooAnimalFactory{
  
    public Animal getAnimal(String type) {
        if(type.equals("ZooDog")){
            return new ZooDog();
        }else if(type.equals("ZooCat")){
            return  new ZooCat();
        }
        return null;
    }
}
  • WildAnimalFactory
public class WildAnimalFactory{
   
    public Animal getAnimal(String type) {
        if(type.equals("WildDog")){
            return new WildDog();
        }else if(type.equals("WildCat")){
            return  new WildCat();
        }
        return null;
    }
}

如果你需要其他各种各样的工厂,我们只能一遍又一遍地写着,那么为什么我们不能抽取出来一个动物工厂超类,让其他工厂去继承它,获得工厂所需的方法和属性呢?这就是抽象工厂:

  • AnimalFactory
public abstract class AnimalFactory {
    public abstract Animal getAnimal(String type);
    }
}

此时,我们的ZooAnimalFactory和WildAnimalFactory可以这样写:

  • ZooAnimalFactory
public class ZooAnimalFactory extends AnimalFactory{
  	@Override
    public Animal getAnimal(String type) {
        if(type.equals("ZooDog")){
            return new ZooDog();
        }else if(type.equals("ZooCat")){
            return  new ZooCat();
        }
        return null;
    }
}
  • WildAnimalFactory
public class WildAnimalFactory extends AnimalFactory{
   @Override
    public Animal getAnimal(String type) {
        if(type.equals("WildDog")){
            return new WildDog();
        }else if(type.equals("WildCat")){
            return  new WildCat();
        }
        return null;
    }
}

2.2、为抽象工厂中添加工厂方法

我们上面的抽象工厂已经可以满足基本的需求了,但是还有一点美中不足:工厂中的动物由getAnimal(String type)方法创建,这里头真正产生动物的代码没有被封装起来,这就是所谓的工厂方法,即真正产生出对象的方法,我们可以在抽象工厂中添加一个工厂方法createAnimal(String type),并且让子类去重写这个工厂方法。

  • AnimalFactory
/**
 * @Auther: ARong
 * @Date: 2018/11/25 19:34
 * @Description: 动物工厂超类
 */
public abstract class AnimalFactory {

    public Animal getAnimal(String type){
        //调用createAnimal方法,该方法由实现类去重写
        Animal animal = createAnimal(type);
        return animal;
    }

    protected abstract Animal createAnimal(String type);
}

三、工厂模式总结

以上工厂模式的类,可以用简单的UML关系图来表示:
设计模式之禅(4)-工厂模式

  • AnimalFactory
/**
 * @Auther: ARong
 * @Date: 2018/11/25 19:34
 * @Description: 动物工厂超类
 */
public abstract class AnimalFactory {

    public Animal getAnimal(String type){
        //调用createAnimal方法,该方法由实现类去重写
        Animal animal = createAnimal(type);
        return animal;
    }

    protected abstract Animal createAnimal(String type);
}
  • ZooAnimalFactory
/**
 * @Auther: ARong
 * @Date: 2018/11/25 19:36
 * @Description: AnimalFactory的实现类
 */
public class ZooAnimalFactory extends AnimalFactory{


    //按需重写createAnimal方法
    @Override
    protected Animal createAnimal(String type) {

        if(type.equals("ZooDog")){
            return new ZooDog();
        }else if(type.equals("ZooCat")){
            return  new ZooCat();
        }

        return null;
    }
}
  • WildAnimalFactory
/**
 * @Auther: ARong
 * @Date: 2018/11/25 19:41
 * @Description: AnimalFactory的实现类,野生动物工厂
 */
public class WildAnimalFactory extends AnimalFactory{
    @Override
    protected Animal createAnimal(String type) {

        if(type.equals("WildDog")){
            return new WildDog();
        }else if(type.equals("WildCat")){
            return  new WildCat();
        }


        return null;
    }
}
  • Animal
/**
 * @Auther: ARong
 * @Date: 2018/11/17 11:08
 * @Description:动物的抽象类,定义动物的属性以及抽象行为和具体行为
 */
public abstract class Animal {
    //动物名称
    private String name;
    //定义run方法
    public abstract  void run();

    //get、set
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • ZooCat/ZooDog/WildCat/WildDog的代码不列出了

  • 测试

/**
 * @Auther: ARong
 * @Date: 2018/11/25 19:44
 * @Description: 动物工厂测试
 */
public class TestAnimalFactory {


    @Test
    public void getZooAnimal(){
        AnimalFactory zooAnimalFactory = new ZooAnimalFactory();
        Animal zooDog = zooAnimalFactory.getAnimal("ZooDog");
        zooDog.run();
    }


    @Test
    public void getWildAnimal(){
       AnimalFactory wildAnimalFactory = new WildAnimalFactory();
        Animal wildCat = wildAnimalFactory.getAnimal("WildCat");
        wildCat.run();
    }

}

相关文章:

  • 2021-07-03
  • 2022-12-23
  • 2021-07-11
猜你喜欢
  • 2021-08-06
  • 2021-07-27
  • 2021-07-07
  • 2021-11-08
  • 2021-04-02
  • 2021-08-30
  • 2021-06-29
相关资源
相似解决方案