最近在工作的时候写了好多获取**列表的方法,因为每一种应用所传入的条件都不一样,所以我定义了很多不同参数的方法,返回值类型都是相同的,在需求越来越多的时候我发现,
我的方法里面多了好多重载,多到连我自己想找出一个对应的方法都难找。
我举几个方法让大家分析一下: GetFitListByUserId(int userId, int couponTypeId, int cityId,
            Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn,
                  bool isDesc,
            int start, int count, out int totalCount)GetMisfitListByUserId(int userId, int couponTypeId, int cityId,
              Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn,
                  bool isDesc,
             int start, int count, out int totalCount)
GetFitListByUserId(int userId, int couponTypeId,
            int start, int count, out int totalCount)GetListByPoint(string keyword,
            double longitude, double latitude, double radius, Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn,
            bool isDesc, int start, int count, out int totalCount)
 GetListByPoint(int couponTypeId,
            double longitude, double latitude, double radius, Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn,
            bool isDesc, int start, int count)GetFitListByPoint(int userId, int couponTypeId,
            double longitude, double latitude, double radius, Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn,
            bool isDesc, int start, int count, out int totalCount)其中FitList与MisfitList是适合与不适合大概意思。还有很多重载我没有一一写出,在陆陆续续加入重载后,参数变得很多,有些方法有10个重载之多,别说管理,连应用的时候找出来都难。
请各位大侠指教指教,此类问题该如何解决,在方法命名,参数,重载方面应该如何设计。

