抽象工厂模式(Java)

工厂模式可以分为:简单工厂模式,工厂方法模式,抽象工厂模式。

简单工厂模式就没什么好说的了,无非是所有的东西都写在一个类里面,要什么就调用什么,如果要添加新的方法也是到这类里面添加,代码很多,看起来也是很乱,就像一个大工厂,什么都在里面。扩展性很低。

而工厂方法模式,把说明的理论和生产的东西就分开一点。抽象工厂模式是工厂方法模式的升级。
说简单点,后面两种工厂模式都是java三大特征的继承和多态的具体表现,你从后面的类图中就可以很简单看到继承(接口为实现)的关系,而你在代码中就很容易看到多态的使用。
关于工厂方法模式,上次已经有详细的介绍了,本文主要是介绍抽象工厂模式。

抽象工厂模式的概念

抽象工厂模式的定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。
同时你也可以对比一下工厂方法模式的定义:为某个对象提供一个接口,而且无需指定它们的具体类。
都是子类实现接口的方法,并在子类写具体的代码。这里抽象工厂的接口类是能创建多个相关的对象,而工厂方法的接口类是只创建一个对象。

抽象工厂模式的类图:

1
对比工厂方法模式,你要知道它们之间的类图区别,就能理解这两种模式的区别。
工厂方法模式中也是可以有多个具体工厂,也是可以有多个抽象产品,和多个具体工厂、具体产品类。区别是在抽象工厂接口类中,能创建几个产品对象。
抽象工厂模式的工厂能创建多个相关的产品对象,而工厂方法模式的工厂只创建一个产品对象。

抽象工厂模式的优点/缺点:

1.优点

针对同一组产品创建新的生产线,只需实现那组产品的抽象工厂接口即可创建新的工厂类。

2.缺点

抽象方法模式的最大缺点就是产品族本身的扩展非常困难。如果在产品族中增加一个新的产品类型,则需要修改多个接口,并影响现已有的工厂类。
上面这句话,有些人不怎么理解,我給大家解释一下,打个比方说,你要在这个工厂创建三个对象,原本只是创建两个对象的,那么你就要在抽象方法中添加一个创建对象的方法,那么所有实现了这个接口的类都是要重新添加这个创建对象的方法,这就是对之前的工厂有影响的原因。

抽象工厂模式的应用场景

当一个对象都有相同的约束时,可以使用抽象工厂模式。
打个比方说,这个工厂的几个产品都需要经过某些共同的步骤和打上相同的商标,这一组产品可以在一个工厂里面生产,减少很多重复的代码在不同的地方都出现多次。

抽象工厂模式的实例

这里设计一个工厂生产奔驰汽车和它对应的导航仪两种产品。

实例类图

2
这个类图和上面的抽象工厂的类图是一样的,只是把东西具体化,代码化。

各个接口/类的代码

(1)生产奔驰的接口Benz

package P3_abstractFactory;

/**
 * 奔驰产品的抽象接口
 */
public interface Benz {
    void carColor();//设置颜色
    void carSpeed();//设置速度
    void carPrice();//设置价格

}


(2)生产车辆导航仪的接口类

package P3_abstractFactory;

/**
 * 车辆导航仪的抽象产品接口类
 */
public interface CarNavigator {

    void navigatorColor();//导航仪的颜色

    void navigatorPrice();//导航仪的价格


}

(3)奔驰工厂的抽象接口类BanzFactory

package P3_abstractFactory;

/**
 * 奔驰工厂的抽象接口
 */
public interface BanzFactory {
    /**
     * 创建奔驰的方法
     */
      Benz createCar();

    /**
     * 创建导航仪的方法
     */
    CarNavigator createNacigator();

}

(4)生产奔驰车辆C180和相关导航仪的具体工厂类

package P3_abstractFactory;

/**
 * 生产某一个型号奔驰车辆的实际工厂
 */
public class C180Factory implements BanzFactory {
    @Override
    public Benz createCar() {
        return new BenzC180();
    }

