中国开发网: 论坛: .NET/C#: 贴子 496802
haitao
No Buzzword AOP --- When we don't have AOP
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
我的blog:http://szhaitao.blog.hexun.com & http://www.hoolee.com/user/haitao
--以上均为泛泛之谈--
不尽牛人滚滚来,无边硬伤纷纷现 人在江湖(出来的),哪能不挨刀(总归是要的)
网络对话,歧义纷生;你以为明白了对方的话,其实呢?

您所在的IP暂时不能使用低版本的QQ,请到:http://im.qq.com/下载安装最新版的QQ,感谢您对QQ的支持和使用

相关信息:


欢迎光临本社区,您还没有登录,不能发贴子。请在 这里登录