解决方案 »

  1.   

    把参数做成一个实体类,然后只写一个方法,在方法里判断实体类里属性值,如果不为空则列为条件之一,为空就不考虑。
    GetFitListByPoint(Class class)
    {
        if(!string.IsNullOrEmpty(class.UserID))
        {
             //业务逻辑
        }
        if(!string.IsNullOrEmpty(class.couponTypeId))
        {
             //业务逻辑
        }
        ……
    }
      

  2.   

    打开MSDN,索引:类库设计准则。
      

  3.   

    使用mvc模式 在传参数的时候不要使用字段,可以使用一个model传递 
      

  4.   

    举个例子,可以根据情况处理,这样统一代码
    GetListByPoint(string keyword,
                double longitude, double latitude, double radius, Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn,
                bool isDesc, int start, int count, out int totalCount)
    class demo  
    {
    string keyword;
    double longitude;
    double latitude;
    double radius; 
    Com.Ritu.Coupon.Common.EnumType.CouponAttribute orderColumn;           
    bool isDesc; 
    int start;
    int count; 
    public demo(){}
    }
    GetListByPoint(demo _demo, out int totalCount)
    {
    _demo.keyword=....
    ...
    }
      

  5.   

    谢谢xufzu123 和ak8800 的解答,但是我发现另外一个问题,如果都用这个种方式的话,方法就变成一个了:
    GetListByDemo(demo _demo);
    这样会不会使得方法名称不够形象?一般我们命名如果带点意义的话,看起来就很明了。
    像GetListByUser(int user);
    这样就很明了的可以知道是根据用户获取列表,
    请问这些问题该如何考虑。
      

  6.   

    你这种情况不太适合传单个类实例作为参数,传类参数用在成员间没有复杂逻辑,参数相对比较统一简单的情况下,否则虽然调用是统一了,但具体给类的哪几个成员赋值后传就比较容易混淆,自己也搞不清了,
    试想这种情况,除了调用方便,逻辑还看得清吗:
    F(Class C)
    C.a
    C.ad
    C.ag
    C.as
    C.aerw
    C.awr
    C.at4
    C.w43a
    C.hra
    C.56a
    C.a3
    C.ayy
    C.aer
    C.are你还记得住调用某个重载方法时该给哪几个赋值吗比较好的办法是
    F(Class Common,Class Spcial)
    Common.A
    Common.B
    Common.C 
    Common类里是通用的参数,是必需要填的

    Spcial.A.A1
    Spcial.A.A2
    是A情况下必须要填的参数
    Spcial.B.B1
    Spcial.B.B2
    是B情况下必须要填的参数
    最后Common里有一个特殊的枚举成员
    Common.Cate 用来填写和判断是那种逻辑,是A还是B还是...
      

  7.   

    然后Spcial成员优先级比Common高
    比如
    Common.Price=10;
    Spcial如果也有一个Price
    Spcial.Price=20
    那业务计算时就拿Spcial的值
    在方法所在类是继承的情况下,参数同样也是继承的
    CA
    {
      public F(Class Common,Class Spcial)
    }SSpcial:Spcial
    {
      int FF_A; // 加了一个FF 
    }CAA:CA
    {
     override public F(Class Common,Class FFSpcial)
    }这样
    CA ca=new CA();
    Comman C=new Common();
    // 赋值
    Spcial S=new Spcial();
    // 赋值
    ca.F(C,S)CA ca=new CAA();
    C=new Common();
    // 赋值
    S=new SSpcial();
    // 赋值
    ((SSpcial)S).FF_A=1;
    ca.F(C,S)调用的地方都是一样的
    ca.F(C,S)
      

  8.   

    这里写错了
    CAA:CA 

    override public F(Class Common,Class Spcial)
    {
      int A=((SSpcial)S).FF_A; // 还可以取值

      

  9.   

    此方法,确实是很简单明了,但是未能解决复杂的条件问题,
    GetFitList(Class class) 

        if(!string.IsNullOrEmpty(class.UserID)) 
        { 
            //业务逻辑 
        } 
        if(!string.IsNullOrEmpty(class.couponTypeId)) 
        { 
            //业务逻辑 
        } 
        …… 

    如果里面的参数一样,但是组合起来的时候数据提取的逻辑确不一样的时候怎么办,
    例如:方法内部逻辑
    if(!string.IsNullOrEmpty(class.UserID)) 
        { 
            //读取A表中匹配userid的记录 
        } 
        if(!string.IsNullOrEmpty(class.couponTypeId)) 
        { 
            //读取A,b表关联中 couponTypeId匹配的记录
        } 
    ---
    现在如果增加一个逻辑
    if(!string.IsNullOrEmpty(class.UserID) && !string.IsNullOrEmpty(class.couponTypeId) ) 
        { 
           //读取A,b表关联中 couponTypeId匹配且匹配userid的记录 
        } 
    ----因为这里面操作的表不只一个,针对不同的业务会关联查询多个表,这样开发人员就不知道到底要传什么值进来才能按他所要的逻辑获取数据了,问题确实难,希望大侠还有更好的方案。
      

  10.   

    不是吧using System;
    using System.Collections.Generic;
    using System.Text;namespace ConsoleApplication12
    {
        class Program
        {
            // 仅仅是一个例子,不代表任何实际意义,也不是最简单的写法        class Shoe
            {
                public String ID = String.Empty;
                public String Color = String.Empty;
                public float Price = 10; // 普通鞋子全售价10块
            }        class BlackShoe_Size_30 : Shoe
            {
                String _SalesVIPList = String.Empty;            public String SalesVIPList
                {
                    get
                    {
                        return _SalesVIPList;
                    }                set
                    {
                        _SalesVIPList = value;
                    }
                }            public BlackShoe_Size_30()
                {
                    Color = "黑色";
                    Price = 15;
                }        }        class RedShoe_Size_40 : Shoe
            {
                DateTime _ClearDate;            public DateTime ClearDate
                {
                    get
                    {
                        return _ClearDate.Date;
                    }                set
                    {
                        _ClearDate = value.Date;
                    }
                }            public RedShoe_Size_40()
                {
                    Color = "红色";
                    Price = 8.5f;
                }
            }        class _BlackParam
            {
                public String SalesVIPList;
            }        class _RedParam
            {
                public DateTime ClearDate;
            }        class SpacialParam
            {
                public _BlackParam BlackParam = new _BlackParam();
                public _RedParam RedParam = new _RedParam();
            }        static void SetShoeInfo(Shoe S, SpacialParam SP)
            {
                if (S is BlackShoe_Size_30 )
                    ((BlackShoe_Size_30)S).SalesVIPList = SP.BlackParam.SalesVIPList;
                else if (S is RedShoe_Size_40 )
                    ((RedShoe_Size_40)S).ClearDate = SP.RedParam.ClearDate;
            }        static void ShowShoeInfo(Shoe S)
            {
                String Message = "#" + S.ID + Environment.NewLine
                    + "颜色:" + S.Color + Environment.NewLine
                    + "单价:" + S.Price + Environment.NewLine;            if (S is BlackShoe_Size_30)
                    Message += "尺码:30" + Environment.NewLine
                        + "专卖客户:" + ((BlackShoe_Size_30)S).SalesVIPList;
                else if (S is RedShoe_Size_40)
                    Message += "尺码:40" + Environment.NewLine
                        + "清仓日期:" + ((RedShoe_Size_40)S).ClearDate.ToString("D");
                Message += Environment.NewLine;
                Console.WriteLine(Message);
            }
            
            static void Main(string[] args)
            {
                // 仅仅演示 SpacialParam类的Param分类赋值的写法
                // 而和S,S2无关,其实这个例子里是可以直接赋值
                // S.SalesVIPList=... 
                // S2.ClearDate=...
                            SpacialParam SP=new SpacialParam ();
                
                BlackShoe_Size_30 S = new BlackShoe_Size_30();
                RedShoe_Size_40 S2 = new RedShoe_Size_40();            S.ID = "001";
                SP.BlackParam.SalesVIPList = "老板";
                SetShoeInfo(S, SP);            S2.ID = "002";
                SP.RedParam.ClearDate = DateTime.Now.AddYears(1);
                SetShoeInfo(S2, SP);
                
                ShowShoeInfo(S);
                ShowShoeInfo(S2);
                
                Console.Read();
            }
        }
    }