web层action端业务逻辑层设计

项目越做越大,代码越来越多。陆续出了一些问题。

 

1、action层代码过多,复用性不强。往往多个应用要使用同一个功能。如A应用中有发布感受,B应用中也需要,这时B就把A中action的代码复制过来。

 

2、一个功能比较复杂,调用service比较多。发布文章前要判断是否黑名单,是否有违禁词,然后持久化,然后发积分和站内信等。现在全部写在一起,修改困难,不灵活。

 

重构目标:

 

1、新建Biz层,该层负责调用各单一小模块实现一个复杂功能。该层可打成jar包或发布成SOA,供其他方调用。

 

2、其他应用中如果也要发感受功能,但需要改一个小位置。如发积分策略,将新增自己的发积分模块并注入该Biz即可,影响小。

 

附上代码

 

package com.my.biz;

/**
 * 
 * 描述
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public interface IBiz {

    Object[] execute(Object ... objects );
}

 

package com.my.biz;

import java.util.List;

import com.my.domain.Review;

/**
 * 
 * 描述 这是发布感受的处理流程
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class InsertReviewBiz implements IBiz{

    //初始化信息
    private List<IBizHandler<Review>> initInfoHandlers;
    
    //验证信息
    private List<IBizHandler<Review>> validateHandlers; 
        
    //安全检查
    private List<IBizHandler<Review>> securityCheckHandlers;
    
    //持久化
    private List<IBizHandler<Review>> saveHandlers;
    
    //持久化后操作
    private List<IBizHandler<Review>> afterSaveHandlers;
    
    /**
     * objects[0] = review;
     */
    @Override
    public Object[] execute(Object... objects) {
        // TODO Auto-generated method stub
        BizUtil.exetureHandler(initInfoHandlers, (Review)objects[0]);
        
        BizUtil.exetureHandler(validateHandlers, (Review)objects[0]);
        
        BizUtil.exetureHandler(securityCheckHandlers, (Review)objects[0]);
        
        BizUtil.exetureHandler(saveHandlers, (Review)objects[0]);
        
        BizUtil.exetureHandler(afterSaveHandlers, (Review)objects[0]);
        
        return objects;
    }

    

    public void setInitInfoHandlers(List<IBizHandler<Review>> initInfoHandlers) {
        this.initInfoHandlers = initInfoHandlers;
    }

    public void setValidateHandlers(List<IBizHandler<Review>> validateHandlers) {
        this.validateHandlers = validateHandlers;
    }

    public void setSecurityCheckHandlers(
            List<IBizHandler<Review>> securityCheckHandlers) {
        this.securityCheckHandlers = securityCheckHandlers;
    }

    public void setSaveHandlers(List<IBizHandler<Review>> saveHandlers) {
        this.saveHandlers = saveHandlers;
    }

    public void setAfterSaveHandlers(List<IBizHandler<Review>> afterSaveHandlers) {
        this.afterSaveHandlers = afterSaveHandlers;
    }

    
}

 

 

package com.my.biz;

/**
 * 
 * 描述
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 * @param <T>
 */
public interface IBizHandler<T> {

    void execute(T t);
}

 

 

 

package com.my.biz;

import java.util.List;

