工厂模式/抽象工厂模式的缺点及解决方法
通过 if...else 语句或switch...case 语句 判断选择不同的实现类; 且随着时间的推移,还要增加新的判断; 应该改为用什么设计模式,可以满足开闭原则
在这种情况下,可以考虑使用工厂模式来满足开闭原则。工厂模式可以根据特定的条件动态创建对象,从而将对象的创建过程与客户端代码分离,同时也能够轻松地扩展新的实现类而不需要修改现有的代码。
具体来说,可以使用工厂方法模式或抽象工厂模式来实现。工厂方法模式通过定义一个工厂接口和多个具体工厂类,每个具体工厂类负责创建特定的产品对象;抽象工厂模式则通过定义一个抽象工厂接口和多个具体工厂类,每个具体工厂类负责创建一组相关的产品对象。
下面是一个简单的示例,演示如何使用工厂方法模式来实现根据条件选择不同的实现类,并且能够轻松扩展新的实现类:
// 定义产品接口
interface Service {void performOperation();
}// 具体产品类1
class ServiceImpl1 implements Service {@Overridepublic void performOperation() {System.out.println("Using implementation 1");}
}// 具体产品类2
class ServiceImpl2 implements Service {@Overridepublic void performOperation() {System.out.println("Using implementation 2");}
}// 定义工厂接口
interface ServiceFactory {Service createService();
}// 具体工厂类1
class ServiceFactoryImpl1 implements ServiceFactory {@Overridepublic Service createService() {return new ServiceImpl1();}
}// 具体工厂类2
class ServiceFactoryImpl2 implements ServiceFactory {@Overridepublic Service createService() {return new ServiceImpl2();}
}// 客户端代码
public class Client {private ServiceFactory serviceFactory;public Client(ServiceFactory serviceFactory) {this.serviceFactory = serviceFactory;}public void performOperation() {Service service = serviceFactory.createService();service.performOperation();}public static void main(String[] args) {// 根据条件选择不同的工厂ServiceFactory serviceFactory;if (/* some condition */) {serviceFactory = new ServiceFactoryImpl1();} else {serviceFactory = new ServiceFactoryImpl2();}// 创建客户端并执行操作Client client = new Client(serviceFactory);client.performOperation();}
}
在这个示例中,通过使用工厂方法模式,可以根据条件选择不同的具体工厂类,从而创建不同的产品对象。如果需要增加新的实现类,只需要创建新的具体产品类和对应的具体工厂类,而不需要修改现有的客户端代码,符合开闭原则。
你的例子给了两种产品, 要是再多两种产品, 不是要改代码了,这样就违背开闭原则了
你说得对,如果产品的种类增加,那么工厂方法模式可能需要修改现有的代码来添加新的具体工厂类和产品类,这将违反开闭原则。为了解决这个问题,可以考虑使用抽象工厂模式。
抽象工厂模式可以创建一组相关或依赖的产品对象,而不需要指定它们的具体类。这样,当需要添加新的产品时,只需创建新的具体产品类和对应的具体工厂类,而不需要修改现有的代码。
下面是一个简单的示例,演示如何使用抽象工厂模式来创建多种产品对象,并且能够轻松扩展新的产品种类而不需要修改现有的代码:
// 定义产品接口
interface Service {void performOperation();
}// 具体产品类1
class ServiceImpl1 implements Service {@Overridepublic void performOperation() {System.out.println("Using implementation 1");}
}// 具体产品类2
class ServiceImpl2 implements Service {@Overridepublic void performOperation() {System.out.println("Using implementation 2");}
}// 具体产品类3
class ServiceImpl3 implements Service {@Overridepublic void performOperation() {System.out.println("Using implementation 3");}
}// 具体产品类4
class ServiceImpl4 implements Service {@Overridepublic void performOperation() {System.out.println("Using implementation 4");}
}// 定义抽象工厂接口
interface AbstractServiceFactory {Service createService();
}// 具体工厂类1
class ServiceFactoryImpl1 implements AbstractServiceFactory {@Overridepublic Service createService() {return new ServiceImpl1();}
}// 具体工厂类2
class ServiceFactoryImpl2 implements AbstractServiceFactory {@Overridepublic Service createService() {return new ServiceImpl2();}
}// 具体工厂类3
class ServiceFactoryImpl3 implements AbstractServiceFactory {@Overridepublic Service createService() {return new ServiceImpl3();}
}// 具体工厂类4
class ServiceFactoryImpl4 implements AbstractServiceFactory {@Overridepublic Service createService() {return new ServiceImpl4();}
}// 客户端代码
public class Client {private AbstractServiceFactory serviceFactory;public Client(AbstractServiceFactory serviceFactory) {this.serviceFactory = serviceFactory;}public void performOperation() {Service service = serviceFactory.createService();service.performOperation();}public static void main(String[] args) {// 根据条件选择不同的工厂AbstractServiceFactory serviceFactory;if (/* some condition */) {serviceFactory = new ServiceFactoryImpl1();} else if (/* some other condition */) {serviceFactory = new ServiceFactoryImpl2();} else if (/* another condition */) {serviceFactory = new ServiceFactoryImpl3();} else {serviceFactory = new ServiceFactoryImpl4();}// 创建客户端并执行操作Client client = new Client(serviceFactory);client.performOperation();}
}
在这个示例中,抽象工厂模式通过定义抽象工厂接口和多个具体工厂类,每个具体工厂类负责创建一组相关的产品对象。客户端根据条件选择不同的具体工厂类,从而创建不同的产品对象。如果需要增加新的产品,只需创建新的具体产品类和对应的具体工厂类,而不需要修改现有的客户端代码,符合开闭原则。
你这个产品类,要是再增加产品5,产品6,还符合开闭原则吗? 请重新考虑,给出完全符合的例子。 可以使用配置信息
如何化解此问题,请参考JAVA ORM Bee工具,关闭不同数据库方言SQL的实现:
DbFeatureRegistry