设计模式|简单工厂、工厂方法、抽象工厂

本文深入探讨了简单工厂和工厂方法两种设计模式的概念、优缺点及应用场景。通过动物类的实例,展示了如何使用简单工厂模式减少应用层对具体实现类的依赖,以及工厂方法模式如何进一步提高代码的扩展性和遵循开闭原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单工厂

概念

  • 定义:

    由一个工厂对象决定创建出哪一种产品类的实例

  • 类型:

    创建型,但不属于GOF23种设计模式

  • 使用场景

  • 优点

  • 缺点

案例一

动物的抽象类

public abstract class Animal {
    public abstract void eat();
}
public class Cat extends Animal {
    public void eat() {
        System.out.println("Cat is eating");
    }
}
public class Dog extends Animal {
    public void eat() {
        System.out.println("Dog is eating");
    }
}
public class Demo {
    @Test
    public void demo1(){
        Animal cat = new Cat();
        cat.eat();
        Animal dog = new Dog();
        dog.eat();
    }
}

在这里插入图片描述

缺点:应用层依赖具体的实现类

思路:让应用层不依赖具体的实现类

重构

简单工厂demo1

public class AnimalFactory {
    
    public Animal getAnimal(String name){
        Animal animal = null;
        if ("cat".equalsIgnoreCase(name)){
            animal = new Cat();
        }else if ("dog".equalsIgnoreCase(name)){
            animal = new Dog();
        }
        
        return animal;
    }
    
}

测试

@Test
public void demo2(){
    AnimalFactory animalFactory = new AnimalFactory();
    Animal cat = animalFactory.getAnimal("cat");
    if (cat == null){
        return;
    }
    cat.eat();
}

缺点:当需要新增一个实现时,需要破坏animalFactory原有的代码,不符合开闭原则。

简单工厂demo2

在AnimalFactory工厂类中,重写getAnimal方法

public Animal getAnimal(Class<Cat> c){
    Animal animal = null;
    try {
        animal = (Animal) Class.forName(c.getName()).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return animal;
}

测试

@Test
public void demo3(){
    AnimalFactory animalFactory = new AnimalFactory();
    Animal cat = animalFactory.getAnimal(Cat.class);
    if (cat == null){
        return;
    }
    cat.eat();
}

在这里插入图片描述

测试成功

工厂方法

概念

  • 定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
  • 类型:创建型
  • 使用场景
    • 创建对象需要大量重复的代码
    • 应用层不依赖与产品类实例如何被创建、实现等细节。
    • 一个类通过其子类来指定创建哪个对象
  • 优点
  • 用户只需要关心所需要对象对应的工厂,无需关心创建的细节。
  • 加入新的功能是复合开闭原则,提高扩展性
  • 缺点
    • 类的个数容易过多,增加复杂度
    • 增加了系统的抽象性和理解难度

案例二

安装工厂方法的定义,对上面的案例一进行重构

  • 将AnimalFactory定义成抽象类,定义一个创建对象的抽象方法。
public abstract class AnimalFactory {

    public abstract Animal getAnimal();

}

AnimalFactory只是定义一种规范,不定义具体的实现。完全交给子类来实现。

public class CatFactory extends AnimalFactory {
    public Animal getAnimal() {
        return new Cat();
    }
}
public class DogFactory extends AnimalFactory {
    public Animal getAnimal() {
        return new Dog();
    }
}

应用层调用

public class Demo {
    @Test
    public void demo4(){
        AnimalFactory catFactory = new CatFactory();
        Cat cat = (Cat) catFactory.getAnimal();
        cat.eat();
    }
}

在这里插入图片描述

这样扩展性增加了。

应用

Collection中的iterator方法

java.util.Collection 接口中定义了一个抽象的 iterator() 方法,该方法就是一个工厂方法。

对于 iterator() 方法来说 Collection 就是一个根抽象工厂,下面还有 List 等接口作为抽象工厂,再往下有 ArrayList 等具体工厂。

java.util.Iterator 接口是根抽象产品,下面有 ListIterator 等抽象产品,还有 ArrayListIterator 等作为具体产品。

使用不同的具体工厂类中的 iterator 方法能得到不同的具体产品的实例。

【参考】JDK中的工厂方法模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值