package com.zqh.factory;
interface IMessage{
public void send();
}
class NetMessage implements IMessage{
@Override
public void send() {
System.out.println("net消息发送。");
}
}
class CloudMessage implements IMessage{
@Override
public void send() {
System.out.println("Cloud消息发送。");
}
}
interface IService{
public void service();
}
class HouseService implements IService{
@Override
public void service() {
System.out.println("住宿服务。");
}
}
public class FactoryImpl {
public static void main(String[] args) throws Exception {
/**
* 为什么要提供有一个反射的实例化?那么到底是使用关键字new还是使用反射呢?
* 如果直接实例化则一定会有耦合问题
* 在实际开发之中,接口的主要作用是为不同的层提供有一个操作的标准
* 所以使用工厂设计模式
*/
System.out.println("\t-----静态工厂-----");
IMessage message = Factory.getMessageInstance("com.zqh.factory.NetMessage");
message.send();
/**
* 以上属于静态工厂类的调用
* 而动态工厂类采用了泛型
*/
System.out.println("\t-----动态工厂-----");
IMessage message2 = Factory.getInstance("com.zqh.factory.NetMessage",IMessage.class);
message2.send();
IMessage message3 = Factory.getInstance("com.zqh.factory.CloudMessage",IMessage.class);
message3.send();
IService service = Factory.getInstance("com.zqh.factory.HouseService",IService.class);
service.service();
}
}
class Factory {
private Factory(){}//没有产生实例化对象的意义,所以构造方法私有化
public static IMessage getMessageInstance(String className){
/**
* 此种属于静态工厂设计模式
* 如果追加一个子类,则工厂类一定要做出修改
*/
// if("netmessage".equalsIgnoreCase(className)){
// return new NetMessage();
// }else if("cloudmessage".equalsIgnoreCase(className)){
// return new CloudMessage();
// }
/**
* 最好的解决方法就是不使用关键字new来完成
* 因为关键字new在使用时需要有一个明确的类存在
* 所以newInstance()方法只需要有一个明确表示类名称的字符串即可应用
*/
IMessage instance = null;
try {
instance = (IMessage) Class.forName(className).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return instance;
}
public static IService getServiceInstance(String className){
//...
return null;
}
/**
* 利用反射机制实现的工厂设计模式,最大的优势在于,对于接口子类的扩充将不再影响到工厂类的定义。
* 但进一步思考,实际的项目开发过程之中有可能会存在有大量的接口,并且这些接口都可能需要通过工厂类实例化,
* 所以此时的工厂设计模式不应该只为一个IMessage接口服务,而应该变为为所有接口服务
*/
/**
* 获取接口实例化对象
* @author zhaoqinghonh
* @param className 接口的子类
* @param clazz 描述的是一个接口的类型
* @return 如果子类存在则返回指定接口实例化对象
*/
@SuppressWarnings("unchecked")
public static <T> T getInstance(String className,Class<T> clazz){
T instance = null;
try {
instance = (T) Class.forName(className).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return instance;
}
//这样才是可以在开发中使用的基本工厂模式,达到了可重用性
}
设计模式-工厂的代码实现与详解
最新推荐文章于 2023-02-03 17:03:04 发布