/**
 * 
 * 描述
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public final class BizUtil {

    private BizUtil(){
        
    }
    
    static <T> void exetureHandler(List<IBizHandler<T>> bizHandlers,T t){
        for(IBizHandler<T> bizHandler : bizHandlers){
            bizHandler.execute(t);
        }
    }
}

 

 

以下是各处理handler的实现

 

 

package com.my.biz.handler;

import com.my.biz.IBizHandler;
import com.my.domain.Review;
import com.my.domain.model.ITargetRepository;

/**
 * 
 * 初始化感受
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class InitReviewHandler implements IBizHandler<Review>{

    private ITargetRepository targetRepository;
    
    public void execute(Review review){
        review.setTargetSubCategory(targetRepository.
                findTarget(review.getTargetId()).getSubCategroy());
    }

    public ITargetRepository getTargetRepository() {
        return targetRepository;
    }

    public void setTargetRepository(ITargetRepository targetRepository) {
        this.targetRepository = targetRepository;
    }
    
    
}

 

 

package com.my.biz.handler;

import org.springframework.util.Assert;

import com.my.biz.IBizHandler;
import com.my.domain.Review;

/**
 * 
 * 验证感受对象数据
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class ValidateReviewHandler implements IBizHandler<Review>{

    @Override
    public void execute(Review review) {
        // TODO Auto-generated method stub
        Assert.isTrue(review != null);
        Assert.isTrue(review.getContent() != null);
        Assert.isTrue(review.getUserId() > 0);
        Assert.isTrue(review.getTargetId() != null);
        Assert.isTrue(review.getTargetSubCategory() != null && review.getTargetSubCategory().size() > 0);
        
    }

    public static void main(String[] args) {
        Review review = null;
        Assert.isNull(review);
        System.out.println(" end ");
    }
    
}

 

package com.my.biz.handler;

/**
 * 
 * 安全处理
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class SecurityCheckException extends RuntimeException{
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public SecurityCheckException(String content){
        
        super(content);
    }

    
    public static void main(String[] args) throws Exception{
        throw new SecurityException("含有违禁词");
    }
}

 

 

 

package com.my.biz.handler;

import com.my.biz.IBizHandler;
import com.my.domain.Review;
import com.my.domain.model.IReviewRepository;

/**
 * 
 * 持久化感受
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class SaveReviewHandler implements IBizHandler<Review>{

    private IReviewRepository reviewRepository;
    
    @Override
    public void execute(Review t) {
        // TODO Auto-generated method stub
        reviewRepository.create(t);
    }

    public IReviewRepository getReviewRepository() {
        return reviewRepository;
    }

    public void setReviewRepository(IReviewRepository reviewRepository) {
        this.reviewRepository = reviewRepository;
    }

}

 

 

package com.my.biz.handler;

import com.my.biz.IBizHandler;
import com.my.domain.Review;

/**
 * 
 * 发消息
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class AfterSaveReviewSendNotifyHandler implements IBizHandler<Review>{

    @Override
    public void execute(Review t) {
        // TODO Auto-generated method stub
        StringBuilder str = new StringBuilder();
        str.append("id:" + t.getId() + " ")
            .append("targetId:" + t.getTargetId() + " ")
            .append("content:" + t.getContent() + " ");
        System.out.println(" send notify : " + str.toString());
    }
    
    
    
}

 

package com.my.biz.handler;

/**
 * 
 * 安全处理不通过异常
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class SecurityCheckException extends RuntimeException{
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public SecurityCheckException(String content){
        
        super(content);
    }
}

 

以下是domain

package com.my.domain;

import java.util.Date;
import java.util.Set;

/**
 * 
 * 感觉对象
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class Review {

    private String id;
    
    private String content;
    
    private String targetId;
    
    private Set<Integer> targetSubCategory;
    
    private int userId;
    
    private Date createTime;

    public String getId() {
        return id;
    }

    public String getContent() {
        return content;
    }

    public String getTargetId() {
        return targetId;
    }

    public int getUserId() {
        return userId;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setTargetId(String targetId) {
        this.targetId = targetId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Set<Integer> getTargetSubCategory() {
        return targetSubCategory;
    }

    public void setTargetSubCategory(Set<Integer> targetSubCategory) {
        this.targetSubCategory = targetSubCategory;
    }
    
    
}

 

package com.my.domain;

import java.util.Set;

/**
 * 
 * 发布感受的对象,如店铺
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class Target {

    private String id;
    
    private Set<Integer> subCategroy;

    public String getId() {
        return id;
    }

    public Set<Integer> getSubCategroy() {
        return subCategroy;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setSubCategroy(Set<Integer> subCategroy) {
        this.subCategroy = subCategroy;
    }
    
    
}

 

package com.my.domain.model;

import com.my.domain.Review;

/**
 * 
 * 感觉对象仓库
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public interface IReviewRepository {

    Review create(Review review);
}

 

package com.my.domain.model;

import com.my.domain.Target;

/**
 * 
 * 感受目标对象仓库
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public interface ITargetRepository {

    Target findTarget(String targetId);
}

 

package com.my.infrastructure.persistence;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.my.domain.Review;
import com.my.domain.model.IReviewRepository;

/**
 * 
 * 用ibatis实现的感受仓库
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class ReviewRepositoryIbatis implements IReviewRepository{

    @Override
    public Review create(Review review) {
        // TODO Auto-generated method stub
        review.setId(String.valueOf(Math.random()));
        review.setCreateTime(new Date());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("persistence review . id :" + review.getId() + " create date: " + format.format(review.getCreateTime()));
        return review;
    }

    
}

 

package com.my.infrastructure.persistence;

import java.util.HashSet;
import java.util.Set;

import com.my.domain.Target;
import com.my.domain.model.ITargetRepository;

/**
 * 
 * 用ibatis实现的感受目标对象仓库
 *
 * @author 锅巴
 * @version 1.0 2010-8-26
 */
