设计模式(4)-工厂模式


更多关于设计模式的文章请点击设计模式之禅(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关系图来表示:
在这里插入图片描述

  • 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();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值