01-Spring中的工厂模式

工厂模式

工厂模式的三种形态: 工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式

  • 第一种:简单工厂模式是工厂方法模式的一种特殊实现,简单工厂模式又叫静态工厂方法模式不属于23种设计模式之一
  • 第二种:工厂方法模式, 是23种设计模式之一
  • 第三种:抽象工厂模式, 是23种设计模式之一

简单/静态工厂模式

简单工厂模式的优点

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时只需要向工厂索要即可, 客户端只负责消费,工厂只负责生产, 初步实现了责任的分离

简单工厂模式的缺点

  • 工厂类集中了所有产品的创造逻辑,有人把它叫做上帝类/全能类, 显然工厂类非常关键一旦出问题整个系统将瘫痪
  • 不符合OCP开闭原则,在进行系统产品扩展时需要修改工厂类的代码创建新的产品,这样客户端才能获取到扩展的产品

简单工厂模式的角色包括三个:抽象产品角色,具体产品角色, (静态)工厂类角色(提供创建对象的静态方法)

// 抽象产品角色: 武器
public abstract class Weapon {
    // 所有的武器都有攻击行为
    public abstract void attack();
}
// 具体产品角色:坦克
public class Tank extends Weapon{
    @Override
    public void attack() {
        System.out.println("坦克开炮!");
    }
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{
    @Override
    public void attack() {
        System.out.println("战斗机投下原子弹!");
    }
}
//工厂类角色:根据不同的武器类型不同的生产武器
public class WeaponFactory {
    // 根据不同的武器类型生产不同的武器
    public static Weapon get(String weaponType){
        if (weaponType == null || weaponType.trim().length() == 0) {
            return null;
        }
        Weapon weapon = null;
        if ("TANK".equals(weaponType)) {
            weapon = new Tank();
        } else if ("FIGHTER".equals(weaponType)) {
            weapon = new Fighter();
        } else {
            throw new RuntimeException("不支持该武器!");
        }
        return weapon;
    }
}

编写测试程序,通过指定武器的类型从静态工厂中获取对应的武器

public class Client {
    public static void main(String[] args) {
        Weapon weapon1 = WeaponFactory.get("TANK");
        weapon1.attack();

        Weapon weapon2 = WeaponFactory.get("FIGHTER");
        weapon2.attack();
    }
}

工厂方法模式

工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时只需要向对应的工厂索要即可, 客户端只负责消费,工厂只负责生产
  • 如果想进行产品扩展,只需要添加一个具体产品类和一个具体工厂类,不需要修改原来的代码符合OCP原则

工厂方法模式的缺点

  • 每次增加一个产品时都需要增加一个具体类和对象实现工厂, 使得系统中类的个数成倍增加导致系统的复杂度增加,同时也增加了系统具体类的依赖

工厂方法模式的角色包括:抽象工厂角色(生产多种武器), 具体工厂角色(一个工厂对应生产一种武器), 抽象产品角色, 具体产品角色

//抽象工厂角色: 专门生产各种武器的工厂
public interface WeaponFactory {
    Weapon get();
}
//具体工厂角色:专门生产枪的工厂
public class GunFactory implements WeaponFactory{
    @Override
    public Weapon get() {
        return new Gun();
    }
    
}
//具体工厂角色:专门生成飞机的工厂(工厂也可以通过简单工厂模式封装成一个大工厂,然后调用其的静态方法创建对应的工厂)
public class FighterFactory implements WeaponFactory{
    @Override
    public Weapon get() {
        return new Fighter();
    }
}
// 抽象产品角色: 武器类
public abstract class Weapon {
    // 所有武器都有攻击行为
    public abstract void attack();
}
// 具体产品角色:枪
public class Gun extends Weapon{
    @Override
    public void attack() {
        System.out.println("开枪射击!");
    }
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{
    @Override
    public void attack() {
        System.out.println("战斗机发射核弹!");
    }
}

编写测试程序,获取对应的工厂创建对应的产品

public class Client {
    public static void main(String[] args) {
        // 这里的new GunFactory()可以采用简单工厂模式进行隐藏,调用WeaponFactory的静态方法根据传递的参数创建对应的工厂
        WeaponFactory factory = new GunFactory();
        Weapon weapon = factory.get();
        weapon.attack();

        WeaponFactory factory1 = new FighterFactory();
        Weapon weapon1 = factory1.get();
        weapon1.attack();
    }
}

新增一个匕首产品类只需要新增一个该产品对应的匕首工厂即可

// 具体产品角色:匕首
public class Dagger extends Weapon{
  @Override
  public void attack() {
      System.out.println("切割!");
  }
}
//具体工厂角色:专门生产匕首的工厂
public class DaggerFactory implements WeaponFactory{
  @Override
  public Weapon get() {
      return new Dagger();
  }
}
// 测试生产新增的产品类
public class Client {
  public static void main(String[] args) {
      WeaponFactory factory2 = new DaggerFactory();
      Weapon weapon2 = factory2.get();
      weapon2.attack();
  }
}

抽象工厂模式

工厂方法模式是针对一个产品等级结构(一个产品系列一个工厂类),而抽象工厂模式是针对多个产品等级结构(多个产品系列一个工厂类)

抽象工厂模式的优点

