C#抽象方法

时间:2011-02-24 16:37:05

标签: c# design-patterns methods abstraction

我有一套方法,包括日期和布尔。然后,这些方法使用一些SQL,然后将其传递给另一个方法并返回一个列表。除了返回的SQL和List之外,每个方法都基本相同。现在我知道有更好的方法来做这些方法,但我不确定如何。

有没有人对我如何抽象或使用更好的设计有任何想法,因为方法几乎相同?

以下是代码:

private List<ENT_Message> GetMessageData(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    List<ENT_Message> ret = new List<ENT_Message>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from tbl_message";
    }
    else
    {
        sql = " Select * from tbl_message where created_Date between @start_Date and @end_date";
    }

    return Converter.SerializeToMessageList(this.GetData(startDate, endDate, IsSelectAll, sql));                   
}

private List<ENT_SensorData> GetSensorData(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    List<ENT_SensorData> ret = new List<ENT_SensorData>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from tbl_sensor_data";
    }
    else
    {
        sql = "select * from tbl_sensor_data where Timestamp between @start_date and @end_Date";
    }

    return Converter.SerializeToSensorDataList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
}

private List<ENT_SensorDataEvent> GetSensorDataEvents(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    List<ENT_SensorDataEvent> ret = new List<ENT_SensorDataEvent>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from tbl_sensor_data_event";
    }
    else
    {
        sql = "select * from tbl_sensor_data_event where start_time between @start_date and @end_Date";
    }

    return Converter.SerializeToSensorEventDataList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
}

private List<ENT_SensorDataState> GetSensorDataState(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    List<ENT_SensorDataState> ret = new List<ENT_SensorDataState>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from tbl_sensor_data_state";
    }
    else
    {
        sql = "select * from tbl_sensor_data_state where start_time between @start_date and @end_Date";
    }

    return Converter.SerializeToSensorDateStateList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
}

private List<ENT_WorkOrder> GetWorkOrders(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    List<ENT_WorkOrder> ret = new List<ENT_WorkOrder>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from tbl_workorder";
    }
    else
    {
        sql = "select * from tbl_sensor_data_state where completed_date between @start_date and @end_Date";
    }

    return Converter.SerializeToWorkOrderList(this.GetData(startDate, endDate, IsSelectAll, sql));   
}

6 个答案:

答案 0 :(得分:2)

看起来您有机会制作通用方法。如果我有语法错误,我会提前道歉。

private List<T> GetData<T>(DateTime? startDate, DateTime? endDate, bool IsSelectAll) where T : ENT_Data
{
    List<T> ret = new List<T>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from " + T.table;
    }
    else
    {
        sql = " Select * from " + T.table + " where created_Date between @start_Date and @end_date";
    }

    return Converter.Serialize<T>(this.GetData(startDate, endDate, IsSelectAll, sql));    
}

请注意我做过的一些事情:

  1. 泛型方法有一个约束,即T是ENT_Data的子类,是我刚刚编写的类型。
  2. 我为ENT_Data类型提供了table字段,供您查询。
  3. Converter.Serialize方法也以类似方式制作通用。
  4. 如果我错过了任何重要信息,请告诉我。

答案 1 :(得分:2)

您可以大大缩短您的功能。例如,而不是

private List<ENT_SensorDataState> GetSensorDataState(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    List<ENT_SensorDataState> ret = new List<ENT_SensorDataState>();
    string sql = "";

    if (IsSelectAll)
    {
        sql = "select * from tbl_sensor_data_state";
    }
    else
    {
        sql = "select * from tbl_sensor_data_state where start_time between @start_date and @end_Date";
    }

    return Converter.SerializeToSensorDateStateList(this.GetData(startDate, endDate, IsSelectAll, sql));
}

你可以简单地写

private List<ENT_SensorDataState> GetSensorDataState(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
{
    string sql = "select * from tbl_sensor_data_state"
                 + (IsSelectAll ? "" : "where start_time between @start_date and @end_Date");

    return Converter.SerializeToSensorDateStateList(this.GetData(startDate, endDate, IsSelectAll, sql));
}

这基本上将你的功能简化为真正重要的东西:SQL和序列化函数的名称。

答案 2 :(得分:1)

private List<T> GetData<T>(DateTime? startDate, DateTime? endDate, bool IsSelectAll)
        {
            List<T> ret = new List<T>();

            string tableName = "";//Select the table name based on T here
            string sql = "";

            if (IsSelectAll)
            {
                sql = "select * from tbl_sensor_data";
            }
            else
            {
                sql = "select * from tbl_sensor_data where Timestamp between @start_date and @end_Date";
            }
            //Build your list using the appropriate converter based on T here        
            return Converter.SerializeToSensorDataList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
        }

从那时起,你打电话给

GetData<ENT_whatever>() 

答案 3 :(得分:1)

您可以创建一个类SqlRetriever,然后使用要发送的特定SQL消息对每个类进行子类化。

class SqlRetriever {
    public abstract void SendSqlCmd();
    public ArrayList List {
        get; set;
    }
}

class SqlRetrieverXXX
    public const string SqlCmd = " ... ";
    public override void SendSqlCmd()
    {
       /* ... */
    }
}

另一种可能性,涉及较少的分类,设计较差的设计如下:

class SqlRetriever {
        public const string SQLCmd1 = "...";
        public const string SQLCmd2 = "...";

        public void SendSqlCmd(string sqlcmd)
        {
             /*Send the SQL Cmd and store the result in the list */
        }

        public ArrayList List {
            get; set;
        }

        public static ArrayList DoSqlCmd(string sqlCmd)
        {
             var obj = new SqlRetriever();

             obj.SendSqlCmd( sqlCmd );

             return obj.List;
        }
}

答案 4 :(得分:0)

如果将sql语句和委托方法存储在键中某个类型为T的映射中,则将方法设为泛型(方法采用类型T并返回T的List),可以进行映射查找以获取正确的sql语句和委托方法。

答案 5 :(得分:0)

您可以从一个基类继承所有ENT_ *类。然后制作一个方法List&lt; ENT_Base&gt; GetData(yourParams)。创建一个工厂方法,根据ENT_Base的类型为您提供实体列表。 你的GetData()调用并返回它。 你不会绕过switch-case或if-then来确定你必须返回哪种实体。