设计模式之抽象工厂模式(Java实现)

简介: 设计模式之抽象工厂模式(Java实现)

一、认识抽象工厂模式


抽象工厂模式也是工厂模式的一种,相对于简单工厂模式、工厂方法模式考虑的是一类产品的生产,而抽象工厂模式则是考虑多个产品族的创建。在抽象工厂模式中,有一个抽象工厂,该抽象工厂中提供了产生不同抽象产品的方法。其中抽象工厂是可以创建工厂的工厂!


定义:抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口无需指定它们具体的类。


应用场景:


提供一个产品类的工厂,所有的产品以同样的接口出现,使用者不依赖于具体的实现。

强调一些列相关的产品对象(如下面示例的产品族),一起使用创建对象需要大量重复的代码。

结构:抽象工厂、具体工厂;抽象产品、具体产品。


优缺点:


优点:获取具体系列产品只需要通过具体系列工厂获取,无序关心创建的细节;

缺点:规定了所有可能被创建的产品集合,若是出现某一个系列出现新的产品就会导致所有的系列都会创建指定的接口!扩展新产品困难,增加了系统的抽象性与复杂度。

引用 C语言中文网—抽象工厂模式图




二、实现抽象工厂模式


2.1、代码实现


在Abstract目录下的是抽象工厂模式代码:



抽象产品:Iphone、Router


//手机接口
public interface Iphone {
    void start();
    void music();
    void ring();
    void stop();
}
//路由器接口
public interface Router {
    void start();
    void stop();
    void work();
}


抽象工厂解决的是一个产品族的创建,品牌可以有多个,一个品牌也会生产不同的产品,其不同品牌的相同产品我们就可以将其进行抽象,由于我们注重的并不是一个产品的创建而是一个产品族,所以我们还需要抽象一个品牌接口即相当于是一个抽象工厂,该抽象工厂可以创建具体的工厂(实现其接口)。

抽象工厂:Brand


//品牌接口(可根据不同的品牌获取不同的产品)
public interface Brand {
    Iphone getPhone();
    Router getRouter();
}


具体产品:HuaWeiPhone、LianXiangPhone、HuaWeiRouter、LianXiangRouter


//手机的实现类
//华为牌手机
public class HuaWeiPhone implements Iphone {
    @Override
    public void start() {
        System.out.println("华为手机启动中...");
    }
    @Override
    public void music() {
        System.out.println("华为手机播放音乐中...");
    }
    @Override
    public void ring() {
        System.out.println("华为手机开启闹铃中...");
    }
    @Override
    public void stop() {
        System.out.println("华为手机关机中...");
    }
}
//联想牌手机
public class LianXiangPhone implements Iphone {
    @Override
    public void start() {
        System.out.println("联想手机正在启动...");
    }
    @Override
    public void music() {
        System.out.println("联想手机播放音乐中...");
    }
    @Override
    public void ring() {
        System.out.println("联想手机开启闹铃...");
    }
    @Override
    public void stop() {
        System.out.println("联想手机关机中...");
    }
}
//路由器的实现类
//华为路由器
public class HuaWeiRouter implements Router{
    @Override
    public void start() {
        System.out.println("华为路由器正在启动...");
    }
    @Override
    public void stop() {
        System.out.println("华为路由器正在关机...");
    }
    @Override
    public void work() {
        System.out.println("华为路由器开始工作...");
    }
}
//联想路由器
public class LianXiangRouter implements Router{
    @Override
    public void start() {
        System.out.println("联想路由器正在启动...");
    }
    @Override
    public void stop() {
        System.out.println("联想路由器正在关机...");
    }
    @Override
    public void work() {
        System.out.println("联想路由器开始工作...");
    }
}


具体工厂:既然产品有了,那我们一定是从指定工厂中来获取产品,接着我们通过抽象工厂来创建工厂类:


//华为工厂(提供华为手机、华为路由器)
public class HuaWeiFactory implements Brand{
    @Override
    public Iphone getPhone() {
        return new HuaWeiPhone();
    }
    @Override
    public Router getRouter() {
        return new HuaWeiRouter();
    }
}
//联想工厂(提供联想手机、联想路由器)
public class LianXiangFactory implements Brand{
    @Override
    public Iphone getPhone() {
        return new LianXiangPhone();
    }
    @Override
    public Router getRouter() {
        return new LianXiangRouter();
    }
}


最终我们来创建一个顾客类Customer,获取不同品牌的产品并且使用产品:


public class Customer {
    public static void main(String[] args) {
        //获取华为工厂
        Brand huawei = new HuaWeiFactory();
        Iphone phone = huawei.getPhone();//华为工厂获取华为手机
        phone.start();
        phone.music();
        phone.ring();
        phone.stop();
        Router router = huawei.getRouter();//华为工厂获取华为路由器
        router.start();
        router.work();
        router.stop();
        //----------------------
        System.out.println();
        Brand lianxiang = new LianXiangFactory();
        Iphone phone1 = lianxiang.getPhone();//华为工厂获取华为手机
        phone1.start();
        phone1.music();
        phone1.ring();
        phone1.stop();
        Router router1 = lianxiang.getRouter();//华为工厂获取华为路由器
        router1.start();
        router1.work();
        router1.stop();
    }
}





2.2、分析说明


在上面顾客类中的测试方法里,我们通过不同的工厂来获取到不同品牌的产品,具体的产品进行了代码的隔离,无需关心创建过程中的细节!


我们看下上面整体代码的依赖图:



将具体产品类型进行抽象,将具体生产商抽象成一个工厂并提供获取抽象产品的接口。

当我们需要具体的产品时只需要通过具体的工厂的方法即可获取,而不用再去管其中的细节。

若是我们要添加其他品牌如小米,我们只需要实现Brand接口创建一个工厂,分别实现其接口即可,符合开闭原则;若是新增一个产品A,那么就需要在Brand中添加获取A的接口,那么其所有实现该接口的工厂类都需要修改,这就不符合开闭原则。



总结


1、抽象工厂由四个部分组成:抽象工厂、具体工厂;抽象产品、具体产品。


2、添加新的产品族时只需要实现抽象工厂接口创建一个工厂并实现其中的方法即可,符合了开闭原则;而对于添加某个新产品则需要添加抽象工厂的接口,即造成所有抽象工厂的实现类都要进行修改,这就违反了开闭原则。


3、针对于抽象工厂模式不可以增加产品,可以增加产品族!(一旦增加产品就会造成大量修改)。


4、对于抽象工厂模式针对于的是产品族!

相关文章
|
20天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
1月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
36 4
|
2月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
52 0
[Java]23种设计模式
|
1月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 Java
Java设计模式
Java设计模式
33 0
|
6月前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
72 4
|
3月前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
45 11
|
4月前
|
设计模式 存储 负载均衡
【五】设计模式~~~创建型模式~~~单例模式(Java)
文章详细介绍了单例模式(Singleton Pattern),这是一种确保一个类只有一个实例,并提供全局访问点的设计模式。文中通过Windows任务管理器的例子阐述了单例模式的动机,解释了如何通过私有构造函数、静态私有成员变量和公有静态方法实现单例模式。接着,通过负载均衡器的案例展示了单例模式的应用,并讨论了单例模式的优点、缺点以及适用场景。最后,文章还探讨了饿汉式和懒汉式单例的实现方式及其比较。
【五】设计模式~~~创建型模式~~~单例模式(Java)
|
3月前
|
设计模式 Java 安全
Java设计模式-单例模式(2)
Java设计模式-单例模式(2)
|
7月前
|
设计模式 安全 Java
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
下一篇
DataWorks