假设一个手机软件初始化的应用场景,该软件支持IOS
、Android
、Windows
等多个操作系统平台,针对不同的操作系统,该软件提供了不同的操作功能(Operation
)类和操作界面(Surface
)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台
Operation.java
/**
* @Description 操作功能抽象类
*/
public abstract class Operation {
public abstract void init();
}
AndroidOperation.java
/**
* @Description Android操作功能产品类
*/
public class AndroidOperation extends Operation {
@Override
public void init() {
System.out.println("初始化Android操作功能");
}
}
IOSOperation.java
/**
* @Description IOS操作功能产品类
*/
public class IOSOperation extends Operation {
@Override
public void init() {
System.out.println("初始化IOS操作功能");
}
}
OperationFactory.java
/**
* @Description 操作功能工厂类(工厂方法模式)
*/
public interface OperationFactory {
Operation getOperation();
}
AndroidOperationFactory.java
/**
* @Description Android操作功能工厂类
*/
public class AndroidOperationFactory implements OperationFactory {
@Override
public Operation getOperation() {
return new AndroidOperation();
}
}
IOSOperationFactory.java
/**
* @Description IOS操作功能工厂类
*/
public class IOSOperationFactory implements OperationFactory {
@Override
public Operation getOperation() {
return new IOSOperation();
}
}
Test.java
/**
* @Description 工厂方法模式测试类
*/
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
/**
* @Description 操作功能抽象类
*/
public abstract class Operation {
public abstract void init();
}
AndroidOperation.java
/**
* @Description Android操作功能产品类
*/
public class AndroidOperation extends Operation {
@Override
public void init() {
System.out.println("初始化Android操作功能");
}
}
IOSOperation.java
/**
* @Description IOS操作功能产品类
*/
public class IOSOperation extends Operation {
@Override
public void init() {
System.out.println("初始化IOS操作功能");
}
}
Surface.java
/**
* @Description 操作界面抽象类
*/
public abstract class Surface {
public abstract void init();
}
AndroidSurface.java
/**
* @Description Android操作界面产品类
*/
public class AndroidSurface extends Surface {
@Override
public void init() {
System.out.println("初始化Android操作界面");
}
}
IOSSurface.java
/**
* @Description IOS操作界面产品类
*/
public class IOSSurface extends Surface {
@Override
public void init() {
System.out.println("初始化IOS操作界面");
}
}
InitFactory.java
/**
* @Description 初始化工厂接口:抽象工厂
*/
public interface InitFactory {
Operation getOperation();
Surface getSurface();
}
AndroidInitFactory.java
/**
* @Description Android初始化工厂:具体工厂类
*/
public class AndroidInitFactory implements InitFactory{
@Override
public Operation getOperation() {
return new AndroidOperation();
}
@Override
public Surface getSurface() {
return new AndroidSurface();
}
}
IOSInitFactory.java
/**
* @Description IOS初始化工厂:具体工厂类
*/
public class IOSInitFactory implements InitFactory{
@Override
public Operation getOperation() {
return new IOSOperation();
}
@Override
public Surface getSurface() {
return new IOSSurface();
}
}
Test.java
/**
* @Description 抽象工厂测试类
* @author coisini
* @date Mar 4, 2022
* @version 1.0
*/
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;
/**
* @Description Properties工具类
* @author coisini
* @date Feb 28, 2022
* @version 1.0
*/
public class PropertiesUtil {
/**
* 根据key读取value
* @Description: 相对路径, properties文件需在classpath目录下,
* 比如:config.properties在包com.coisini.util,
* 路径就是/com/coisini/util/config.properties
* @param filePath
* @param keyWord
* @return String
* @throws
*/
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;
}
/**
* 根据配置文件提取类名返回实例对象
* @param filePath
* @param keyWord
* @param packagePath
* @return
*/
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;
}
}
/**
* 获取抽象工厂实例对象
* @return
*/
public static Object getAbstractFactoryBean() {
return getBean("/com/coisini/design/util/config.properties",
"abstractFactory.className",
"com.coisini.design.pattern.creational.abstractfactory.v3.");
}
}
Test.java
/**
* @Description 抽象工厂测试类
*/
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