none
请教通过类对象调用成员函数时传参和返回值方式问题 RRS feed

  • 问题

  • 我做了个类,类中有数据成员私有,属性公有和成员函数public,而且有个特点,在使用某个方法时经常需要使用到该类中其他方法得出的数据
    class A
    {
        private string _name;
        private int  _pasword;
        private char[] _qita;
        .......
        public string Name{ set{}  get{} }
        public int Password{ set{}  get{} }
        public char[] Qita{ set{}  get{} }
        .......
        下面是方法了
    }
    在调用该类方法和写方法时就遇到了几种选择,我是新手,不知道那种方式更好,希望高手指点下
    1.成员函数做成有返回值,这样调用函数就可以得到计算出来的结果
      public char[] B(int ,string...)
      缺点:调用该类方法时就必须定义个和函数返回值相同类型的变量来保存值(因为这值在调用该类其他方法时要用到),如果要调用多个该类的这样方法时,就得在使用的地方设置很多变量来保存值
      我想这样的话使用的地方代码就不简洁,会出现一个按钮事件里代码过长
    2 成员函数无返回值,每次运算完就把得到的数据就放到该对象相应的属性里,这样在解决了上面的缺点,而且这样也可以在需要时直接传参给其他方法使用了。
     public void B(int,string...)
      {
              .....
            Qita=上面计算的结果保存到该属性
      }
      在给其他方法传参数时这样做:假设对象是theA,类中另外一个方法是public void C(char[] Qita)
        直接:theA.C(theA.Qita)
        还有个问题就是既然使用这种方式的话,方法的参数是不是可以省去了,直接theA.C()因为在C(){ }中属性可见。
        缺点:考虑到有些数据要作为下面方法的参数,这样我的类封装给人用的时候就可能出问题了,有些数据需要先算出来的,保存到属性,别人不调用B就直接调用我上面说的方法C(thA.Qtita),这时就错了,
        当然看方法注释或调试时可以检查出来,不知道这会不会是个问题。
      我目前采用这种方式
    3 成员函数还是无返回值,类似第一种,只是把保存值的那个变量作为参数引用传参数进方法,在方法中将计算结果保存到该变量中,缺点类似第一种
    大家在帮忙分析时可以主要考虑下面几个因素:
        1.很多方法用到的数据是从其他方法得到的
        2. 考虑类的封装,我希望类拿给别人用的时候,他直接可以调用他要实现的功能的相应方法 ,而不会出现像我第二点中说的缺点
        3.设计类的时候  a.设计几个相对功能独立的类,在使用的时候直接声明各个类的对象实现各自的方法 b.设计一个大类,考虑到我项目中有些类中方法计算的数据在其他类中可能要用到,在使用是直接一个对象就可以了,而且不会出现上一个类中的对象销毁了,但是下一个对象要用到的问题。这两种方式那种更适合我的问题。
      4.我现在做的是单机版程序,以后还要做web版的,我希望在做web版时尽可能少改点
      5.我考虑分层来做的,数据层,业务逻辑层,表现层
    2009年8月1日 1:28

答案

  • Hi,
       随便参与讨论一下,,其实可以参考一下Framwork的类库,你反射查看一下,他们如何设计的。
       直接返回值,这个方式比较直接,方便调用。这个比较常见、。
       通过属性获取数据,那么你必须提供属性初始化的内部调用,这样的做发在asp.net的类库常见,比如获取一个页面的的response对象,内部已经对此属性提供了实现。有点是属性器可以提供访问限制。
       引用类型传参,这个方式的好处是可以修改参数,主要优势在于可以提供多个返回值。
       个人呢推荐方式1和3。除非你的类库只是内部类之间的调用,才推荐2。
       分层可以,这个也是常见的三层架构,你可以复用数据和业务逻辑层。以后开发网站也很方便。
       方法可行
    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    • 已标记为答案 梦里人 2009年8月1日 13:59
    2009年8月1日 4:42
    版主

