工厂模式 - 抽象工厂

1、抽象工厂模式

1.1、什么是抽象工厂模式

抽象工厂模式是对象的创建模式,是工厂模式的进一步推广。抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。“抽象工厂”就是抽象产品角色的工厂。抽象工厂模式面对的问题是多个产品等级结构的系统设计。这里的“多个产品等级结构”就是别人所说的产品族。

 

1.1.1、产品族

       产品族是指位于不同产品等级结构中,功能相关联的产品组成的家族。每个产品族中含有产品的数目与产品等级结构的数目是相等的。

 

1.2、抽象工厂模式的结构

       抽象工厂类(AbstractFactory)角色:担任这个角色的是工厂方法模式的核心。通常使用接口或者抽象类实现。所有的具体工厂需要实现这个接口或者继承抽象类。

       具体工厂类(Concrete Creator)角色:在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑。

       抽象产品(Product)角色:工厂方法模式所创建的对象的父类,或它们共同拥有的接口。

       具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西。

 

客户端:

/**
 * 客户端
 */
public class Client {

    public static void main(String[] args) {
        Creator creator1 = new ConcreteCreator1();
        ProductA productA1 = creator1.factoryA();
        ProductB productB1 = creator1.factoryB();
        productA1.print();
        productB1.print();

        Creator creator2 = new ConcreteCreator2();
        ProductA productA2 = creator2.factoryA();
        ProductB productB2 = creator2.factoryB();
        productA2.print();
        productB2.print();
    }
}

 

抽象产品,产品等级结构A:

/**
 * 抽象产品,产品等级结构A
 */
public interface ProductA {

    /**
     * 用于打印产品信息
     */
    void print();
}

 

抽象产品,产品等级结构B:

/**
 * 抽象产品,产品等级结构B
 */
public interface ProductB {

    /**
     * 用于打印产品信息
     */
    void print();
}

 

具体产品A1:

/**
 * 具体产品A1
 */
public class ConcreteProductA1 implements ProductA {
    @Override
    public void print() {
        System.out.println("this is ConcreteProductA1 ...");
    }
}

 

具体产品A2:

/**
 * 具体产品A2
 */
public class ConcreteProductA2 implements ProductA {
    @Override
    public void print() {
        System.out.println("this is ConcreteProductA2 ...");
    }
}

 

具体产品B1:

/**
 * 具体产品B1
 */
public class ConcreteProductB1 implements ProductB {
    @Override
    public void print() {
        System.out.println("this is ConcreteProductB1 ...");
    }
}

 

具体产品B2:

/**
 * 具体产品B2
 */
public class ConcreteProductB2 implements ProductB {
    @Override
    public void print() {
        System.out.println("this is ConcreteProductB2 ...");
    }
}

 

抽象工厂:

/**
 * 抽象工厂
 */
public interface Creator {

    /**
     * 产品等级结构A的工厂
     * @return
     */
    ProductA factoryA();

    /**
     * 产品等级结构B的工厂
     * @return
     */
    ProductB factoryB();
}

 

具体工厂1:

/**
 * 具体工厂1
 */
public class ConcreteCreator1 implements Creator {

    @Override
    public ProductA factoryA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB factoryB() {
        return new ConcreteProductB1();
    }
}

 

具体工厂2:

/**
 * 具体工厂2
 */
public class ConcreteCreator2 implements Creator {

    @Override
    public ProductA factoryA() {
        return new ConcreteProductA2();
    }

    @Override
    public ProductB factoryB() {
        return new ConcreteProductB2();
    }
}

 

类图:

 

1.3、优点

       当产品存在某种关联关系形成产品族,抽象工厂模式相比工厂方法模式减少了具体工厂类数量。在不添加新的抽象产品时,添加新的产品族只需要新增新的具体工厂即可,即通过不同产品的组合形成新的产品族,新的产品族对应新的抽象工厂和具体工厂。符合开闭原则。

 

1.4、缺点

       当需要在产品族中添加产品,意味着需要修改抽象工厂和具体工厂,违反了开闭原则。如果通过新增抽象工厂来添加产品族,那么原有的产品族就多余了。

 

1.5、实例

 

抽象工厂:园丁

/**
 * 抽象工厂
 * 园丁
 */
public interface Gardener {
    /**
     * 蔬菜工厂方法
     */
    Veggie createVeggie(String name);
    /**
     * 水果工厂方法
     */
    Fruit createFruit(String name);
}

 

具体工厂:北方园丁

/**
 * 具体工厂
 * 北方园丁
 */
public class NorthernGardener implements Gardener {

    /**
     * 蔬菜工厂方法
     */
    @Override
    public Veggie createVeggie(String name) {
        return new NortherVeggie(name);
    }
    /**
     * 水果工厂方法
     */
    @Override
    public Fruit createFruit(String name) {
        return new NortherFruit(name);
    }
}

 

具体工厂:热带园丁

/**
 * 具体工厂
 * 热带园丁
 */
public class TropicalGardener implements Gardener {

    /**
     * 蔬菜工厂方法
     */
    @Override
    public Veggie createVeggie(String name) {
        return new TropicalVeggie(name);
    }
    /**
     * 水果工厂方法
     */
    @Override
    public Fruit createFruit(String name) {
        return new TropicalFruit(name);
    }
}

 

抽象产品:水果

/**
 * 抽象产品角色
 * 水果
 */
public interface Fruit {
    /**
     * 收获
     */
    void harvest();
}

 

抽象产品:蔬菜

/**
 * 抽象产品角色
 * 蔬菜
 */

public interface Veggie {

    /**
     * 生长
     */
    void grow();
}

 

具体产品:北方水果

/**
 * 具体产品
 * 北方水果
 */
@Log
@Getter
@Setter
@AllArgsConstructor
public class NortherFruit implements Fruit {
    private String name;

    @Override
    public void harvest() {
        log.info(this.name +" is harvested ...");
    }
}

 

具体产品:北方蔬菜

/**
 * 具体产品
 * 北方蔬菜
 */
@Log
@Getter
@Setter
@AllArgsConstructor
public class NortherVeggie implements Veggie {
    private String name;

    @Override
    public void grow() {
        log.info(this.name +" is growing ...");
    }
}

 

具体产品:热带水果

/**
 * 具体产品
 * 热带水果
 */
@Log
@Getter
@Setter
@AllArgsConstructor
public class TropicalFruit implements Fruit {
    private String name;

    @Override
    public void harvest() {
        log.info(this.name +" is harvested ...");
    }
}

 

具体产品:热带蔬菜

/**
 * 具体产品
 * 热带蔬菜
 */
@Getter
@Setter
@AllArgsConstructor
@Log
public class TropicalVeggie implements Veggie {
    private String name;

    @Override
    public void grow() {
        log.info(this.name +" is growing ...");
    }
}

 

客户端:

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        Gardener northerGardener = new NorthernGardener();
        Fruit northerFruit1 = northerGardener.createFruit("northerFruit1");
        northerFruit1.harvest();
        Veggie northerVeggie1 = northerGardener.createVeggie("northerVeggie1");
        northerVeggie1.grow();

        Gardener tropicalGardener = new TropicalGardener();
        Fruit tropicalFruit2 = tropicalGardener.createFruit("tropicalFruit2");
        tropicalFruit2.harvest();
        Veggie tropicalVeggie2 = tropicalGardener.createVeggie("tropicalVeggie2");
        tropicalVeggie2.grow();
    }
}

 

输出:

 

 类图:

 

 

 

 

 

 

 

参考:

  《Java与模式》

posted @ 2018-10-15 00:35  Simple°  阅读(254)  评论(0编辑  收藏  举报