DCI的AspectJ实现

11-03-17 banq
文章作者写了使用多个框架实现DCI模式(Data Context Interaction)的文章,这次他使用aspectJ(Spring)谈如何实现DCI,他的结论是比Qi4j要清晰一些。

下面是Qi4j的实现代码:

SingletonAssembler assembler = new SingletonAssembler() {
    public void assemble(ModuleAssembly module) throws AssemblyException {
        module.addEntities(TaskEntity.class, UserEntity.class);//加入任务数据实体  和用户数据实体
        module.addServices(MemoryEntityStoreService.class, UuidIdentityGeneratorService.class);//加入服务
    }
};

UnitOfWork uow = assembler.unitOfWorkFactory().newUnitOfWork();

TaskEntity task = uow.newEntity(TaskEntity.class);

EntityBuilder<UserEntity> builder = uow.newEntityBuilder(UserEntity.class);
builder.instanceFor(AssigneeData.class).name().set("Rickard");
UserEntity user = builder.newInstance();

{
    //根据用户名为"Rickard "产生一个场景
    InboxContext inbox = new InboxContext(user, user);
    //与任务结合
    inbox.assign(task);
}

uow.complete();
<p>

以上代码主要表达意思是:给一个名叫"Rickard "的用户分配一个任务。作者认为上面代码很多严重依赖反射,影响性能,而且这些实体类不是普通的POJO类,和Spring之类框架整合起来困难。

下面是和aspectJ的过程,第一步定义几种分配行为,作为实体的元注解使用:

public interface Assignments {

    void assign(Assignable assignable, Assignee assignee);

    List<Assignable> assignments();
}

public interface Assignable {

    void assignTo(Assignee assignee);
}

public interface Assignee {

    String assigneeName();
}
<p>

以下是参与者的实体数据:

@AssignmentsRole //分配者
public class Project {
}

@AssignableRole  //被分配者
public class Task {
}
    
@AssignmentsRole
@AssigneeRole
public class User {

    public User(String name) {
        setName(name);
    }
}
<p>

下面是关键的建立一个aspect类:

aspect AssignableImpl {

    declare parents: (@AssignableRole *) implements Assignable;

    private Assignee Assignable.assignee;

    //分配动作 
   public void Assignable.assignTo(Assignee assignee) {
 // No object schizophrenia - this reference is to the entity itself.
        this.assignee = assignee;
        System.out.println(assignee.assigneeName());
    }
}
<p>

下面是场景对象

public class InboxContext {

    private Assignments assignments;
    private Assignee assignee;

    public InboxContext(Assignments assignments, Assignee assignee) {
        this.assignments = assignments;
        this.assignee = assignee;
    }

    public void assign(Assignable assignable) {
        assignments.assign(assignable, assignee);
    }
}
<p>

(banq疑问:一般DCI有了场景 数据就可以了,这里多出一个aspectj,难道比qi4j要简单吗?)

最后是实现DCI混合客户端代码:

Task task = new Task();
User user = new User("Rickard");

InboxContext inbox = new InboxContext(user, user);
//给用户Rickard分配任务
inbox.assign(task);

System.out.println("Nr of assignments: " + user.assignments().size());

Project project = new Project();
Task task2 = new Task();

//获得场景
inbox = new InboxContext(project, user);
//给某个项目中的用户Rickard分配任务
inbox.assign(task2);

System.out.println("Nr of assignments: " + project.assignments().size());
<p>

User Task都是没有继承任何类的POJO,可以被序列化,也可以在spring.xml配置中配置。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userRickard" class="net.sourceforge.dciaspectj.example1.entity.User">
        <constructor-arg index="0" value="Rickard" />
    </bean>

    <bean id="project" class="net.sourceforge.dciaspectj.example1.entity.Project" />

    <bean id="task1" class="net.sourceforge.dciaspectj.example1.entity.Task" />

    <bean id="task2" class="net.sourceforge.dciaspectj.example1.entity.Task" />

    <bean id="userInbox" class="net.sourceforge.dciaspectj.example1.context.InboxContext">
        <constructor-arg index="0" ref="userRickard" />
        <constructor-arg index="1" ref="userRickard" />
    </bean>

    <bean id="projectInbox" class="net.sourceforge.dciaspectj.example1.context.InboxContext">
        <constructor-arg index="0" ref="project" />
        <constructor-arg index="1" ref="userRickard" />
    </bean>
</beans>
<p>

原文:

DCI in AspectJ | Javalobby

案例代码:http://sourceforge.net/projects/dci-in-aspectj/files/dci_in_aspectj-1.0.0-src.zip/download

                   

2
banq
2011-03-17 11:25
请注意,文中使用配置了实体类User等创建时,并给给User对象赋值为"Rickard",这只是一个演示,关键是:实战中:User或Project的数据是从数据库中获得的。

关键是:我们已经注意到,在Spring管理的业务层,已经对实体类加了@AssignmentsRol之类元注解,也就是不能不管模型实体类了,下面的问题是:模型实体类的对象生存在哪里?

http://www.jdon.com/jivejdon/thread/39885/15#23132346

猜你喜欢