  • 可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象
  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
  • 一个抽象工厂类可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例

抽象工厂模式缺点

  • 产品族扩展非常困难,要增加一个系列的某一产品,既要在AbstractFactory里加代码,又要在具体的里面加代码

在这里插入图片描述

抽象工厂中包含4个角色:抽象工厂角色, 具体工厂角色, 抽象产品角色, 具体产品角色

抽象产品角色:武器产品族,水果产品族

public abstract class Weapon {
    // 所以武器都有攻击行为
    public abstract void attack();
}

public abstract class Fruit {
    // 所有果实都有一个成熟周期
    public abstract void ripeCycle();
}

具体产品角色:武器产品族

// 武器产品族中的产品等级1
public class Gun extends Weapon{
    @Override
    public void attack() {
        System.out.println("开枪射击!");
    }
}

// 武器产品族中的产品等级2
public class Dagger extends Weapon{
    @Override
    public void attack() {
        System.out.println("切割!");
    }
}


// 水果产品族中的产品等级1
public class Orange extends Fruit{
    @Override
    public void ripeCycle() {
        System.out.println("橘子的成熟周期是10个月");
    }
}

package com.powernode.product;

// 水果产品族中的产品等级2 
public class Apple extends Fruit{
    @Override
    public void ripeCycle() {
        System.out.println("苹果的成熟周期是8个月");
    }
}

抽象工厂角色: 既能生产武器又能生产水果

public abstract class AbstractFactory {
    public abstract Weapon getWeapon(String type);
    public abstract Fruit getFruit(String type);
}

具体工厂角色: 武器族工厂, 水果族工厂,根据用户提供的名称创建具体的产品

// 武器族工厂
public class WeaponFactory extends AbstractFactory{
    public Weapon getWeapon(String type){
        if (type == null || type.trim().length() == 0) {
            return null;
        }
        if ("Gun".equals(type)) {
            return new Gun();
        } else if ("Dagger".equals(type)) {
            return new Dagger();
        } else {
            throw new RuntimeException("无法生产该武器");
        }
    }

    @Override
    public Fruit getFruit(String type) {
        return null;
    }
}
// 水果族工厂
public class FruitFactory extends AbstractFactory{
    @Override
    public Weapon getWeapon(String type) {
        return null;
    }

    public Fruit getFruit(String type){
        if (type == null || type.trim().length() == 0) {
            return null;
        }
        if ("Orange".equals(type)) {
            return new Orange();
        } else if ("Apple".equals(type)) {
            return new Apple();
        } else {
            throw new RuntimeException("我家果园不产这种水果");
        }
    }
}

测试程序

public class Client {
    public static void main(String[] args) {
        // 客户端调用方法时只面向AbstractFactory调用方法
        AbstractFactory factory = new WeaponFactory(); 
        Weapon gun = factory.getWeapon("Gun");
        Weapon dagger = factory.getWeapon("Dagger");
        gun.attack();
        dagger.attack();

        AbstractFactory factory1 = new FruitFactory(); 
        Fruit orange = factory1.getFruit("Orange");
        Fruit apple = factory1.getFruit("Apple");
        orange.ripeCycle();
        apple.ripeCycle();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值