享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

No Buzzword AOP --- When we don't have AOP

Posted on 2005-10-09 17:00  idior  阅读(1904)  评论(5编辑  收藏  举报

现在有这么一个需求, 你已经写好了一个类 (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是怎么解决的