工厂模式

91 阅读3分钟

这篇文章简单介绍java工厂设计模式,用最简单的例子演示如何使用工厂模式,以及为什么要用工厂模式。

使用场景:

在开发中我们经常使用抽象类或者接口定义一类功能,通过具体的实现类实现。创建这些实现类的时候可以使用工厂类来简化代码,提高代码的扩展性。

代码演化:

不使用工厂模式

interface Animal {
    void eat();
}

Class Dog implements Animal {
    public void eat(){
        System.out.println("吃骨头");
    }
}

Class Cat implements Animal {
    public void eat(){
        System.out.println("吃鱼");
    }
}

class MainClass {
    private String anl = "dog";
    public static void main(String args[]) {
        Animal animal;
        if ("dog".equals(anl)){
            animal = new Dog();
        } else if ("cat".equals(anl)){
            animal = new Cat();
        }
        animal.eat();
    } 
}

使用简单工厂模式

在调用的时候都是使用new创建对象的,调用者不一定对Animal这个接口了解。所以我们可以在开发Animal的同时创建工厂类,这样调用的时候不需要写这么多if else,就能创建对象了。

interface Animal {
    void eat();
}

Class Dog implements Animal {
    public void eat(){
        System.out.println("吃骨头");
    }
}

Class Cat implements Animal {
    public void eat(){
        System.out.println("吃鱼");
    }
}

class AnimalFactory {
    public static Animal getAnimal(String anl) {
        Animal animal;
        if ("dog".equals(anl)){
            animal = new Dog();
        } else if ("cat".equals(anl)){
            animal = new Cat();
        }
        return animal;
    } 
}

class MainClass {
    public static void main(String args[]) {
        Animal animal = AnimalFactory.getAnimal("dog");
        animal.eat();
    } 
}

使用工厂方法模式

简单工厂模式最大的问题就是,每一次增加新的实现类的时候修改修改工厂类创建对象的方法,如果实现类比较多的时候,if else会非常的长。
这时候就演化出工厂方法模式: 就是想工厂类抽象化,每一个实现类对应一个工厂抽象类,调用者使用工厂抽象类(这个可以在配置文件中配置,这样修改工厂类不需要重新build工程)去创建对应的对象。 这种方式,在开发新的实现类的时候就可以开发新的对应的工厂实现类,不会影响以前的代码。

interface Animal {
    void eat();
}

Class Dog implements Animal {
    public void eat(){
        System.out.println("吃骨头");
    }
}

Class Cat implements Animal {
    public void eat(){
        System.out.println("吃鱼");
    }
}

interface AnimalFactory {
    Animal getAnimal();
}

class DogFactory implements AnimalFactory{
    public Animal getAnimal() {
       return new Dog();
    } 
}

class CatFactory implements AnimalFactory{
    public Animal getAnimal() {
       return new Cat();
    } 
}

class MainClass {
    public static void main(String args[]) {
        //DogFactory可以在配置文件中配置,通过放射的方式创建工厂类
        Animal animal = DogFactory.getAnimal();
        animal.eat();
    } 
}

抽象工厂模式

工厂方法模式也存在问题,就是如果一个借口有很多实现类,那么也就会有很多实现工厂类。这也是一种资源消耗。为了解决这个问题,就有了抽象工厂模式:

  • 将所有的工厂类进行分类,每一个具体的工厂类都能创建一类对象。
    当然抽象工厂类也有扩展性问题:
  • 扩展新的工厂类是很容易,但是对于已经有的工厂类,如果想要扩容让他创建新的对象,那就十分困难。 比如,我们将动物分成野生动物和宠物。那么DogFactory可以创建野生狗和宠物狗,CatFactory可以创建野生猫和宠物猫。那么新增新的工厂比如PigFactory是很容易的,但是假如又有一类新的Dog,那么DogFactory就很难创建它了。
interface Animal {
    void eat();
}

Class PegDog implements Animal {
    public void eat(){
        System.out.println("吃骨头罐头");
    }
}

Class WildDog implements Animal {
    public void eat(){
        System.out.println("吃骨头渣");
    }
}

Class PegCat implements Animal {
    public void eat(){
        System.out.println("吃鱼饼干");
    }
}

Class WildCat implements Animal {
    public void eat(){
        System.out.println("吃鱼骨头");
    }
}

abstract class AbstractAnimalFactory {
    abstract Animal getPegAnimal();
    abstract Animal getWildAnimal();
}

class DogFactory extends AbstractAnimalFactory{
    public Animal getPegAnimal() {
       return new PegDog();
    } 
    
    public Animal getWildAnimal() {
       return new WildDog();
    }
}

class CatFactory extends AbstractAnimalFactory{
    public Animal getPegAnimal() {
       return new PegCat();
    } 
    
    public Animal getWildAnimal() {
       return new WildCat();
    } 
}

class MainClass {
    public static void main(String args[]) {
        //DogFactory可以在配置文件中配置,通过放射的方式创建工厂类
        Animal peg = DogFactory.getPegAnimal();
        Animal wild = DogFactory.getWildAnimal();
        peg.eat();
        wild.eat();
    } 
}