    @Override
    public CarNavigator createNacigator() {
        return new C180Navigator();
    }
}

(5)生产奔驰车辆Z260和相关导航仪的具体工厂类

package P3_abstractFactory;

/**
 * 生产某一个型号奔驰车E260辆的实际工厂
 */
public class E260Factory implements BanzFactory {
    @Override
    public Benz createCar() {
        return new BenzE260();
    }

    @Override
    public CarNavigator createNacigator() {
        return new E260Navigator();
    }
}

(6)生产奔驰车辆C180的具体产品类

package P3_abstractFactory;

/**
 * 奔驰C180的生产的具体类
 */
public class BenzC180 implements Benz {
    /**
     * 构造方法,创建的时候就设置基本属性
     */
    public BenzC180() {
        carColor();
        carPrice();
        carSpeed();
    }

    @Override
    public void carColor() {
        System.out.println("奔驰C180的颜色是银白色");

    }

    @Override
    public void carSpeed() {
        System.out.println("奔驰C180的速度是200公里每小时");
    }

    @Override
    public void carPrice() {
        System.out.println("奔驰C180的价格是100万");
    }
}

(7)生产奔驰车辆C180对应导航仪的具体产品类

package P3_abstractFactory;

/**
 * 车型C180的导航仪
 */
public class C180Navigator implements CarNavigator {

    C180Navigator(){
        navigatorColor();
        navigatorPrice();
    }

    @Override
    public void navigatorColor() {
        System.out.println("汽车C180的导航仪颜色:黑色");
    }

    @Override
    public void navigatorPrice() {
        System.out.println("汽车C180的导航仪价格:480元");
    }
}

奔驰车辆E260的具体产品类

package P3_abstractFactory;

/**
 * 奔驰E260的生产的具体类
 */
public class BenzE260 implements Benz {
    /**
     * 构造方法,创建的时候就设置基本属性
     */
    public BenzE260() {
        carColor();
        carPrice();
        carSpeed();
    }

    @Override
    public void carColor() {
        System.out.println("奔驰E260的颜色是银白色");

    }

    @Override
    public void carSpeed() {
        System.out.println("奔驰E260的速度是200公里每小时");
    }

    @Override
    public void carPrice() {
        System.out.println("奔驰E260的价格是100万");
    }
}

(7)生产奔驰车辆E260对应导航仪的具体产品类

package P3_abstractFactory;

/**
 * 车型E260的导航仪
 */
public class E260Navigator implements CarNavigator {

    E260Navigator(){
        navigatorColor();
        navigatorPrice();
    }

    @Override
    public void navigatorColor() {
        System.out.println("汽车E260的导航仪颜色:白色");
    }

    @Override
    public void navigatorPrice() {
        System.out.println("汽车E260的导航仪价格:880元");
    }
}

生产奔驰车辆和相关产品的调用者类AbstractFactoryDemo

package P3_abstractFactory;

/**
 * 抽象工厂模式调用
 * 生产两个奔驰车C180、E260和它们对应的导航仪的演示
 * 这里使用多态的方法类创建各个类别的车型产品
 */
public class AbstractFactoryDemo {
    public static void main(String[] a) {
        System.out.println("生产奔驰车C180");
        //父类但对象子类的实例
        BanzFactory banzFactory = new C180Factory();//创建一个C180工厂
        //调用父类的方法,这就是java多态的一种体现
        banzFactory.createCar();//C180工厂生产车辆C180
        banzFactory.createNacigator();//生产车辆C180对应的导航仪

        System.out.println("=========================================");
        System.out.println("生产奔驰车Z260");
        BanzFactory banzFactory2 = new E260Factory();
        banzFactory2.createCar();//E260工厂生产车辆E260
        banzFactory2.createNacigator();//生产车辆E260对应的导航仪

    }

}

程序运行的结果:

3

从实例中分析,工厂方法模式的优点/缺点

1.优点

