从餐具的生产说到抽象工厂

从餐具的生产说到抽象工厂

在上一篇文章中我们探索和了解了什么是工厂模式,接下来我们继续深入到抽象工厂

什么是抽象工厂

抽象工厂模式是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类

理解

我对抽象工厂模式的理解是为了创建一套一套的产品而存在的工厂模式。比如:

  1. 网页风格可以使用抽象工厂模式,一键换肤,朋克画风、Q版画风、极简画风等。虽然画风不同,但是每种画风都会有按钮颜色、按钮边框大小等页面细节信息。
  2. 游戏中的地图风格也可以使用抽象工厂模式,熔岩地图、冰雪地图、沙漠地图等。虽然地图风格不同,但每种地图都会大地、树木、移动力等细节参数。
  3. 餐具生产厂商也可以使用抽象工厂模式,生产一次性餐具的工厂和生产可回收使用餐具的工厂。虽然工厂不同,但是他们都生产碗、筷子、盘子等餐具。

餐具工厂

我们用餐具工厂这个例子来体会一下什么是抽象工厂

  1. 首先我们定义一下工厂以及要生产的产品

    /**
     * 餐具的顶层接口
     * @author wangxing
     */
    public interface Tableware {
    
        /**
         * 使用
         */
        void use();
    
        /**
         * 回收
         */
        void recycle();
    }
    
    /**
     * 碗
     * @author wangxing
     */
    public interface Bowl extends Tableware {}
    
    /**
     * 筷子
     * @author wangxing
     */
    public interface Chopsticks extends Tableware {}
    
    /**
     * 盘子
     * @author wangxing
     */
    public interface Plate extends Tableware {}
    
    /**
     * 餐具工厂
     * @author wangxing
     */
    public interface TablewareFactory {
    
        /**
         * 生产筷子
         * @param user 筷子的使用者
         * @return 筷子
         */
        Chopsticks createChopsticks(String user);
    
        /**
         * 生产碗
         * @param user 碗的使用者
         * @return
         */
        Bowl createBowl(String user);
    
        /**
         * 生产盘子
         * @param user 盘子的使用者
         * @return
         */
        Plate createPlate(String user);
    }
    

    我们在接口定义了碗Bowl、盘子Plate、筷子Chopsticks,以及工厂需要能够生产碗createBowl、生产盘子createPlate、生产筷子createChopsticks。但是并没有具体的声明要如何生产,以及具体的产品类型。

  2. 接下来我们定义一种一次性餐具的工厂,以及一些一次性餐具

    /**
     * 一次性碗
     * @author wangxing
     */
    public class DisposableBowl implements Bowl{
        @Override
        public void use() {
            System.out.println("这是一次性碗");
        }
    
        @Override
        public void recycle() {
            System.out.println("用完就扔掉吧");
        }
    }
    /**
     * 一次性筷子
     * @author wangxing
     */
    public class DisposableChopsticks implements Chopsticks{
        @Override
        public void use() {
            System.out.println("这是一次性筷子");
        }
    
        @Override
        public void recycle() {
            System.out.println("用完扔掉");
        }
    }
    /**
     * 一次性的盘子
     * @author wangxing
     */
    public class DisposablePlate implements Plate {
        @Override
        public void use() {
            System.out.println("这是一次性盘子");
        }
    
        @Override
        public void recycle() {
            System.out.println("用完扔掉吧");
        }
    }
    
    /**
     * 一次性餐具工厂
     * @author wangxing
     */
    public class DisposableTablewareFactory implements TablewareFactory {
        @Override
        public Chopsticks createChopsticks(String user) {
            return new DisposableChopsticks();
        }
    
        @Override
        public Bowl createBowl(String user) {
            return new DisposableBowl();
        }
    
        @Override
        public Plate createPlate(String user) {
            return new DisposablePlate();
        }
    }
    

    通过这个一次性餐具工厂我们可以生产出很多一次性的餐具。

  3. 然后我们再定义一个可回收的餐具的餐具工厂

    /**
     * 可反复使用的碗
     * @author wangxing
     */
    public class RepeatableBowl implements Bowl {
        @Override
        public void use() {
            System.out.println("这个碗可以反复使用");
        }
    
        @Override
        public void recycle() {
            System.out.println("用完洗一洗");
        }
    }
    
    /**
     * 可反复使用的筷子
     * @author wangxing
     */
    public class RepeatableChopsticks implements Chopsticks {
        @Override
        public void use() {
            System.out.println("这是可反复使用的筷子");
        }
    
        @Override
        public void recycle() {
            System.out.println("用完洗一洗");
        }
    }
    
    /**
     * 可反复使用的盘子
     * @author wangxing
     */
    public class RepeatablePlate implements Plate {
        @Override
        public void use() {
            System.out.println("这是一次性盘子");
        }
    
        @Override
        public void recycle() {
            System.out.println("用完扔掉吧");
        }
    }
    
    /**
     * 可反复使用的餐具的工厂
     * @author wangxing
     */
    public class RepeatableTablewareFactory implements TablewareFactory {
        private final ConcurrentHashMap<String, Chopsticks> chopsticksCache = new ConcurrentHashMap<>();
        private final ConcurrentHashMap<String, Bowl> bowlCache = new ConcurrentHashMap<>();
        private final ConcurrentHashMap<String, Plate> plateCache = new ConcurrentHashMap<>();
    
        @Override
        public Chopsticks createChopsticks(String user) {
            return chopsticksCache.computeIfAbsent(user, k -> new RepeatableChopsticks());
        }
    
        @Override
        public Bowl createBowl(String user) {
            return bowlCache.computeIfAbsent(user, k -> new RepeatableBowl());
        }
    
        @Override
        public Plate createPlate(String user) {
            return plateCache.computeIfAbsent(user, k -> new RepeatablePlate());
        }
    }
    

总结

通过上面的代码我们定义了两个产品族。一个是一次性餐具,一个是可回收使用的餐具。当我们使用一次性餐具时,我们使用DisposableTablewareFactory 作为TablewareFactory的具体实现。当我们使用可回收餐具时,我们使用RepeatableTablewareFactory 作为TablewareFactory的具体实现。我们仅仅是换了工厂的实现类,就达到了替换两种不同餐具的效果

与工厂方法的对比

  1. 感觉上好像抽象工厂只是比工厂方法多生产了很多产品而已。如果一个工厂只生产一种产品,那这就是工厂方法,但是如果要生成多个产品(这里机油了产品族的概念),那就是抽象工厂
  2. 工厂方法强调产品,而抽象工厂强调产品族。
  3. 当你的产品灵活多变或者产品的创建需要隐藏时,使用工厂方法。当你有一系列的产品(风格)灵活多变时,使用抽象工厂。
  4. 最后再强调一遍,产品—>工厂方法产品族—>抽象工厂
上一篇:Photoshop打造唯美梦幻般的折叠式圣诞贺卡


下一篇:Photoshop打造红色梦幻爱情立体字效果