public class TargetRepositoryIbatis implements ITargetRepository{

    @Override
    public Target findTarget(String targetId) {
        // TODO Auto-generated method stub
        Target target = new Target();
        target.setId(targetId);
        Set<Integer> set = new HashSet<Integer>();
        set.add(52);
        set.add(36);
        set.add(68);
        target.setSubCategroy(set);
        System.out.println("target find ");
        return target;
    }

    
}

 

spring 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "/spring-beans.dtd">
<!--
	- Application context definition.
-->
<beans>

	
 
  	<bean id="reviewRepository" class="com.my.infrastructure.persistence.ReviewRepositoryIbatis"/>
  	
  	<bean id="targetRepository" class="com.my.infrastructure.persistence.TargetRepositoryIbatis"/>




	<bean id="initReviewHandler" class="com.my.biz.handler.InitReviewHandler">
		<property name="targetRepository">
			<ref bean="targetRepository"/> 
		</property>
	</bean>
	
	<bean id="validateReviewHandler" class="com.my.biz.handler.ValidateReviewHandler"/>
	
	<bean id="securityCheckReviewHandler" class="com.my.biz.handler.SecurityCheckReviewHandler"/>
	
	<bean id="saveReviewHandler" class="com.my.biz.handler.SaveReviewHandler">
		<property name="reviewRepository">
			<ref bean="reviewRepository"/> 
		</property>
	</bean>
	
	<bean id="afterSaveReviewSendNotifyHandler" class="com.my.biz.handler.AfterSaveReviewSendNotifyHandler"/>
	
	
	
	
	<bean id="insertReviewBiz" class="com.my.biz.InsertReviewBiz">
		<property name="initInfoHandlers">
			<list>
				<ref bean="initReviewHandler"/> 
			</list>
		</property>
		
		<property name="validateHandlers">
			<list>
				<ref bean="validateReviewHandler"/> 
			</list>
		</property>
		
		<property name="securityCheckHandlers">
			<list>
				<ref bean="securityCheckReviewHandler"/>
			</list>
		</property>
		
		<property name="saveHandlers">
			<list>
				<ref bean="saveReviewHandler"/>
			</list>
		</property>
		
		<property name="afterSaveHandlers">
			<list>
				<ref bean="afterSaveReviewSendNotifyHandler"/>
			</list>
		</property>
	
	</bean>
	
 
</beans>

 

junit测试

package com.my.biz;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.my.domain.Review;

public class BizTest {

    ApplicationContext context = null;
    IBiz insertReviewBiz = null;
    
    @Before
    public void setContent(){
        context = new ClassPathXmlApplicationContext(new String[]{"conf/review.context.xml"});
        insertReviewBiz = (IBiz)context.getBean("insertReviewBiz");
    }
    
    @Test
    public void testRunBiz(){
        
       try{
           Review review = new Review();
           review.setTargetId("8");
           review.setContent("888899897");
           review.setUserId(5);
           insertReviewBiz.execute(review);
       }catch(Exception e){
           e.printStackTrace();
       }
       
    }
}

 

 

各个模块都是注入的,Biz层只需要保证大的流程及执行顺序即可。具体实现推迟到handler中,通过增加新的hanlder更改配置文件就可以实现不同的需求。

 

代码实现比较仓促,希望指教。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值