首页
学习
活动
专区
圈层
工具
发布

设计模式(三):旅行的角度理解抽象工厂模式

之前的文章介绍了工厂模式,这篇文章介绍工厂模式的强化版本抽象工厂模式(Abstract Factory Pattern) 。

我们知道工厂模式是用于在延迟创建具体的对象,抽象工厂模式可以看作是面向工厂模式的工厂模式,所以,我称它为强化版本。

什么时候用抽象工厂模式?

我个人并不喜欢抽象工厂模式,因为它一定是为了应付复杂的系统。

试想一下,谁喜欢负责的东西呢?

但软件行业,复杂的业务其实代表了更精细化的需求,所以,这也是它的意义所在。

抽象工厂模式是为了应对产品线,产品线有不同的分支,每个分支代表不同的维度。

还是以前面工厂模式中的出行举例子。

从广州到深圳出行,乘坐交通工具的话有:飞机、高铁、大巴等等选项。

但另外一种维度,我不考虑具体的交通工具,我只考虑舒适程度,那么我就有下面的选择:

  1. 经济档(硬座、二等座、经济舱)
  2. 舒适档(软座、一等座)
  3. 豪华档(商务座、头等舱)

我们都知道,软件开发要拥抱变化,当面对同一个客户,他的需求发生变化时,我们的代码也需要做调整。

抽象工厂模式可以应对这种需求。

抽象工厂模式实现

首先,交通工具类型用一个工厂表示,这和之前的文章无异。

然后,照葫芦画瓢,再弄一个档次工厂。

然后,再针对交通工具和档次工厂设计一个工厂

最后,整体 UML 图就出来了。

当 UML 图出来后,剩下的就是编码工作了。

Java 代码实现

1. 交通工具接口及实现类

Transportation.java

代码语言:javascript
复制
public interface Transportation {
   void move(String dst);
}

Bus.java

代码语言:javascript
复制
public class  Bus  implements Transportation{

    @Override
    public void move(String dst) {
        // TODO Auto-generated method stub
        System.out.println("Take a bus to "+dst);
    }
}

Tran.java

代码语言:javascript
复制
public class  Train  implements Transportation{

    @Override
    public void move(String dst) {
        // TODO Auto-generated method stub
        System.out.println("Take a train to "+dst);
    }
}

Plane.java

代码语言:javascript
复制
public class  Plane  implements Transportation{

    @Override
    public void move(String dst) {
        // TODO Auto-generated method stub
        System.out.println("Take a plane to "+dst);
    }
}

然后创建 TransportationFactory

代码语言:javascript
复制
public class TransportationFactory  extends AbstractFactory {

    @Override
    public Transportation getTransportation(String type){
        if(type == null){
            return null;
        }        
        if(type.equalsIgnoreCase("TRAIN")){
            return new Train();
        } else if(type.equalsIgnoreCase("BUS")){
            return new Bus();
        } else if(type.equalsIgnoreCase("PLANE")){
            return new Plane();
        }
        return null;
    }

    @Override
    public Degree getDegree(int type) {
        // TODO Auto-generated method stub
        return null;
    }
    
}

交通工具类相关代码完成后,就创建消费档次借口及实现类

2. 消费档次接口及实现类

Degree.java

代码语言:javascript
复制
public interface Degree {
   void move(int type);
}

Economical.java

代码语言:javascript
复制
public class Economical  implements Degree {

    @Override
    public void move(int type) {
        // TODO Auto-generated method stub
        System.out.println("本次乘坐经济档次交通工具出行");
    }
}

Comfortable.java

代码语言:javascript
复制
public class Comfortable  implements Degree {

    @Override
    public void move(int type) {
        // TODO Auto-generated method stub
        System.out.println("本次乘坐舒适型交通工具出行");
    }
}

Luxuroius.java

代码语言:javascript
复制
public class Luxurious  implements Degree {

    @Override
    public void move(int type) {
        // TODO Auto-generated method stub
        System.out.println("本次乘坐豪华型交通工具出行");
    }
}

然后,创建相关的工厂 DegreeFactory

代码语言:javascript
复制
public class DegreeFactory extends   AbstractFactory {

   @Override
   public Transportation getTransportation(String type){return  null;}

   @Override
    public Degree getDegree(int  type){
        switch(type)
        {
            case 0:
                return new  Economical();
            
            case 1:
                return  new Comfortable();

            case 2:
                return new Luxurious();
         
            default:
                break;
        }
        return null;
    }
    
}

3. 工厂的工厂

AbstractFactory.java

代码语言:javascript
复制
public abstract class AbstractFactory {
    public abstract Transportation getTransportation(String type);
    public abstract Degree getDegree(int  type);
}

有了抽象类,还需要一个工厂创建器 FactoryCreator

代码语言:javascript
复制
public class FactoryCreator {

    public AbstractFactory  getFactory(String type) {
        if(type == null){
            return null;
        }        
        if(type.equalsIgnoreCase("Tranportation")){
            return new TransportationFactory();
        } 

        return new DegreeFactory();
    }


}

最后,编写测试 Demo AbstractFactoryDemo.java

代码语言:javascript
复制
public class AbstractFactoryDemo {

    public static void main(String[] args) {

        FactoryCreator creator = new FactoryCreator();

        TransportationFactory factory = (TransportationFactory)creator.getFactory("Tranportation");

  
         Transportation transportation = factory.getTransportation("train");
        transportation.move("深圳");

        DegreeFactory factory1 = (DegreeFactory)creator.getFactory("Degree");
         Degree degree = factory1.getDegree(2);
        degree.move(2);

    }

}

最终结果如下:

代码语言:javascript
复制
Take a train to 深圳
本次乘坐豪华型交通工具出行

可以看到,代码正常运行。

完整代码地址

更进一步

上面的例子很简单,其实实际开发中会稍微复杂。

比如,我们要出行,一般会通过旅行社,那么不同的旅行社给出的方案是不一样的。

如果把每一个旅行社当作是一个工厂的话,抽象工厂方法在这里也会大放异彩。

有些旅行社出方案时会考虑交通工具、目的地,有些旅行社则更多以时长、价格、舒适度为卖点。

把这些因素:

  1. 地点
  2. 时长
  3. 交通方式
  4. 价格
  5. 体验

分别建立一个接口,那么可以自由重组好多种方案。

不同的 Factory 其实是可以共享一些接口的。

放出一张 UML 示意图,代码大家自己完成。

下一篇
举报
领券