惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
U
Unit 42
H
Help Net Security
博客园_首页
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 【当耐特】
Recent Announcements
Recent Announcements
Recorded Future
Recorded Future
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Cloudflare Blog
S
Security @ Cisco Blogs
M
MIT News - Artificial intelligence
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
Spread Privacy
Spread Privacy
The GitHub Blog
The GitHub Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
K
Kaspersky official blog
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
V
Vulnerabilities – Threatpost
WordPress大学
WordPress大学
C
Cisco Blogs
G
Google Developers Blog
N
News and Events Feed by Topic
P
Palo Alto Networks Blog
Apple Machine Learning Research
Apple Machine Learning Research
Schneier on Security
Schneier on Security
博客园 - 聂微东
Security Latest
Security Latest
Security Archives - TechRepublic
Security Archives - TechRepublic
O
OpenAI News
云风的 BLOG
云风的 BLOG
IT之家
IT之家
PCI Perspectives
PCI Perspectives
Microsoft Security Blog
Microsoft Security Blog
NISL@THU
NISL@THU
小众软件
小众软件
Scott Helme
Scott Helme
大猫的无限游戏
大猫的无限游戏
L
LINUX DO - 最新话题
Microsoft Azure Blog
Microsoft Azure Blog
Simon Willison's Weblog
Simon Willison's Weblog
N
News and Events Feed by Topic
F
Fortinet All Blogs
The Last Watchdog
The Last Watchdog

博客园 - Anders小明

关于架构的思考 如何定义和建立架构 企业应用下的业务组件开发实践 浅谈领域驱动设计 浅谈基础平台 浅谈企业应用架构(二) 浅谈企业应用架构(一) 技术书籍推荐 AOSD的实践冲动——Use Case的实现 业务流程的层次和内容 Domain Model的三种类型及其级别 基于业务模块组件的系统架构 小议领域模型(Domain Model)补充以及更新 软件架构乱弹——问题域及其解决方法 软件工程中的经济行为与软件架构师的工作 Web框架比较 Interface plays as Placeholder, without any class implement it [转贴]做好个人时间管理 基于抽象的分层结构
AspectJ应用--软件产品化的新方法
Anders小明 · 2007-02-12 · via 博客园 - Anders小明

Author: Anders小明

产品化和客户化两个词语是一个对孪生兄弟,一个没有强大客户化能力的软件是不能称为产品化的软件.产品化也就意味着软件公司的开发至少分为两个不同性质的角色:一个负责产品化,一个负责客户化.除去传统的参数化, 继承以及plugin技术外,aspectJ为我们提供另一种能力.

如前所述, 公司有两个不同角色的团队在开发和维护—研发组和项目组,更进一步,本文所说适应如下的开发团队结构:
一个研发组---多个项目组, 每个项目组需要定制化的东西各自不尽相同. 为了保证几个团队的工作的相对独立性,公司希望项目组在做客户化过程中不改研发团队所开发的代码,应用了已知的方法:参数化, 继承以及plugin技术外.

然而这些技术并没有覆盖到所有的问题, 问题描述如下
example.JPG

经过分析发现需要客户化的地方,是需要在Root类里加一个propertyA, 这个时候基于已有的能力,我们可以做的选择是要么项目组A在修改Root类,要么修改每个叶子类(LeafA....), 显然修改root类是一个不错的选择. 然而槽糕的是,项目组B需要是添加另一个properyB,于是项目组B也这么做了. 对于项目组A和B来说这样做是没有太多问题的.
但对于研发组来说问题却是很严重的, 由于研发组需要从项目回收代码,以便吸取优点改进软件,研发组不得不小心的维护各个版本,并处理项目组所做的修改.而同时项目组获取了修改研发组代码的权力,处于时间的压力,会产生不符合系统结构约束的代码.
很明显,这样的工作方式不利我们的工作,我们需要一个新的思路.

在正式提出新方法前,我想先介绍一下微软的DSL Tools以及C# 2.0,各位客官,还请耐心的看一下。
DSL Tools是微软开发的Domain Specification Language,目的是用更接近于业务的语言模型来描述业务问题,并生成运行代码。工具允许其用户定义各自的Domain Language,目标是软件工厂。DSL Tools面临的一个问题(也是公司目前面临),定义好的DSL以及生成代码,不可避免的出现不同客户存在细微的差异性,DSL Tools必须很好的解决它,事实上DSL Tools的确做到了——它基于是C#2.0 Partial Class技术。(有关于DSL Tools的更多信息可以参见MSDN)。
简单说的Partial Class的其实就是一个类的结构信息可以被存储在多个文件中,以下是个例子:
 
file1.cs(微软的一个文件可以定义多个类,所有其文件名不需要同类名):
public partial class CAgent {
    private String name;
    Property String Name{
        get{
            return name;
        }
        set{
            this.name = name;
        }
    }
    public void doSomethingA(){
        ....
    }
}
 
file2.cs
public partial class CAgent {
    private String code;
    Property String Code{
        get{
            return code;
        }
        set{
            this.code= code;
        }
    }
    public void doSomethingB(){
        ....
    }
}
虽然CAgent类被分解为两个文件,不过对于调用者类说,CAgent具体name以及code两个property,以及doSomethingA和doSomethingB两个方法。
现在你可以想象DSL Tools是如何解决客户化这个问题的了!
DSL Tools生成的所有class都是partial class,当对于CAgent(或者其它类)有需要客户化时,需要做的只是添加一个新的文件,用同样的类名加上一个partial的关键字,
public partial class CAgent 就可以添加新的属性和方法(如同我展示的那样,想象一下file1.cs是研发维护,而file2.cs是项目维护的)。也就说,DSL的研发团队和客户化团队的工作时相对独立的。
 
那么你一定会说,这个微软的C#,不幸的是公司用的是Java,java的语言规范不支持这样的能力。
是的,你说的很对,Java语言本身是不支持,不过我们有这样的手段——那就是AspectJ。
实际上AspectJ面世很久了,我接触它至少有一年半了,不过支持一直没有想到这样的用法,直到我研究了DSL Tools(我相信很多道理是相通的,我们目前面临的问题硅谷的那帮人也一样面对过)
下面是一个简单的例子:
OnType.java:
public class OnType {
 public void doAction(){
  System.out.println("OnType.doAction");
 }
}
 
OnTypeAspect.aj
public aspect OnTypeAspect {
 public String OnType.name = "OnTypeAspect";
 
 public void OnType.doActionAspect(){
  System.out.println("OnType.doActionAspect and name is "+ name);
 }
}
 
Main2.aj
public class Main2 {
 public static void main(String[] args){
  OnType onType = new OnType();
  onType.doActionAspect();
 }
}
 
如你所见,程序是可以完整的运行。你的控制台打出了:OnType.doActionAspect and name is OnTypeAspect
不仅如此,AspectJ可以为已有的类添加新的接口,就像C#的partial class做的那样。
 
我以为aspectj是实现我们的目标的一个捷径,并且它是经过实践的,我不相信aspectj和微软的那帮人会闲着没事来支持这样的技术。BTW,我听说weblogic的jrockit准备在虚拟机一级上支持aspectj, 那么或许剩下的工作就是如何管理使用AspectJ了.