Как устранить дублирующийся код - PullRequest
2 голосов
/ 10 ноября 2009

У меня есть следующие методы, которые все возвращают разные типы. У меня есть четыре таких метода. В духе хороших практик программирования (СУХОЙ) следует использовать некоторые методы ООП, такие как наследование или интерфейсы, или просто использовать их. Любые комментарии или примеры кода приветствуются. Спасибо.

  static AttendeeResponse GetAttendees(HttpWebRequest request)
    {
        HttpWebResponse resp = (HttpWebResponse)request.GetResponse();

        try
        {
            XmlSerializer ser = new XmlSerializer(typeof(AttendeeResponse));
            return (AttendeeResponse)ser.Deserialize(resp.GetResponseStream());
         }
        catch(Exception e)
        {
            error =  e.InnerException.ToString();
            return null;
        }

    }

    static MemberResponse GetMembers(HttpWebRequest request)
    {
        HttpWebResponse resp = (HttpWebResponse)request.GetResponse();

        try
        {
            XmlSerializer ser = new XmlSerializer(typeof(MemberResponse));
            return (MemberResponse)ser.Deserialize(resp.GetResponseStream());
        }
        catch (Exception e)
        {
            error = e.InnerException.ToString();
            return null;
        }

    }

Ответы [ 6 ]

13 голосов
/ 10 ноября 2009

Как насчет:

// TODO: Improve the name :)
static T FetchItem<T>(HttpWebRequest request)
{
    using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
    {
        try
        {
            XmlSerializer ser = new XmlSerializer(typeof(T));
            return (T) ser.Deserialize(resp.GetResponseStream());
        }
        catch (Exception e)
        {
            error = e.InnerException.ToString();
            return default(T);
        }
    }
}

Обратите внимание, что я включил using комментарий, чтобы избежать утечки соединений. Вам также не нужно закрывать поток, согласно документам.

Значение return null пришлось изменить на return default(T) в случае, если T является необнуляемым типом значения; альтернативой было бы ограничить T ссылочным типом, используя where T : class как часть объявления метода.

Используйте это так:

MemberResponse members = FetchItem<MemberResponse>(request);
...
AttendeeResponse attendee = FetchItem<AttendeeResponse>(request);
1 голос
/ 10 ноября 2009

Использовать дженерики?

static T GetResponse<T>(HttpWebRequest request)
{
    HttpWebResponse resp = (HttpWebResponse)request.GetResponse();

    try
    {
        XmlSerializer ser = new XmlSerializer(typeof(T));
        return (T)ser.Deserialize(resp.GetResponseStream());
     }
    catch(Exception e)
    {
        error =  e.InnerException.ToString();
        return null;
    }

}
0 голосов
/ 02 апреля 2014

Вы можете исключить дублирование кода делегатами. например: если мне нужно закончить две задачи с базой данных:

 OleDbCommand oci = new OleDbCommand(queryString, connection);
 oci.Connection.Open();
 oci.CommandText = "delete * from firstTable";
 oci.ExecuteNonQuery();
 oci.Connection.Close();

 OleDbCommand ocn = new OleDbCommand(queryString, connection);
 ocn.Connection.Open();
 ocn.CommandText = "select count(*) from secondTable";
 int affected = convert.ToInt32(ocn.ExecuteScalar();
 ocn.Connection.Close();

как вы видите, мы продублировали здесь код. Поэтому мне нужно изменить код моего кода следующим образом:

OleDbCommand myAccessCommand = null;
int count = -1;
OleDbWork(secondConnectionString, "SELECT COUNT(*) FROM   secondTable",
out myAccessCommand,
() =>
{
     count = Convert.ToInt32(myAccessCommand.ExecuteScalar());

});

OleDbWork(firstConnectionString, "delete * from firstTable",
out myAccessCommand,
() =>
{
    myAccessCommand.ExecuteNonQuery();
}

и мой метод OleDbWork будет выглядеть так:

internal bool OleDbWork(string connString, string command,
out OleDbCommand myAccessCommand, Action action)
    {
        OleDbConnection myAccessConn = null;
        myAccessCommand = null;
        try
        {
            myAccessConn = new OleDbConnection(connString);
        }
        catch (Exception)
        {
            MessageBox.Show("Cannot connect to database!");

            return false;
        }

        try
        {

            myAccessCommand = new OleDbCommand(command, myAccessConn);

            myAccessConn.Open();

            action();
            return true;

        }
        catch (Exception ex)
        {
            MessageBox.Show("Cannot retrieve data from database. \n{0}",
            ex.Message);

            return false;
        }
        finally
        {
            myAccessConn.Close();
        }
    }

Надеюсь, это поможет

0 голосов
/ 10 ноября 2009
MemberResponse membResp = (MemberResponse )StaticClassName.SerializeIt(request);

static Object SerializeIt(HttpWebRequest request)
    {
        HttpWebResponse resp = (HttpWebResponse)request.GetResponse();

        try
        {
            XmlSerializer ser = new XmlSerializer(typeof(MemberResponse));
            return (Object)ser.Deserialize(resp.GetResponseStream());
        }
        catch (Exception e)
        {
            error = e.InnerException.ToString();
            return null;
        }

    }
0 голосов
/ 10 ноября 2009

Похоже, хороший кандидат на дженерики. Может быть ..?

static E GetPiece< E >(HttpWebRequest request)    {
{
   ...  
}
0 голосов
/ 10 ноября 2009

Вы можете использовать Generics:

static T GetMembers<T>(HttpWebRequest request)
{
    HttpWebResponse resp = (HttpWebResponse)request.GetResponse();

    try
    {
        XmlSerializer ser = new XmlSerializer(typeof(T));
        return (T)ser.Deserialize(resp.GetResponseStream());
    }
    catch (Exception e)
    {
        error = e.InnerException.ToString();
        return null;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...