设计模式-简单工厂模式、工厂模式、抽象工厂模式在Java中的使用示例

场景

软件架构设计原则-开闭、依赖倒置、单一职责、接口隔离、迪米特、里氏替换、合成复用,附Java语言示例讲解:

软件架构设计原则-开闭、依赖倒置、单一职责、接口隔离、迪米特、里氏替换、合成复用,附Java语言示例讲解_霸道流氓气质的博客-CSDN博客

在上面讲了软件架构设计原则后,还有常用的设计模式-简单工厂模式、工厂模式、抽象工厂模式的使用示例。

简单工厂模式(Simple Factory Pattern)

是指由一个工厂对象决定创建哪一种产品类的实例,其不属于Gof的23种设计模式。简单工厂适用于工厂类负责创建

的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象不需要关心。

工厂方法模式(Factory Method Pattern)

是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到

子类中进行。在工厂方法模式中用户只关心所需产品对应的工厂,无需关心创建细节,而且加入新的产品时符合开闭原则。

工厂方法模式主要解决产品扩展的问题。

在简单工厂模式中,随着商品的增多,如果每个商品的购买逻辑有区别,则工厂的职责就会变得越来越多,就比如万能工厂。

根据单一职责原则将职能拆分,专厂干专事。比如电脑由电脑工厂创建,书籍由书籍工厂创建,对工厂本身也做一个抽象。

抽象工厂模式(Abstract Factory Pattern)

是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们的具体类。客户端(应用层)不依赖于产品类实例如何被创建、如何