如果需要生产新的汽车产品和对应的导航仪设备,你只需要创建一个该产品对应的具体工厂和该产品的具体实现类,不需要改变抽象的工厂类和抽象的产品类,具体工厂类和具体产品类需要什么操作已经在抽象接口类定义好了。

2.缺点

之前有说工厂方法的扩展性算是比较好的,而抽象工厂模式的扩展性就没那么好了。
比如说某个工厂需要多创建几个产品对象,那么就需要增加抽象工厂的方法,增加抽象接口的方法后,其他实现了抽象工厂接口方法的所有类都需要改变,才能正常编译。

比如:我们在代码中有定义生产导航仪的接口方法和具体实现,那如果我们添加一个新的产品,比如内置空调,这时候要在抽象接口中添加定义生产空调的接口,并且之前所有的产品类都实现的这个接口,所以之前型号的汽车也要实现内置空调的方法,这里方法可以是没有具体操作的,但是方法肯定是要实现的。

 

博文参考:https://blog.csdn.net/wenzhi20102321/article/category/6686813/2

https://blog.csdn.net/wenzhi20102321/article/details/78153437?utm_source=copy

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。该模式通过定义一个抽象工厂接口,然后在具体的工厂类中实现该接口,从而创建不同类型的对象。 在Java中,抽象工厂模式通常由以下几个角色组成: 1. 抽象工厂(Abstract Factory):定义了创建一系列产品对象的接口,它包含多个创建产品的抽象方法。 2. 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体的产品对象。 3. 抽象产品(Abstract Product):定义了产品对象的接口,可以是一个抽象类或接口。 4. 具体产品(Concrete Product):实现了抽象产品接口,是具体工厂创建的对象。 下面是一个简单的抽象工厂模式的示例代码: ```java // 抽象产品A interface ProductA { void operationA(); } // 具体产品A1 class ConcreteProductA1 implements ProductA { @Override public void operationA() { System.out.println("具体产品A1的操作"); } } // 具体产品A2 class ConcreteProductA2 implements ProductA { @Override public void operationA() { System.out.println("具体产品A2的操作"); } } // 抽象产品B interface ProductB { void operationB(); } // 具体产品B1 class ConcreteProductB1 implements ProductB { @Override public void operationB() { System.out.println("具体产品B1的操作"); } } // 具体产品B2 class ConcreteProductB2 implements ProductB { @Override public void operationB() { System.out.println("具体产品B2的操作"); } } // 抽象工厂 interface AbstractFactory { ProductA createProductA(); ProductB createProductB(); } // 具体工厂1 class ConcreteFactory1 implements AbstractFactory { @Override public ProductA createProductA() { return new ConcreteProductA1(); } @Override public ProductB createProductB() { return new ConcreteProductB1(); } } // 具体工厂2 class ConcreteFactory2 implements AbstractFactory { @Override public ProductA createProductA() { return new ConcreteProductA2(); } @Override public ProductB createProductB() { return new ConcreteProductB2(); } } // 客户端代码 public class Client { public static void main(String[] args) { AbstractFactory factory1 = new ConcreteFactory1(); ProductA productA1 = factory1.createProductA(); ProductB productB1 = factory1.createProductB(); productA1.operationA(); productB1.operationB(); AbstractFactory factory2 = new ConcreteFactory2(); ProductA productA2 = factory2.createProductA(); ProductB productB2 = factory2.createProductB(); productA2.operationA(); productB2.operationB(); } } ``` 在上述示例中,抽象工厂接口`AbstractFactory`定义了创建产品A和产品B的方法。具体工厂`ConcreteFactory1`和`ConcreteFactory2`分别实现了抽象工厂接口,负责创建具体的产品对象。抽象产品接口`ProductA`和`ProductB`定义了产品对象的操作方法,具体产品类`ConcreteProductA1`、`ConcreteProductA2`、`ConcreteProductB1`和`ConcreteProductB2`实现了抽象产品接口。 通过使用抽象工厂模式,客户端可以通过抽象工厂接口来创建一系列相关的产品对象,而无需关心具体的产品实现类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值