扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
如前所述, 公司有两个不同角色的团队在开发和维护—研发组和项目组,更进一步,本文所说适应如下的开发团队结构:
一个研发组---多个项目组, 每个项目组需要定制化的东西各自不尽相同. 为了保证几个团队的工作的相对独立性,公司希望项目组在做客户化过程中不改研发团队所开发的代码,应用了已知的方法:参数化, 继承以及plugin技术外.
然而这些技术并没有覆盖到所有的问题, 问题描述如下
经过分析发现需要客户化的地方,是需要在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了.
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者