实际应用-简单工厂到工厂方法到Annotation

版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/guo_xl/article/details/84111835
1.刚开始的版本

需求是监听user.queue,获取到用户的消息,消息里有用户的增删改操作

做法比较简单使用简单工厂,代码如下

@JmsListener(destination="USER.QUEUE")
public void onMessage(Object message){
    if(message instanceof JMSObjectMessage){
			JMSObjectMessage msgObj = (JMSObjectMessage)message;
	    Object payload = msgObj.getObject();
        UserMessageHandlerFactory.getHandler(payload).process((PendingUserValue)payload);
    }
}
public class UserMessageHandlerFactory{
    public static MessageHandler getHandler(PendingUserValue payload){
        ...
        if(payload.getAction()==RequestType.CREATE_USER.getStatusCode()){
            return new UserCreateHandler();
        }else if(payload.getAction()==RequestType.CREATE_USER.getStatusCode()){
            return new UserEditHandler();
        }
        ...
    }
}
public static  enum RequestType {
		CREATE_USER("create_user", 0),
		EDIT_USER("edit_user", 1),
		DELETE_USER("delete_user", 2);
	
		String statusName;
		int statusCode;
		RequestType(String statusName, int statusCode) {
			this.statusName=statusName;
			this.statusCode = statusCode;
		}
		public String getStatusName() {
			return statusName;
		}
		public int getStatusCode() {
			return statusCode;
		}

		public static RequestType valueOf(int code){
			EnumSet<RequestType> set =EnumSet.allOf(RequestType.class);
			return  set.stream().filter(requestType->{
				return requestType.getStatusCode()==code;
			}).findFirst().get();
		}
	}
interface MessageHandler<T>{
	public void process(T t) throws Exception;
}
public class UserCreateHandler implements MessageHandler<PendingUserValue>{
    	public void process(PendingUserValue p){
    	    ...
    	}
}
public class UserEditHandler implements MessageHandler<PendingUserValue>{
    	public void process(PendingUserValue p){
    	    ...
    	}
}

UML图如下
在这里插入图片描述

2. 二期版本

1期开发完毕后,加入了更多的需求,例如account的增删改 ,都是走同样的模式。在1期开发完毕的基础上变成如下模式。由简单工厂变成了工厂方法

public MessageHandlerFactory{
    public static MessageHandler getHandler(Object payload){
        if(payload instanceOf PendingUserValue){
           return  UserMessageHandlerFactory.getHandler(PendingUserValue(payload));
        }else if(payload instanceOf PendingAccountValue){
             return  AccountMessageHandlerFactory.getHandler(PendingAccountValue(payload));
        }
        ....
    }
}
public class AccountMessageHandlerFactory{
    public static MessageHandler getHandler(PendingAccountValue payload){
        ...
        if(payload.getAction()==RequestType.CREATE_ACCOUNT.getStatusCode()){
            return new AccountCreateHandler();
        }else if(payload.getAction()==RequestType.EDIT_ACCOUNT.getStatusCode()){
            return new AccountEditHandler();
        }
        ...
    }
}
@JmsListener(destination="USER.QUEUE")
public void onMessage(Object message){
    if(message instanceof JMSObjectMessage){
		JMSObjectMessage msgObj = (JMSObjectMessage)message;
	    Object payload = msgObj.getObject();
        MessageHandlerFactory.getHandler(payload).process(payload);
    }
}
@JmsListener(destination="ACCOUNT.QUEUE")
public void onMessage(Object message){
    if(message instanceof JMSObjectMessage){
		JMSObjectMessage msgObj = (JMSObjectMessage)message;
	    Object payload = msgObj.getObject();
        MessageHandlerFactory.getHandler(payload).process(payload);
    }
}

上面实际上演化成了工厂方法,UML图
在这里插入图片描述

优点 :符合开闭原则,比如后面要新加个Group的处理,只需要增加GroupMessageHandlerFactory 以及GroupCreateHandlerGroupEditHandler

