设计模式(十):抽象工厂模式(创建型模式)

时间:2024-03-09 13:08:01

        Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对
象的接口,而无须指定它们的具体类。

       之前写过简单工厂和工厂方法模式(创建型模式),这两种模式比较简单。

       简单工厂模式其实不符合开闭原则,即对修改关闭,扩展开放。简单工厂每次需要新增新的产品就需要修改工厂类。而工厂方法模式,每个工厂只负责创建单一的产品,相当于真实工厂里面的一条流水线,如果一个工厂自身能创建多个产品呢?那就需要抽象工厂了。

      三种工厂模式的区别:

      简单工厂模式:一个抽象产品类(或接口),可以派生出多个具体产品类。 
                               只有一个静态工厂,负责创建多个具体产品类的实例。
      工厂方法模式:一个抽象产品类(或接口),可以派生出多个具体产品类。   
                               一个抽象工厂类(或接口),可以派生出多个具体工厂类。   
                               每个具体工厂类只能创建一个具体产品类的实例。  
      抽象工厂模式:多个抽象产品类(或接口),可以派生出多个具体产品类。   
                               一个抽象工厂类(或接口),可以派生出多个具体工厂类。   
                               每个具体工厂类可以创建多个具体产品类的实例。   
   
区别:工厂方法模式只有一个抽象产品类(或接口),而抽象工厂模式有多个。   
      工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。


“抽象工厂”就像真的工厂,“工厂方法”就像工厂中的一条生产线。

抽象工厂模式Demo:

先看类图:

工程结构:

上代码:

package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:Fruit
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:水果接口
 * @Date:2024/3/8 10:25
 * @Author:figo
 */
public interface Fruit {
    //采摘
    void pick();
}

package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:Apple
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:苹果产品
 * @Date:2024/3/8 10:32
 * @Author:figo
 */
public class Apple implements Fruit{

    @Override
    public void pick() {
        System.out.println("采摘苹果");
    }
}

package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:Banana
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:香蕉产品
 * @Date:2024/3/8 10:35
 * @Author:figo
 */
public class Banana implements Fruit{

    @Override
    public void pick() {
        System.out.println("采摘香蕉");
    }
}


package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:Bag
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:包装盒接口
 * @Date:2024/3/8 10:36
 * @Author:figo
 */
public interface Bag {
    //打包
    void pack(Fruit fruit);
}


package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:AppleBag
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:苹果包装盒
 * @Date:2024/3/8 10:37
 * @Author:figo
 */
public class AppleBag implements Bag{
    @Override
    public void pack(Fruit fruit) {
        System.out.println("苹果盒打包苹果");
    }
}



package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:BananaBag
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:香蕉包装盒
 * @Date:2024/3/8 10:37
 * @Author:figo
 */
public class BananaBag implements Bag{

    @Override
    public void pack(Fruit fruit) {
        System.out.println("香蕉盒打包苹果");

    }
}


package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:AbstractFactory
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:抽象工厂,能生产多种产品,比工厂方法模式只能生产单一产品更强
 * @Date:2024/3/8 10:42
 * @Author:figo
 */
public abstract class AbstractFactory {
    public abstract  Fruit getFruit();
    public abstract Bag getBag();
}

package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:AppleFactory
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:苹果工厂能生产苹果和苹果包装盒
 * @Date:2024/3/8 10:46
 * @Author:figo
 */
public class AppleFactory extends AbstractFactory{
    @Override
    public Fruit getFruit() {
        return new Apple();
    }

    @Override
    public Bag getBag() {
        return new AppleBag();
    }
}



package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:BananaFactory
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:香蕉工厂,能生产香蕉也能生产香蕉包装盒
 * @Date:2024/3/8 10:49
 * @Author:figo
 */
public class BananaFactory extends AbstractFactory{
    @Override
    public Fruit getFruit() {
        return new Banana();
    }

    @Override
    public Bag getBag() {
        return new BananaBag();
    }
}


package com.figo.study2024.pattern.abstractfactory;

/**
 * @ClassName:FruitGardenClient
 * @PackageName:com.figo.study2024.pattern.abstractfactory
 * @Description:水果园客户端,测试抽象工厂模式
 * @Date:2024/3/8 10:51
 * @Author:figo
 */
public class FruitGardenClient {
    public static void main(String[] args) {
        fruitOrder();
    }

    /**
     * 水果订单
     */
    public static void fruitOrder()
    {
        //初始化工厂
        AbstractFactory factory = new AppleFactory();//spring使用注入方式,这里测试苹果工厂
        //苹果工厂能生产苹果
        Fruit fruit = factory.getFruit();
        fruit.pick();
        //苹果工厂也能生产包装盒
        Bag bag = factory.getBag();
        bag.pack(fruit);
        //以下物流运输业务。。。。
    }
}