Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Troubles with large amount of Code duplication

I have a lot of methods that follow in large parts the same algorithm, and I ideally want to be able to make calls to a generic method that eliminates a lot of code duplication.

I have tons of methods like the ones below, I would optimally want to be able to just call Save<SQLiteLocation>(itemToSave); but i have a great deal of trouble since that the methods SQLiteConnection.Find<T> won't accept an abstract data type like T in generics.

Is there any way to get around this, if i could get it fixed i would save as many as 150 lines of code

Here's my code:

    public bool SaveLocation(ILocation location, ref int primaryKey)
    {
        var dbConn = new SQLiteConnection (dbPath);

        SQLiteLocation itemToSave = new SQLiteLocation ();
        itemToSave.LocationName = location.LocationName;
        itemToSave.Latitude = location.Latitude;
        itemToSave.Longitude = location.Longitude;
        itemToSave.PrimaryKey = location.PrimaryKey;

  ----------------------------------------------------------------------------------------

        SQLiteLocation storedLocation = dbConn.Find<SQLiteLocation>
                                        (x => x.PrimaryKey == location.PrimaryKey);

        if (storedLocation != null)
        {
            dbConn.Update(itemToSave);
            return true;
        }

        else if (storedLocation == null)
        {
            dbConn.Insert(itemToSave);
            primaryKey = itemToSave.PrimaryKey;
            return true;
        }
        return false;
    }

And here another method see how the code in both methods below my dashed line is basically the same thing

    public bool SaveInvitation(IInvitation invitation, ref int primaryKey)
    {
        var dbConn = new SQLiteConnection(dbPath);

        SQLiteInvitation itemToSave = new SQLiteInvitation ();
        itemToSave.GroupName = invitation.GroupName;
        itemToSave.InviterName = invitation.InviterName;
        itemToSave.ParseID = invitation.ParseID;
        itemToSave.GroupParseID = invitation.GroupParseID;
        itemToSave.PrimaryKey = invitation.PrimaryKey;

---------------------------------------------------------------------------------------

        SQLiteInvitation storedInvitation = dbConn.Find<SQLiteInvitation> 
                                            (x => x.PrimaryKey == invitation.PrimaryKey);

        if (storedInvitation != null)
        {
            dbConn.Update(itemToSave);
            return true;
        }
        else if (storedInvitation == null)
        {
            dbConn.Insert(itemToSave);
            primaryKey = itemToSave.PrimaryKey;
            return true;
        }
        return false;
    }
like image 430
Guano Avatar asked Dec 04 '14 19:12

Guano


People also ask

Why is code duplication a problem?

Code duplication makes software less maintainable and reduces our ability to iterate fast.

Why is code duplication so in serious?

The main reason for creation for the duplicate code is Copy and Paste Programming. Developers justify this practice of plagiarism by commenting that this section of code works for the program, and to make it look original modify variables and architecture of the code.

Is it OK to have duplicate code?

In computer programming, duplicate code is a sequence of source code that occurs more than once, either within a program or across different programs owned or maintained by the same entity. Duplicate code is generally considered undesirable for a number of reasons.

Is duplicated code always bad?

Duplication is bad, but… It isn't a question of whether you'll remember: it's a question of when you'll forget.” Which makes perfect sense. It's time well spent when you try to make your code streamlined and readable. You'll end up with a cleaner, easier-to-maintain, and more extensible code base as a result.


1 Answers

Shouldn't you be able to do something like this: Note: ICommonInterface is anything that is common between any allowable classes you would want to use as T. Preferably, looking at your code, an interface or class that exposes the PrimaryKey property.

public bool SaveItem<T>(T item, ref int primaryKey) where T : ICommonInterface, new()
{
    var dbConn = new SQLiteConnection(dbPath);


    T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey);

    if (storedItem != null)
    {
        dbConn.Update(item);
        return true;
    }
    else if (storedItem == null)
    {
        dbConn.Insert(item);
        primaryKey = item.PrimaryKey;
        return true;
    }
    return false;
}

EDIT: Added the new() constraint to the method.

like image 64
gmiley Avatar answered Nov 04 '22 14:11

gmiley