栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 - 抽象工厂模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 - 抽象工厂模式

目录

实例

手机软件初始化工厂方法模式解决方案 抽象工厂模式

概念抽象工厂模式解决方案方案的演进(配置文件) 总结源码

实例 手机软件初始化

假设一个手机软件初始化的应用场景,该软件支持IOS、Android、Windows等多个操作系统平台,针对不同的操作系统,该软件提供了不同的操作功能(Operation)类和操作界面(Surface)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台

软件结构示意图如下:


工厂方法模式解决方案

初始解决方案采用工厂方法模式,大致如下:Operation.java

public abstract class Operation {
    public abstract void init();
}

AndroidOperation.java

public class AndroidOperation extends Operation {
    @Override
    public void init() {
        System.out.println("初始化Android操作功能");
    }
}

IOSOperation.java

public class IOSOperation extends Operation {
    @Override
    public void init() {
        System.out.println("初始化IOS操作功能");
    }
}

OperationFactory.java

public interface OperationFactory {
    Operation getOperation();
}

AndroidOperationFactory.java

public class AndroidOperationFactory implements OperationFactory {
    @Override
    public Operation getOperation() {
        return new AndroidOperation();
    }
}

IOSOperationFactory.java

public class IOSOperationFactory implements OperationFactory {
    @Override
    public Operation getOperation() {
        return new IOSOperation();
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        OperationFactory operationFactory = new AndroidOperationFactory();
        Operation operation = operationFactory.getOperation();
        operation.init();

        operationFactory = new IOSOperationFactory();
        operation = operationFactory.getOperation();
        operation.init();
    }
}

输出如下:

初始化Android操作功能
初始化IOS操作功能

操作界面抽象代码类似,不一一粘贴,完整类图如下所示:

通过类图不难看出,此设计方案当需要支持新的操作系统平台时虽不需要修改现有代码,但类的增加是爆炸的,针对每一个新的操作系统的支持都需要增加新的抽象工厂和具体工程,类的个数成对增加,最后导致系统越来越庞大在工厂方法模式中,具体工厂负责生产具体的产品,每个具体工厂对应一种具体产品,工厂方法具有唯一性,显然,实例所处的业务场景是具有多个产品对象的,并不是单一的产品对象当系统所提供的工厂生产的具体产品并不是一个单一产品,而是多个位于不同产品等级结构、属于不同类型的具体产品时,就可以使用抽象工厂模式

抽象工厂模式示意图如下:
产品等级结构:产品的继承结构产品族:指同一个工厂生产的位于不同产品等级结构中的一组产品
抽象工厂模式 概念

抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类抽象工厂模式又称为Kit模式,它是一种对象创建型模式
抽象工厂模式解决方案

Operation.java

public abstract class Operation {
    public abstract void init();
}

AndroidOperation.java

public class AndroidOperation extends Operation {
    @Override
    public void init() {
        System.out.println("初始化Android操作功能");
    }
}

IOSOperation.java

public class IOSOperation extends Operation {
    @Override
    public void init() {
        System.out.println("初始化IOS操作功能");
    }
}

Surface.java

public abstract class Surface {
    public abstract void init();
}

AndroidSurface.java

public class AndroidSurface extends Surface {
    @Override
    public void init() {
        System.out.println("初始化Android操作界面");
    }
}

IOSSurface.java

public class IOSSurface extends Surface {
    @Override
    public void init() {
        System.out.println("初始化IOS操作界面");
    }
}

InitFactory.java

public interface InitFactory {
    Operation getOperation();
    Surface getSurface();
}

AndroidInitFactory.java

public class AndroidInitFactory implements InitFactory{
    @Override
    public Operation getOperation() {
        return new AndroidOperation();
    }

    @Override
    public Surface getSurface() {
        return new AndroidSurface();
    }
}

IOSInitFactory.java

public class IOSInitFactory implements InitFactory{
    @Override
    public Operation getOperation() {
        return new IOSOperation();
    }

    @Override
    public Surface getSurface() {
        return new IOSSurface();
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        InitFactory initFactory = new AndroidInitFactory();
        Operation operation = initFactory.getOperation();
        Surface surface = initFactory.getSurface();
        operation.init();
        surface.init();

        initFactory = new IOSInitFactory();
        operation = initFactory.getOperation();
        surface = initFactory.getSurface();
        operation.init();
        surface.init();
    }
}

输出如下:

初始化Android操作功能
初始化Android操作界面
初始化IOS操作功能
初始化IOS操作界面

类图如下:

抽象工厂可以将一组具有同一主题单独的工厂封装起来抽象工厂模式与工厂方法模式最大的区别在于:工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率
方案的演进(配置文件)

如上客户端Test.java调用代码还具有可改进的地方,可通过配置文件 + 反射实现在不修改客户端代码的基础上更换和扩展对操作系统的支持

config.properties

abstractFactory.className=AndroidInitFactory

PropertiesUtil.java

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;


public class PropertiesUtil {

    
     private static String getProperties(String filePath, String keyWord){
        Properties prop = new Properties();
        String value = null;
        try {
            InputStream inputStream = PropertiesUtil.class.getResourceAsStream(filePath);
            prop.load(inputStream);
            value = prop.getProperty(keyWord);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return value;
     }

    
     private static Object getBean(String filePath, String keyWord, String packagePath) {
         try {
             String className = getProperties(filePath, keyWord);
             Class c = Class.forName(packagePath + className);
             return c.newInstance();
         } catch (Exception e) {
             e.printStackTrace();
             return null;
         }

     }

    
    public static Object getAbstractFactoryBean() {
        return getBean("/com/coisini/design/util/config.properties",
                "abstractFactory.className",
                "com.coisini.design.pattern.creational.abstractfactory.v3.");
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        InitFactory initFactory = (InitFactory) PropertiesUtil.getAbstractFactoryBean();
        Operation operation = initFactory.getOperation();
        Surface surface = initFactory.getSurface();
        operation.init();
        surface.init();
    }
}

通过如上配置文件 + 反射实现方式,客户端代码无需使用new关键字来创建工厂对象,而是将具体工厂类的类名存在配置文件中,通过读取配置文件获取类名字符串,再使用反射机制根据类名字符串生成对象
总结

优点

1、具体产品在应用层代码隔离,无需关心创建细节
2、将一个系列的产品族统一到一起创建

缺点

1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
2、增加了系统的抽象性和理解难度

适用场景

1、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现

源码

GitHub:https://github.com/Maggieq8324/design_pattern.git

- End -
- 个人学习笔记 -
- 仅供参考 -

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/754584.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号