好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

代码抽象层次

代码抽象层次

代码抽象层次

看了kent的实现模式,对代码抽象层次有了一点理解,kent首先问了一个问题,下面的代码有神马问题?

 void   compute()
{
       int  flag =  input();
     flag  |=  1  ;
     output(flag);
} 

粗看来没有,但其实不然,但其实,input和output已经是高层抽象了,例如你并不知道输入来自于何方,到底是键盘输入呢,还是文件输入,又或者是网络输入,同样output也是如此,但是中间设置flag的语句则是一个低层抽象,如果整个函数都是低层抽象,代码应该是这样:

 void   compute()
{
       int  flag =  0  ;
     scanf(  "  %d  " ,& flag);
     flag  |=  1  ;
     fprintf(golbalFileHandler,  "  %d\n  "  ,flag);
} 

反之,如果函数是一个高层抽象的函数,代码应该是这样:

 void   compute()
{
       int  flag =  input();
     setFlag(flag);
     output(flag);
} 

更进一步的,如果flag的位1在业务逻辑的意义是数据以图表形式输出,那么代码应该是这样:

 void   compute()
{
       int  flag =  input();
     setOutputWithChart(flag);
     output(flag);
} 

将高层逻辑和低层逻辑剥离的最大好处时,高层逻辑不用管低层逻辑是怎么实现的,即所谓的解耦,低层逻辑从键盘读也好,从文件读也好,那是低层逻辑的事情,而且低层逻辑改变实现,这事对于高层逻辑也是透明的

疑问:

1)层次不应该太多,层次太多则小函数太多,未必好

2)不同层次的函数放在什么地方,这是个架构问题?

 

C#中IDisposable和IEnumerable、IEnumerator

 

  C#中如何合理的释放非托管内存?在本文中我们将讲解使用IDisposable释放托管内存和非托管内存。

   A. 首先需要让类实现IDisposable接口,然后实现IDispose方法。

    A.a 核心Disponse(bool isDisponse)

      1.此方法首先判断isReadyDisposed(判断是否第一次调用此核心方法),如果不是第一次调用则不做任何操作。

      2.再判断是否是 析构函数调用?如果是析构函数调用不释放托管资源,其交由GC进行释放,如果析构函数释放托管资源可能之前GC释放过,就会导致出现异常。此判断内部释放托管资源内存。

      3.释放非托管资源,并且设置标志位isReadyDisposed=true.

   B. 然后分释放托管内存和非托管内存两种情况进行内存释放处理。

    B.a 释放非托管内存

      1.释放非托管内存需要手动调用本类的Dispose()方法,此方法首先调用Dispose(true)手动释放托管和非托管资源,然后调用GC.SuppressFinalize( this ),让GC不要再调用此对象的析构函数。

    B.b 释放托管内存

       1.释放托管内存是由GC自动调用析构函数,析构函数内部调用Dispose(false)方法.此时只释放非托管资源,而托管资源不管,由GC自行释放。

  我们实现好的类代码如下:

     public   class   IDisponseTest : IDisposable
    {
          private   bool  isReadyDisposed =  false  ;

         ~ IDisponseTest()
        {
              //  析构函数调用时不释放托管资源,因为交由GC进行释放 
            Disponse( false  );
        }

          public   void   Dispose()
        {
              //  用户手动释放托管资源和非托管资源 
            Disponse( true  );
              //  用户已经释放了托管和非托管资源,所以不需要再调用析构函数 
            GC.SuppressFinalize( this  );
            
              //  如果子类继承此类时,需要按照如下写法进行。
              //  try
              //  {
              //      Disponse(true);
              //  }
              //  finally
              //  {
              //      base.Disponse();
              //  } 
         }

          public   virtual   void  Disponse( bool   isDisponse)
        {
              //  isReadyDisposed是控制只有第一次调用Disponse才有效才需要释放托管和非托管资源 
             if   (isReadyDisposed)
                  return  ;
              if   (isDisponse)
            {
                  //  析构函数调用时不释放托管资源,因为交由GC进行释放
                  //  如果析构函数释放托管资源可能之前GC释放过,就会导致出现异常

                  //  托管资源释放 
             }
              //  非托管资源释放 
            isReadyDisposed =  true  ;
        }
    } 

   C#制作一个迭代器对象?使用IEnumerable、IEnumerator

   首先 :让类继承IEnumerable和IEnumerator接口,此时此类会出现IEnumerable.GetEnumerator()方法和IEnumerator.Current属性、IEnumerator.MoveNext(),IEnumerator.Reset()方法。

   其次 :IEnumerator接口是对象遍历的方法和属性实现,而IEnumerable.GetEnumerator()方法是为了获取IEnumerator对象。

   最后 :我们看看迭代器代码实现如下实例:

     class   Program
    {
          static   void  Main( string  [] args)
        {
            CubeEnum cubelist  =  new  CubeEnum( 50  );
              foreach (Cube cube  in   cubelist)
            {
                Console.WriteLine(  "  立方体长:  "  + cube.Length +  "  ,宽  "  + cube.Width +  "  ,高  "  +  cube.Height);
            }
            Console.Read();
        }
    }
      //  立方体,长、宽、高 
     public   class   Cube
    {
          public   int  Length {  get ;  set  ; }
          public   int  Width {  get ;  set  ; }
          public   int  Height {  get ;  set  ; }
    }
      ///   <summary> 
     ///   立方体迭代集合,继承了IEnumerable和IEnumerator
      ///   </summary> 
     public   class   CubeEnum : IEnumerable, IEnumerator
    {
          //  索引 
         public   int  Index {  get ;  set  ; }
          //  立方体集合 
         public  Cube[] cubelist {  get ;  set  ; }
          //  初始化立方体集合 
         public  CubeEnum( int   count)
        {
              this .Index = - 1  ;
            cubelist  =  new   Cube[count];
              for  ( int  i =  0 ; i < count; i++ )
            {
                cubelist[i]  =  new   Cube();
                cubelist[i].Length  = i *  10  ;
                cubelist[i].Width  = i *  10  ;
                cubelist[i].Height  = i *  10  ;
            }
        }
          //  实现IEnumerable的 GetEnumerator() 方法获得IEnumerator对象 
         public   IEnumerator GetEnumerator()
        {
              return  (IEnumerator) this  ;
        }
          //  当前Cube立方体 
         public   object   Current
        {
              get  {  return   cubelist[Index]; }
        }
          //  往下一步移动 
         public   bool   MoveNext()
        {
            Index ++ ;
              if  (Index <  cubelist.Length)
            {
                  return   true  ;
            }
              return   false  ;
        }
          //  重置索引 
         public   void   Reset()
        {
            Index  = - 1  ;
        }
    } 

  本文讲述的是C#基础的应用,如有差错,敬请斧正。

  

 

分类:  代码风格&质量

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于代码抽象层次的详细内容...

  阅读:76次