被实现等细节,强调的是一系列相关的产品对象(属于同一个产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类

的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

产品等级结构与产品族

 

上图中有正方形、圆形和菱形三种图形,相同颜色深浅的代表同一个产品族,相同形状的代表同一个产品等级结构。

类比:

A厂家的多个电器,颜色最深的正方形代表A厂家的洗衣机,颜色最深的圆形代表A厂家的空调,颜色最深的菱形

代表A厂家的热水器,颜色最深的一排都属于A的电器这个产品族。

再看最右侧的菱形,颜色最深的是A厂家,第二排颜色浅点的代表B厂家,同理下面还有C厂家、D厂家、E厂家。

所以同一个厂家的就认为是具体的工厂,每个厂家都生产洗衣机、热水器和空调。

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

简单工厂模式示例

以商品为例,定义一个商品的标准接口

package com.ruoyi.demo.designPattern.simpleFactory;

public interface IGoods {
    /**
     * 购买商品
     */
    public void buy();
}

创建一个电脑商品的实现类

package com.ruoyi.demo.designPattern.simpleFactory;

public class ComputerGoods implements IGoods{
    @Override
    public void buy() {
        System.out.println("购买了电脑商品");
    }
}

客户端调用时会这样写

package com.ruoyi.demo.designPattern.simpleFactory;

public class factoryTest {
    public static void main(String[] args) {
        IGoods goods = new ComputerGoods();
        goods.buy();
    }
}

上述代码中,父类IGoods指向子类ComputerGoods的引用,应用层代码需要依赖ComputerGoods,

如果业务扩展,那么客户端依赖会越来越臃肿。

所以用简单工厂模式对代码进行优化

创建工厂GoodsFactory

package com.ruoyi.demo.designPattern.simpleFactory;

public class GoodsFactory {
    public IGoods buy(Class<? extends IGoods> clazz){
        try {
            if(null != clazz){
                return clazz.newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}

这里采用反射技术,当商品不断增多时,不需要修改工厂中的代码。

此时优化客户端代码

package com.ruoyi.demo.designPattern.simpleFactory;

public class factoryTest {
    public static void main(String[] args) {
        GoodsFactory factory = new GoodsFactory();
        IGoods goods = factory.buy(ComputerGoods.class);
        goods.buy();
    }
}

简单工厂模式也有它的缺点:

工厂类的职责相对过重,不易于扩展过于复杂的产品结构。

工厂方法模式示例

为了实现专厂干专事,电脑商品由电脑工厂创建,书籍商品由书籍工厂创建,对工厂本身做一个抽象。

创建IGoodsFactory

package com.ruoyi.demo.designPattern.factoryMethod;

public interface IGoodsFactory {
    IGoods create();
}

再分别创建子工厂,电脑工厂代码如下

package com.ruoyi.demo.designPattern.factoryMethod;

public class ComputerGoodsFactory implements IGoodsFactory {
    @Override
    public IGoods create() {
        return new ComputerGoods();
    }
}

书籍工厂代码如下

package com.ruoyi.demo.designPattern.factoryMethod;

public class BookGoodsFactory implements IGoodsFactory {
    @Override
    public IGoods create() {
        return new BookGoods();
    }
}

其它的如上面一样,分别是

IGoods:

package com.ruoyi.demo.designPattern.factoryMethod;

public interface IGoods {
    /**
     * 购买商品
     */
    public void buy();
}

ComputerGoods:

package com.ruoyi.demo.designPattern.factoryMethod;


public class ComputerGoods implements IGoods {
    @Override
    public void buy() {
        System.out.println("购买了电脑商品");
    }
}

BoolGoods:

package com.ruoyi.demo.designPattern.factoryMethod;


public class BookGoods implements IGoods {
    @Override
    public void buy() {
        System.out.println("购买了书籍商品");
    }
}

测试代码如下:

package com.ruoyi.demo.designPattern.factoryMethod;

public class factoryMethodTest {
    public static void main(String[] args) {
        IGoodsFactory factory = new ComputerGoodsFactory();
        IGoods goods = factory.create();
        goods.buy();

        factory = new BookGoodsFactory();
        goods = factory.create();
        goods.buy();
    }
}

工厂方法模式适用于以下场景:

1、创建对象需要大量重复的代码。

2、客户端(应用层)不依赖于产品类实例如何被创建、如何被实现等细节。

3、一个类通过其子类来指定创建哪个对象。

工厂方法模式也有缺点:

1、类的个数容易增多,增加复杂度。

2、增加了系统的抽象性和理解难度。

抽象工厂模式示例

通过上面同一个厂家的就认为是具体的工厂,每个厂家都生产洗衣机、热水器和空调。

假如商品要扩展经营模式,除了提供实体商品,还要提供售后服务。

在产品等级中增加两个产品:

IEntityGoods实物商品和IServiceAfterSale售后服务。

IEntityGoods:

package com.ruoyi.demo.designPattern.abstractFactory;

public interface IEntityGoods {
    /**
     * 购买实体商品
     */
    public void buy();
}

IServiceAfterSale:

package com.ruoyi.demo.designPattern.abstractFactory;

/**
 * 售后服务
 */
public interface IServiceAfterSale {
    //享受售后服务
    void enjoy();
}

然后创建一个抽象工厂类GoodsFactory:

package com.ruoyi.demo.designPattern.abstractFactory;

/**
 * 抽象工厂是用户的主入口
 * 是Spring中应用得最广泛的一种设计模式
 * 易于扩展
 */
public interface GoodsFactory {
    IEntityGoods createEntityGoods();
    IServiceAfterSale createServiceAfterSale();
}

然后创建电脑产品组的实体电脑类

package com.ruoyi.demo.designPattern.abstractFactory;

public class ComputerEntityGoods implements IEntityGoods {
    @Override
    public void buy() {
        System.out.println("购买了实体电脑商品");
    }
}

扩展产品等级电脑的售后服务类

package com.ruoyi.demo.designPattern.abstractFactory;

public class ComputerServiceAfterSale implements IServiceAfterSale{
    @Override
    public void enjoy() {
        System.out.println("享受了电脑的售后服务");
    }
}

创建电脑产品族的具体工厂ComputerGoodsFactory

package com.ruoyi.demo.designPattern.abstractFactory;

public class ComputerGoodsFactory  implements GoodsFactory{

    @Override
    public IEntityGoods createEntityGoods() {
        return new ComputerEntityGoods();
    }

    @Override
    public IServiceAfterSale createServiceAfterSale() {
        return new ComputerServiceAfterSale();
    }
}

然后再创建书籍产品的实体书籍类

package com.ruoyi.demo.designPattern.abstractFactory;

public class BookEntityGoods implements IEntityGoods {
    @Override
    public void buy() {
        System.out.println("购买了实体书籍商品");
    }
}

扩展产品等级书籍售后服务类

package com.ruoyi.demo.designPattern.abstractFactory;

public class BookServiceAfterSale implements IServiceAfterSale{
    @Override
    public void enjoy() {
        System.out.println("享受了书籍的售后服务");
    }
}

创建书籍产品族的具体工厂

package com.ruoyi.demo.designPattern.abstractFactory;

public class BookGoodsFactory implements GoodsFactory{
    @Override
    public IEntityGoods createEntityGoods() {
        return new BookEntityGoods();
    }

    @Override
    public IServiceAfterSale createServiceAfterSale() {
        return new BookServiceAfterSale();
    }
}

客户端调用代码

package com.ruoyi.demo.designPattern.abstractFactory;

public class absFacTest {
    public static void main(String[] args) {
        ComputerGoodsFactory computerGoodsFactory = new ComputerGoodsFactory();
        computerGoodsFactory.createEntityGoods().buy();
        computerGoodsFactory.createServiceAfterSale().enjoy();

        BookGoodsFactory bookGoodsFactory = new BookGoodsFactory();
        bookGoodsFactory.createEntityGoods().buy();
        bookGoodsFactory.createServiceAfterSale().enjoy();
    }
}

上面的代码完整地描述了两个产品族:电脑产品族和书籍产品族,也描述了两个产品族等级实体商品

和售后服务。抽象工厂模式完美描述了这样一层复杂的关系。但是,如果我们再扩展产品等级,

比如将运费也加入到商品,那么代码从抽象工厂到具体工厂要全部调整,不符合开闭原则。

所以抽象工厂模式是有缺点的:

1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

2、增加了系统的抽象性和理解难度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。在Java,我们可以通过定义一个抽象工厂接口和多个具体工厂类来实现抽象工厂模式。例如,我们可以定义一个抽象工厂接口来创建不同类型的汽车,然后实现多个具体工厂类来创建不同品牌的汽车,如奔驰、宝马等。这样,我们就可以通过调用具体工厂类来创建不同品牌的汽车对象,而无需知道它们的具体类名。 ### 回答2: 抽象工厂模式是一种创建对象的设计模式,在Java广泛应用于软件开发。该模式提供了一种方式,可以通过定义一个接口或者抽象类来创建一组相关或者互相依赖的对象,而无需指定具体的类。 在Java的实例,我们以一个汽车制造工厂为例来说明抽象工厂模式使用。假设我们有两种类型的汽车:轿车和SUV,并且每种类型的汽车又有两种具体的品牌:宝马和奔驰。我们可以使用抽象工厂模式来创建这些具体的汽车对象。 首先,我们定义一个抽象的汽车工厂接口,包含创建轿车和SUV的方法。然后,我们创建两个具体的工厂类:宝马工厂和奔驰工厂,实现这个抽象的接口。每个具体工厂类分别负责创建对应品牌的汽车对象。 接下来,我们定义一个抽象的汽车接口,包含一些汽车的公共方法,比如启动、停止和加速等。然后,我们创建轿车和SUV的具体类,分别实现这个抽象的汽车接口。 最后,我们在客户端使用抽象工厂模式来创建具体的汽车对象。客户端可以通过调用宝马工厂的方法来创建宝马品牌的汽车,也可以通过调用奔驰工厂的方法来创建奔驰品牌的汽车。这样,客户端可以在不同的情境下通过切换不同的工厂类来创建不同品牌的汽车对象,而无需直接实例化具体的类,从而提供了更大的灵活性和扩展性。 总结来说,抽象工厂模式Java的实例可以帮助我们创建一组相关或者互相依赖的对象,将对象的创建与具体的类解耦,提供了更好的灵活性和可扩展性。 ### 回答3: 抽象工厂模式设计模式的一种,其主要目的是提供一个接口来创建一系列相关或相互依赖的对象,而无需指定具体的类。 在Java,我们可以通过一个示例来说明抽象工厂模式的用法。 假设我们要创建一个汽车制造工厂,该工厂可以生产多种品牌的汽车,如奥迪、宝马和奔驰。为了实现抽象工厂模式,我们首先需要定义一个抽象工厂接口,该接口声明了几种不同品牌汽车的生产方法,如createAudi、createBMW和createBenz。 然后,我们创建了三个具体工厂类,分别实现了抽象工厂接口。每个具体工厂类负责创建对应品牌的汽车对象。例如,AudiFactory实现了createAudi方法,用于创建奥迪汽车对象;BMWFactory实现了createBMW方法,用于创建宝马汽车对象;BenzFactory实现了createBenz方法,用于创建奔驰汽车对象。 接下来,我们需要创建一个客户端类,它将使用这些工厂类来创建汽车对象。客户端只需要与抽象工厂接口进行交互,而无需直接与具体工厂类打交道。假设我们要生产一辆奥迪汽车,那么我们可以使用AudiFactory创建一个奥迪汽车对象。 通过使用抽象工厂模式,我们可以轻松地扩展工厂类,以生产更多品牌的汽车,而无需对客户端代码进行修改。例如,如果我们要添加一种新的汽车品牌,如丰田,我们只需创建一个新的具体工厂类ToyotaFactory,并实现createToyota方法来创建丰田汽车对象即可。 总结而言,抽象工厂模式Java的实例可以用于创建一系列相关的对象,通过定义抽象工厂接口和具体工厂类,使得客户端可以通过接口调用来创建对象,提高了代码的可扩展性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霸道流氓气质

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值