Does the Inquisition depend on type, generics, inheritance, or both?

I have a method that initiates a specific class depending on the type of send as a parameter of this method. This works fine, but I really don't like this way of if(c == class_name.class)dealing with this, and I'm sure there is a better way to do this using generics and inheritance. The method I use looks (maybe mistakenly ...) dirty for me.

I have been following several tutorials regarding generics and inheritance, but even if I think I more or less understand these two concepts separately, I struggle to understand their combination ... And I think that both of these concepts can solve my a problem once mixed. Can someone show me the right way to track, generics, inheritance, both, or save my code this way. Is there a better way to do this?

This is my actual method:

private void addData(String csvFile, char separator, Class<?> c) {
        int lineNumber = 1;
        CSVReader reader;

        try {
            reader = new CSVReader(new InputStreamReader(getAssets().open(csvFile)), separator);
            String[] line;

            realm.beginTransaction();
            if(c == FlagDef.class) {
                while ((line = reader.readNext()) != null) {
                    FlagDef flagDef = new FlagDef(Long.parseLong(line[0]), line[1], line[2]);
                    Log.d(TAG, String.format("%s %s %s", line[0], line[1], line[2]));
                    realm.copyToRealm(flagDef);
                    lineNumber++;
                }
            }
            if(c == Picture.class) {
                while ((line = reader.readNext()) != null) {
                    Picture picture = new Picture(Long.parseLong(line[0]), line[1]);
                    Log.d(TAG, String.format("%s %s", line[0], line[1]));
                    realm.copyToRealm(picture);
                    lineNumber++;
                }
            }
            realm.commitTransaction();

            reader.close();
        } catch (FileNotFoundException ex) {
            Log.e(TAG, String.format("File %s not found : %s", csvFile, ex));
        } catch (IOException ex) {
            Log.e(TAG, String.format("Error parsing line number %s : %s", lineNumber, ex));
        }
    }

Call this method:

addData(FILE_FLAGS,SEPARATOR,FlagDef.class);
addData(FILE_PICTURES,SEPARATOR,Picture.class);

Method declaration copyToRealmcan be found here.

This is for Android, and I'm actually targeting API 16.

For brevity, I only indicate two types of Pictureand FlagDef, but I plan to have at least 10 different types.

+4
source share
5

.

, @VGR . , Android API 16. , @VGR, , API 24. , , . , - , .

, StephaneM, , , , .

@Eugene @mickaël-b, , . , , , . , :)

enter image description here

. , , . ... 2 , 2 , .

, , Realm csv.

RealmDbGenerator dbGenerator = new RealmDbGenerator(this);    

    //flags
    dbGenerator.setGenerationStrategy(new FlagDefStrategy());
    dbGenerator.addData(FILE_FLAGS,SEPARATOR);

    //pictures
    dbGenerator.setGenerationStrategy(new PictureStrategy());
    dbGenerator.addData(FILE_PICTURES,SEPARATOR);

RealDbGenerator:

public class RealmDbGenerator {
    private static final String TAG = RealmDbGenerator.class.getSimpleName();

    public void setGenerationStrategy(GenerationStrategy generationStrategy) {
        this.generationStrategy = generationStrategy;
    }

    private GenerationStrategy generationStrategy;
    private Realm realm;
    private Context context;

    public RealmDbGenerator(Context context) {
        this.realm = Realm.getDefaultInstance();
        this.context = context;
    }

    public void addData(String csvFile, char separator) {
        CSVReader reader;

        int lineNumber = 1;

        try {
                reader = new CSVReader(new InputStreamReader(context.getAssets().open(csvFile)), separator);
                String[] line;

                realm.beginTransaction();
                while ((line = reader.readNext()) != null) {
                    generationStrategy.addData(line, realm);
                }
                realm.commitTransaction();

                reader.close();
        } catch (FileNotFoundException ex) {
            Log.e(TAG, String.format("File %s not found : %s", csvFile, ex));
        } catch (IOException ex) {
            Log.e(TAG, String.format("Error parsing line number %s : %s", lineNumber, ex));
        }
    }
}