缺点 MessageHandlerFactory这个类还是要不断的修改加入if…else。如果增加其他的action ,例如delete,则GroupMessageHandlerFactory
UserMessageHandlerFactory
AccountMessageHandlerFactory都需要加入判断。

由此想到了利用annotation编程

增加一个annotation


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface JMSMessageHandler {
    Class jmsPayLoad();//指定jms监听到message是哪种class,例如PendingUserValue,PendingAccoutValue
    RequestType requestType();//例如指定是CREATE_USER还是CREATE_ACCOUNT
}
public static  enum RequestType {
		CREATE_USER("create_user", 0),
		EDIT_USER("edit_user", 1),
		DELETE_USER("delete_user", 2),
		CREATE_ACCOUNT("create_account", 4),
		EDIT_ACCOUNT("edit_account", 5),
		DELETE_ACCOUNT("delete_account", 6);
		String statusName;
		int statusCode;
		RequestType(String statusName, int statusCode) {
			this.statusName=statusName;
			this.statusCode = statusCode;
		}
		public String getStatusName() {
			return statusName;
		}
		public int getStatusCode() {
			return statusCode;
		}

		public static RequestType valueOf(int code){
			EnumSet<RequestType> set =EnumSet.allOf(RequestType.class);
			return  set.stream().filter(requestType->{
				return requestType.getStatusCode()==code;
			}).findFirst().get();
		}
	}
@Service
public class MQListenerJMSHandlerDispatcher implements ApplicationContextAware{

    private ApplicationContext context;
    public void process(Object payload){
    //找到所有MessageHandler的bean
        Map<String, MessageHandler> msp =BeanFactoryUtils.beansOfTypeIncludingAncestors(context,MessageHandler.class);
        try {
            msp.values().stream().filter(handler->{
            if(!handler.getClass().isAnnotationPresent(JMSMessageHandler.class))
						return false;
                 //找到对应的annotation
                 JMSHandler[] jmsHandlers =  handler.getClass().getAnnotationsByType(JMSMessageHandler.class);
                 JMSHandler jmsHandler =jmsHandlers[0];
                 Class payloadClass = jmsHandler.jmsPayLoad();
                 RequestType choiceType = jmsHandler.requestType();
                 Base base =(Base)payload;
                 RequestType requestType = RequestType.valueOf(base.getRequestType());
                 return base.getClass().isAssignableFrom(payloadClass) &&
                         requestType==choiceType;
             }).findFirst().get().process(payload);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context=applicationContext;
    }
}
@JMSMessageHandler(jmsPayLoad=PendingUserValue.class,
            requestType=RequestType.CREATE_USER)
public class UserCreateHandler implements MessageHandler<PendingUserValue>{
    	public void process(PendingUserValue p){
    	    ...
    	}
}
@JMSMessageHandler(jmsPayLoad=PendingUserValue.class,
            requestType=RequestType.EDIT_USER)
public class UserEditHandler implements MessageHandler<PendingUserValue>{
    	public void process(PendingUserValue p){
    	    ...
    	}
}
@JMSMessageHandler(jmsPayLoad=PendingAccountValue.class,
            requestType=RequestType.CREATE_ACCOUNT)
public class UserCreateHandler implements MessageHandler<PendingAccountValue>{
    	public void process(PendingAccountValue p){
    	    ...
    	}
}
@JMSMessageHandler(jmsPayLoad=PendingAccountValue.class,
            requestType=RequestType.EDIT_ACCOUNT)
public class UserEditHandler implements MessageHandler<PendingAccountValue>{
    	public void process(PendingAccountValue p){
    	    ...
    	}
}

UML图
在这里插入图片描述

优点 : 彻底做到了开闭原则,如果要加入新的handler,只需编写后加入@JMSMessageHandler

扫描二维码关注公众号,回复: 6396890 查看本文章

参考
简单工厂,工厂模式,抽象工厂笔记

猜你喜欢

转载自blog.csdn.net/guo_xl/article/details/84111835