No Buzzword AOP --- When we don't have AOP
Posted on 2005-10-09 17:00 idior 阅读(954) 评论(4) 编辑 收藏 引用 网摘
现在有这么一个需求, 你已经写好了一个类 (class Employer). 其中有一些属性和方法。
5 public class Employer
6 {
7 private int id;
8 private string name;
9 public int ID
10 {
11 get { return id; }
12 set { id = value; }
13 }
14 public string Name
15 {
16 get { return name; }
17 set { name = value; }
18 }
19 public void Work()
20 {
21
22 }
23 }
现在要求每个属性在被修改的时候先输出原值再输出修改后的值。这个需求非常简单,很容易就实现了。
5 public class Employer
6 {
7 private int id;
8
9 private string name;
10
11 public int ID
12 {
13 get { return id; }
14 set
15 {
16 Console.WriteLine("Original Value of ID : {0}",id);
17 id = value;
18 Console.WriteLine("Modified Value of ID : {0}",id);
19 }
20 }
21
22 public string Name
23 {
24 get { return name; }
25 set
26 {
27 Console.WriteLine("Original Value of Name : {0}",name);
28 name = value;
29 Console.WriteLine("Modified Value of Name : {0}",name);
30 }
31 }
32
33 public void Work()
34 {
35
36 }
37 }
当然以上是一个很笨的方法,因为输出内容都是硬编码的. 让我们换一个灵活一点的方法. 其中有关StackFrame的用法请参考MSDN.
7 public class Employer
8 {
9 private int id;
10 private string name;
11
12 public int ID
13 {
14 get { return id; }
15 set
16 {
17 StackFrame frame=new StackFrame();
18 // Get Current Method Name "set_ID", then remove "set_"
19 string propertyName=frame.GetMethod().Name.Substring(4);
20 Console.WriteLine("Original Value of {0} : {1}",propertyName,id.ToString());
21
22 id = value;
23
24 Console.WriteLine("Modified Value of {0} : {1}",propertyName,id.ToString());
25 }
26 }
27
28 public string Name
29 {
30 get { return name; }
31 set
32 {
33 StackFrame frame=new StackFrame();
34 string propertyName=frame.GetMethod().Name.Substring(4);
35 Console.WriteLine("Original Value of {0} : {1}",propertyName,name.ToString());
36
37 name = value;
38
39 Console.WriteLine("Modified Value of {0} : {1}",propertyName,name.ToString());
40 }
41 }
42
43 public void Work()
44 {
45
46 }
47 }
出现了很多的重复代码是吧. 没关系,我们就可以将公共的部分提出来.
6 public class Employer
7 {
8 private int id;
9
10 private string name;
11
12 public int ID
13 {
14 get
15 {
16 return id;
17 }
18 set
19 {
20 PrintCurrentProperty(false,id);
21 id = value;
22 PrintCurrentProperty(true,id);
23 }
24 }
25
26 public string Name
27 {
28 get
29 {
30 return name;
31 }
32 set
33 {
34 PrintCurrentProperty(false,name);
35 name = value;
36 PrintCurrentProperty(true,name);
37 }
38 }
39
40 public void PrintCurrentProperty(bool bModified, object value)
41 {
42 StackFrame frame=new StackFrame(1,true);
42 // Get Current Method Name set_ID, then remove "set_"
43 string propertyName = frame.GetMethod().Name.Substring(4);
44 string str = null;
45 string valueString = null;
46 if (bModified == true)
47 str = "Modified";
48 else
49 str = "Original";
50 if (value == null)
51 valueString = "null";
52 else
53 valueString = value.ToString();
54
55 Console.WriteLine("{0} Value of {1} : {2}", str, propertyName, valueString);
56 }
57
58 public void Work()
59 {
60 }
61 }
现在的代码看上去还不错, 即使类中在增加一些属性我们也可以比较方便的实现, 毕竟我们将功能的定义集中到了一个地方(PrintCurrentProperty方法).
如果你看的比较认真, 应该发现以上我们工作的唯一目的就是 --- 消除重复!
如果别的类也需要这个功能呢? 最简单的方法的就是将这个函数Ctrl+C,V到每个需要该功能的类中. Oh! 又是重复. 如何消除它? 将这个方法移到一个专门的类中就可以了.(别跟我提接口, 这篇文章是写给连面向对象都不熟的人看的,要简单简单再简单)
9 public class PropertyPrinter
10 {
11 public void Print(bool bModified, object value)
12 {
13 StackFrame frame=new StackFrame(1,true);
14 // Get Current Method Name set_XXX, then remove "set_"
15 string propertyName = frame.GetMethod().Name.Substring(4);
16 string str = null;
17 string valueString = null;
18 if (bModified == true)
19 str = "Modified";
20 else
21 str = "Original";
22 if (value == null)
23 valueString = "null";
24 else
25 valueString = value.ToString();
26
27 Console.WriteLine("{0} Value of {1} : {2}", str, propertyName, valueString);
28 }
29 }
Employer变化不大.
6 public class Employer
7 {
8
9 private PropertyPrinter propPrinter;
10 private int id;
11 private string name;
12
13 public Employer(PropertyPrinter printer)
14 {
15 propPrinter = printer;
16 }
17
18 public int ID
19 {
20 get
21 {
22 return id;
23 }
24 set
25 {
26 propPrinter.Print(false,id);
27 id = value;
28 propPrinter.Print(true,id);
29 }
30 }
31
32 public string Name
33 {
34 get
35 {
36 return name;
37 }
38 set
39 {
40 propPrinter.Print(false,name);
41 name = value;
42 propPrinter.Print(true,name);
43 }
44 }
45
46
47 public void Work()
48 {
49 }
50 }
14 static void Main(string[] args)
15 {
16 PropertyPrinter printer=new PropertyPrinter();
17 Employer e=new Employer(printer);
18 e.ID=12;
19 e.Name="idior";
20 }
如果再来一个类Car.
4 public class Car
5 {
6 private PropertyPrinter propPrinter;
7
8 private double speed = 0;
9
10 public Car(PropertyPrinter printer)
11 {
12 propPrinter = printer;
13 }
14
15 public double Speed
16 {
17 get
18 {
19 return speed;
20 }
21 set
22 {
23 propPrinter.Print(false,speed);
24 speed = value;
25 propPrinter.Print(true,speed);
26 }
27 }
28 }
现在实现这个功能几乎没有什么重复的代码了.
现在你能看到什么重复代码吗? 你还觉得哪里不爽呢?
不爽的话来看看Aop是怎么解决的。
Feedback
# re: No Buzzword AOP --- When we don't have AOP 回复 更多评论
2005-10-10 18:32 by wanghualiang
好文,简单易懂.
# re: No Buzzword AOP --- When we don't have AOP 回复 更多评论
2005-10-12 16:59 by Tim
你的意思我了解 问题这个例子举得不好
① Console.WriteLine("Original Value of ID : {0}",id);
② propPrinter.Print(false,id);
要重用的时候 还是要Copy
不过是
① 把 ID 改成 Name 且 把 id 改成 name
② 只需要把 id 改成 name
汗 这也叫消除重复?
有区别吗。。。且效率还低了。。。
BTW : 推荐一篇文章给你看
《读书人之俗》---朱自清
# re: No Buzzword AOP --- When we don't have AOP 回复 更多评论
2005-10-12 17:15 by idior
① Console.WriteLine("Original Value of ID : {0}",id);
② propPrinter.Print(false,id);
现在①只是做了很简单的事,而实际应用中是不会如此简单的。
这篇只是引出aop的思想,让你去思考,好的解决方案还要看下篇
http://idior.cnblogs.com/archive/2005/10/11/251816.html