:

public interface GenerationStrategy {
    void addData(String[] line, Realm realm);
}

FlagDefStrategy:

public class FlagDefStrategy implements GenerationStrategy {
    private static final String TAG = FlagDefStrategy.class.getSimpleName();

    @Override
    public void addData(String[] line, Realm realm) {
        FlagDef flagDef = new FlagDef(Long.parseLong(line[0]), line[1], line[2]);
        Log.d(TAG, String.format("%s %s %s", line[0], line[1], line[2]));
        realm.copyToRealm(flagDef);
    }
}

PictureStrategy:

public class PictureStrategy implements GenerationStrategy  {
    private static final String TAG = FlagDefStrategy.class.getSimpleName();

    @Override
    public void addData(String[] line, Realm realm) {
        Picture picture = new Picture(Long.parseLong(line[0]), line[1]);
        Log.d(TAG, String.format("%s %s", line[0], line[1]));
        realm.copyToRealm(picture);
    }
}
+1

, . , , "" .

, , , Picture FlagDef , , CSVable (, ) :

<T extends CSV> void addData(Class<T> c)

( , CSVable)

+2

Class<?> c Function<String[], RealmModel>:

private void addData(String csvFile, char separator, Function<String[], RealmModel> modelConstructor) {

if :

while ((line = reader.readNext()) != null) {
    RealmModel model = modelConstructor.apply(line);
    Log.d(TAG, String.join(" ", line));
    realm.copyToRealm(model);
    lineNumber++;
}

addData :

addData(FILE_FLAGS, SEPARATOR, line -> new FlagDef(Long.parseLong(line[0]), line[1], line[2]));
addData(FILE_PICTURES, SEPARATOR, line -> new Picture(Long.parseLong(line[0]), line[1]));
+2

, , :

abstract class Builder<T> {
    abstract T build( String[] line);
}

:

class FlagDefBuilder extends Builder<FlagDef > {

    @Override
    FlagDef build( String[] line )
    {
        FlagDef flagDef = new FlagDef(Long.parseLong(line[0]), line[1], line[2]);
        Log.d(TAG, String.format("%s %s %s", line[0], line[1], line[2]));
        return flagDef;
    } 

}

    class PictureBuilder extends Builder<FlagDef > {

        @Override
        FlagDef build( String[] line )
        {
            Picture picture = new Picture(Long.parseLong(line[0]), line[1]);
            Log.d(TAG, String.format("%s %s", line[0], line[1]));
            return picture;
        }       
    }

addData :

    private void addData(String csvFile, char separator, Builder<?> b) {
        int lineNumber = 1;
        CSVReader reader;

        try {
            reader = new CSVReader(new InputStreamReader(getAssets().open(csvFile)), separator);
            String[] line;

            realm.beginTransaction();
                while ((line = reader.readNext()) != null) {
                    realm.copyToRealm(b.build(line));
                    lineNumber++;
                }
            }
            realm.commitTransaction();

            reader.close();
        } catch (FileNotFoundException ex) {
            Log.e(TAG, String.format("File %s not found : %s", csvFile, ex));
        } catch (IOException ex) {
            Log.e(TAG, String.format("Error parsing line number %s : %s", lineNumber, ex));
        }
    }

:

addData(FILE_FLAGS,SEPARATOR, new FlagDefBuilder());
addData(FILE_PICTURES,SEPARATOR, new PictureBuilder());

addData.

+1
source

I think this is a modularity problem, why not create two methods to add data and avoid the class type parameter?

private void addFlagData(String csvFile, char separator) {
...
}

private void addPictureData(String csvFile, char separator) {
...
}
0
source

Source: https://habr.com/ru/post/1690131/


All Articles