Sim*_*nni 15
我想在Adam的回答中再添一个例子.
使用方面是一种改进软件模块化的方法,以及OOP,除了OOP"垂直"应用,而AOP"水平"应用.
所以,虽然建议可以用来修改"水平"的应对一些标准的所有方法的行为,在咨询aften代码还需要一些数据,和ITD能够添加域"水平",而在同一时间包含在单个编译单元(方面)中的相关数据和代码.
由于您是通过ITD字段添加数据,因此您可能还希望提供一些方法来操作这些字段,例如setter/getter.
我试着将它改写几次,我希望它很容易理解.
举个例子,假设你有一个图形编辑程序,用户可以在其中创建,删除和显示多个形状(非常规范的呃?:D).
形状有很多数据,例如它们有颜色,坐标等......它们正确地属于类本身.然而,由于这是一个Web 3.0应用程序,您希望用户能够在一个单一的图纸,这意味着当它改变时,每个形状必须知道,如果它已经传达给其他用户的形状改变合作,羯羊它被一些实际拖动它的用户锁定等等.
你可以在简单的OOP中实现它,在Shape中实现相关的部分或任何你的根类,但是你将使用像"this.setDirty(true)"之类的调用或类似的东西来污染所有的setter.
相反,你决定去AOP并在一个方面实现它.在这种情况下,您可以轻松地所有制定者后面加一个建议,但你也需要存储一个"脏"布尔,甚至如果你想优化你的网络协议仅发送变化的增量,改变属性列表.
你可以实现它
public aspect ShapesAreDirtyThings {
private boolean Shape.dirty;
after(Shape s) : execution(* Shape+.set*(..)) {
s.dirty = true;
// Set some other global field, start a thread to communicate
// to other users about the change, whatever ..
}
public boolean Shape.isDirty() {
return s.dirty;
}
public boolean Shape.findDirtyChildren() { // whatever
}
Run Code Online (Sandbox Code Playgroud)
对于常见的AOP来说,这是你无法做到的,只需要封装在单个编译单元中的建议,该建议所需的数据以及最终将对该数据进行操作的方法.
Java不支持多重继承或mixin.但是对于ITD,你可以使Scala像Traits或Ruby一样使用Mixins.
这是一个利用JPA和Spring的Configurable的例子:
接口:
package com.evocatus.aop;
public interface DomainNotify {
public void postPersist();
public void postUpdate();
public void postRemove();
}
Run Code Online (Sandbox Code Playgroud)
AspectJ ITD:
package com.evocatus.aop;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.Transient;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.springframework.beans.factory.annotation.Autowired;
import com.evocatus.service.DomainNotifyService;
privileged aspect DomainNotifyAdvice {
@JsonIgnore
@Transient
@Autowired
transient DomainNotifyService DomainNotify.domainNotifyService;
@PostPersist
public void DomainNotify.postPersist() {
this.domainNotifyService.publishSave(this);
}
@PostUpdate
public void DomainNotify.postUpdate() {
this.domainNotifyService.publishUpdate(this);
}
@PostRemove
public void DomainNotify.postRemove() {
this.domainNotifyService.publishRemove(this);
}
}
Run Code Online (Sandbox Code Playgroud)
现在任何实现 DomainNotify的类都将获得编织的ITD方法.
@Entity
@Configurable
public class MyJPAObject implements DomainNotify {
}
Run Code Online (Sandbox Code Playgroud)