全部回复

  • Hi,
       随便参与讨论一下,,其实可以参考一下Framwork的类库,你反射查看一下,他们如何设计的。
       直接返回值,这个方式比较直接,方便调用。这个比较常见、。
       通过属性获取数据,那么你必须提供属性初始化的内部调用,这样的做发在asp.net的类库常见,比如获取一个页面的的response对象,内部已经对此属性提供了实现。有点是属性器可以提供访问限制。
       引用类型传参,这个方式的好处是可以修改参数,主要优势在于可以提供多个返回值。
       个人呢推荐方式1和3。除非你的类库只是内部类之间的调用,才推荐2。
       分层可以,这个也是常见的三层架构,你可以复用数据和业务逻辑层。以后开发网站也很方便。
       方法可行
    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    • 已标记为答案 梦里人 2009年8月1日 13:59
    2009年8月1日 4:42
    版主
  • 您好,以下个人观点逐一对应您的问题,请参考:

    1、这个是重构中最常用的方法,不用担心变量的问题,您可以不申明它,直接使用成员方法代替临时变量,可能会造成性能的损失,这并不是重要的。使用了成员方法就相当于使用了一个全局的变量,在类中任何地方都可以使用。您可以参考Martin Fowler的《Refactoring:Improving the Design of Existing Code》,里面有详尽的讨论!

    2、是的,方法参数可以省略,可以在Qtita的get中计算。感觉您现在虽然在使用属性但不是很明了。属性的产生历史基本上是可以从我第一个回答中演变出来。其本质就是一个查询方法。在Qtita的get中计算结果,这样客户程序在使用时不会拿到未经计算的值。

    3、这种做法务必不在方法中为引用类型赋值,而是调用引用类型的成员方法来修改。这个在Martin Fowler的书亦有讨论

         3.1、在这里把握好职责分配的问题,使用重构的手法观测这些数据都应该属于哪个类。
         3.2、用我上面所述的就可以解决
         3.3、个人偏向a,毕竟这是一个分析职责和关系的思路,对应对随着项目的进展产生的复杂性,甚至是项目以后的变更,都将大有好处,这也是面向对象的开发核心。

    4、坚持面向对象和面向组件的开发。把您自己当作上帝(上帝要创造和管理这个纷杂的世界是要梳理好各方的责任和关系的),开发的过程中看清各业务模型之间的关系和职责。

    5、分层是一种职责的划分,力争将业务模型和支持系统分离。最终系统更能适应客户的业务需求和变化。
        

    • 已标记为答案 梦里人 2009年8月1日 13:58
    • 取消答案标记 梦里人 2009年8月1日 13:59
    2009年8月1日 5:45
  • 谢谢Frank Xu Lei版主的回答,我懂些了,今天我也重新对这问题思考了下的,就是不知道对不对,我的理解:属性只是提供了外部变量访问类对象成员的数据方法,而不需将私有成员公开,私有成员是描述类的特性的,而外部需要访问他的话才将其声明为属性,属性应该是在对象初始化时就有个初值的,之后就可以获取和设置该属性了,我的第2种做法所担心的问题也就是因为没有在内部对此属性提供实现。而且我的第二种方法是不是还有个问题,就是会出现为了保存某个方法计算的结果而声明一个属性来保存,其实这样做合不合理的?或者换种方式来问就是我的方法计算的结果需不需要设置个属性来保存,这样我可以提供数据给其他类使用?
    • 已标记为答案 梦里人 2009年8月1日 9:07
    • 取消答案标记 梦里人 2009年8月1日 13:58
    2009年8月1日 9:07
  • 谢谢Frank Xu Lei版主的回答,我懂些了,今天我也重新对这问题思考了下的,就是不知道对不对,我的理解:属性只是提供了外部变量访问类对象成员的数据方法,而不需将私有成员公开,私有成员是描述类的特性的,而外部需要访问他的话才将其声明为属性,属性应该是在对象初始化时就有个初值的,之后就可以获取和设置该属性了,我的第2种做法所担心的问题也就是因为没有在内部对此属性提供实现。而且我的第二种方法是不是还有个问题,就是会出现为了保存某个方法计算的结果而声明一个属性来保存,其实这样做合不合理的?或者换种方式来问就是我的方法计算的结果需不需要设置个属性来保存,这样我可以提供数据给其他类使用?

    Hi,
      不要客气,交流。我也是学习。
        属性访问器提供了更灵活的权限控制。本质上这些变量或者对象保存的数据,应该都是在内存里的。只是看你使用什么方式存储和访问了。如果是引用传递或者直接返回的话应该还是原有数据的引用,不会重新分配内存来存储数据。深拷贝可能涉及到重新申请内存的问题。如果可以直接返回数据,就不要在放在一个内的属性里,这样还牵扯到垃圾回收问题,你对象的生命周期不结束,很多资源GC是无法回收的。
    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    2009年8月1日 9:23
    版主