自学内容网 自学内容网

Java设计模模式 - 工厂模式

设计模式 - 工厂模式

1 静态工厂模式

1.1 简单/静态工厂模式

静态工厂模式为创建型涉及模式

通过调用静态方法来创建对象,而不是通过构造器构造对象

优势:

  • 灵活:通过修改静态工厂方法来改变对象的创建逻辑,而不需要修改客户端的代码,客户端还是调用静态工厂即可;同时静态工厂可以有自己的名字,而不是像静态方法一样只能使用类名
  • 可读性更好
  • 限制实例化:可以显示实例化对象的个数,实现单例模式
  • 返回子类型:返回接口或者抽象类的实例,代码扩展性更好

缺陷:

  • 创建的类如果没有公有或者保护的构造方法,则类不发被扩展
  • 与其他静态方法实际没有区别,需要进行说明如何创建这个类
  • 增加产品时需要修改工厂类,违反了开闭原则,对扩展开放,对修改关闭

再创建类的时候,有时候静态工厂方法可能更加合适,而不是只考虑构造方法

1.2 举例

abstract class Animal{
    protected String name;
    protected String color;


    public Animal(String name, String color) {
        this.name = name;
        this.color = color;

    }

    public abstract void eat();

}

class Dog extends Animal{

    public Dog(String name, String color) {
        super(name, color);
    }

    @Override
    public void eat() {
        System.out.println("Dog " + this.name + "-"+ this.color + " is eating!");
    }
}

class Cat extends Animal {

    public Cat(String name, String color) {
        super(name, color);
    }

    @Override
    public void eat() {
        System.out.println("Cat " + this.name + "-" + this.color + " is eating!");
    }

}

// 静态工厂方法
class MyAnimalFactory {
    public static Optional<Animal> getAnimal(String type, String name, String color) {
        Animal animal = null;
        if ("dog".equals(type)) {
            animal = new Dog(name, color);
        } else if ("cat".equals(type)) {
            animal = new Cat(name, color);
        }
        return Optional.ofNullable(animal);
    }
}

使用

public class Main {

    public static void main(String[] args) {

        Optional<Animal> dogOpt = MyAnimalFactory.getAnimal("dog", "xixi", "white");
        dogOpt.ifPresent(dog -> dog.eat());

        Optional<Animal> catOpt = MyAnimalFactory.getAnimal("cat", "haha", "black");
        catOpt.ifPresent(cat -> cat.eat());

    }
}

输出:

Dog xixi-white is eating!
Cat haha-black is eating!

2 工厂模式

2.1 工厂方法

工厂方法定义一个创建对象的接口的工厂,需要子类来实例化具体的工厂,创建工厂需要子类来实现

优势:将产品实现和使用解耦,如果要改变产品的实现,对于创建者没有影响(调用创建者接口,而不关心如何创建)

缺陷:工厂方法太单一,一个工厂只能生产一个品类

与静态工厂方法相比:

  • 工厂方法相比,让子类关系如何实现,具备较大弹性,可以根据需求随意增加工厂,更加灵活
  • 静态工厂把事情放到一起做了,弹性不足

2.2 工厂方法举例


// 工厂方法
interface AnimalFactory {
    public Animal getAnimal(String name, String color);
}

class DogFactory implements AnimalFactory {

    @Override
    public Animal getAnimal(String name, String color) {
        // DogFactory init
        return new Dog(name, color);
    }

}

class CatFactory implements AnimalFactory {

    @Override
    public Animal getAnimal(String name, String color) {
        // CatFactory init
        return new Cat(name, color);
    }
}

public class Main {

    public static void main(String[] args) {
        DogFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.getAnimal("Xixi", "black");
        dog.eat();

        CatFactory catFactory = new CatFactory();
        Animal cat = catFactory.getAnimal("dongdong", "white");
        cat.eat();
    }
}

输出:

Dog Xixi-black is eating!
Cat dongdong-white is eating!

3 抽象工厂

3.1 抽象工厂

指定一个接口,用来创建依赖对象的家族的工厂,而不是指定具体的类

优势:可以把一群相关的产品集合起来,比如某些产品的颜色都是一样的
缺陷:增加新的品类比较困难,需要修改抽象接口,并实现

抽象工厂和工厂方法的区别:

  • 工厂方法基于类(DogFactory, CatFactory),抽象工厂基于对象(WhiteAnimalFactory需要制作具体的对象)
  • 工厂方法通过继承来创建对象,抽象方法通过组合来创建对象

3.2 举例

// 抽象工厂
interface AnimalPropertyFactory {
    Dog getDog(String name);
    Cat getCat(String name);
}

// White Aninal Factory
class WhiteAnimalFactory implements AnimalPropertyFactory {

    private static final String COLOR = "white";
    @Override
    public Dog getDog(String name) {
        return new Dog(name, COLOR);
    }

    @Override
    public Cat getCat(String name) {
        return new Cat(name, COLOR);
    }
}

class BlackAnimalFactory implements AnimalPropertyFactory {

    private static final String COLOR = "Black";
    @Override
    public Dog getDog(String name) {
        return new Dog(name, COLOR);
    }

    @Override
    public Cat getCat(String name) {
        return new Cat(name, COLOR);
    }
}


public class Main {

    public static void main(String[] args) {

        AnimalPropertyFactory whiteAnimalFactory = new WhiteAnimalFactory();
        Dog dog = whiteAnimalFactory.getDog("Xixi");
        dog.eat();

        AnimalPropertyFactory blackAnimalFactory = new BlackAnimalFactory();
        Cat cat = blackAnimalFactory.getCat("Haha");
        cat.eat();

    }
}

输出:

Dog Xixi-white is eating!
Cat Haha-Black is eating!

参考

静态工厂方法的优缺点 https://www.jianshu.com/p/fa15f63d399a

静态工厂方法(实际不是一种设计模式) https://www.cnblogs.com/mj-selina/p/12486980.html

工厂模式——工厂方法 https://www.cnblogs.com/mj-selina/p/12488176.html

工厂模式——抽象工厂 https://www.cnblogs.com/mj-selina/p/12488855.html


原文地址:https://blog.csdn.net/qq_44776065/article/details/142832339

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!