如何使用访客模式处理集合?

时间:2013-05-15 14:15:37

标签: android database json design-patterns visitor

我必须解析JSON文件中的数据并将数据插入到我的数据库中。有三个文件:

  • 国家

    [     {         “id”:1,         “名字”:“美国”,         “org_ids”:[             1,             2,             3         ]     },     {         “id”:2,         “名字”:“中国”,         “org_ids”:[             1,             3,             4         ]     },     {         “id”:3,         “名称”:“香港”,         “org_ids”:[             1,             2         ]     } ]

  • 国际组织

    [     {         “id”:1,         “名字”:“UNO”     },     {         “id”:2,         “名称”:“美国国家组织”     },     {         “id”:3,         “名称”:“国际刑警组织”     },     {         “id”:4,         “名称”:“欧盟”     },     {         “id”:5,         “名称”:“英联邦”     } ]

  • [     {         “id”:1,         “名字”:“非洲”     },     {         “id”:2,         “名字”:“北美”     },     {         “id”:3,         “名字”:“南美洲”     },     {         “id”:4,         “名字”:“亚洲”     },     {         “id”:5,         “名字”:“欧洲”     },     {         “id”:6,         “名字”:“澳大利亚”     } ]

请不要注意我的JSON的内容,它们不包含列出的国际组织的真实成员。这只是一个例子。

Here我被建议使用the visitor design pattern。我完全同意使用它,以免将JSON读取逻辑与数据库逻辑混合在一起。

我的JSON解析器类在下面。

class JsonParser {

    private List<Country> mCountries;

    private abstract class BaseEntity {

        private String name;
        private long id;

        private BaseEntity(long id, String name) {
            this.id = id;
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return ID + COLON + SPACE + id + COMMA + SPACE + NAME + COLON + SPACE + name;
        }
    }

    class Country extends BaseEntity {

        private List<Long> orgsIds;

        public Country(long id, String name, List<Long> orgsIds) {
            super(id, name);
            this.orgsIds = new ArrayList<Long>();
            this.orgsIds.addAll(orgsIds);
        }

        public List<Long> getOrgsIds() {
            return orgsIds;
        }

        @Override
        public String toString() {
            return super.toString() + COMMA + SPACE + ORG_IDS + SPACE + orgsIds;
        }

    }
}

现在我无法理解如何将访客模式应用于集合 mCountries。我计划使用bulkInsertContentProvider方法插入整个列表,因为它比insert更快地工作。

我需要一个优雅的解决方案。

1 个答案:

答案 0 :(得分:0)

解决方案。

我自己找到了解决方案。我不需要访客模式。我刚刚实现了以下逻辑。

<强> JsonPasrer。

此类仅从JSON文件中读取数据。

public class JsoinParser {

    /**
     * Reads a JSON file to a string
     * 
     * @param fileName JSON file name
     * @return null if reading failed
     */
    private String readToString(String fileName) throws IOException {
        StringBuilder resultBuilder = new StringBuilder();
        String filePath = mContext.getExternalFilesDir(null).getAbsolutePath() + File.separatorChar + fileName;
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(filePath));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                resultBuilder.append(line);
            }
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    Log.e("%s", "Failed to close the BufferedReader instance");
                }
            }
        }
        return resultBuilder.toString();

    }

    public List<Organization> readOrgs() throws JSONException, IOException {
        JSONArray array = new JSONArray(readToString(FilesNames.ORGS));
        List<Organization> list = new ArrayList<JsonParser.Organization>();
        // TODO: read here and fill
        return list;
    }

    public List<Continent> readContinents() throws JSONException, IOException {
        JSONArray array = new JSONArray(readToString(FilesNames.CONTINENTS));
        List<Continent> list = new ArrayList<JsonParser.Continent>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            list.add(new Continent(object.getLong(ID), object.getString(NAME)));
        }
        return list;
    }

    public List<Country> readCountries() throws JSONException, IOException {
        JSONArray array = new JSONArray(readToString(FilesNames.COUNTRIES));
        List<Country> list = new ArrayList<JsonParser.Country>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            long id = object.getLong(ID);
            String name = object.getString(NAME);
            List<Long> orgsIds = new ArrayList<Long>();
            try {
                JSONArray orgs = object.getJSONArray(ORGS_IDS);
                orgsIds = new ArrayList<Long>();
                for (int j = 0; j < orgs.length(); j++) {
                    orgsIds.add(orgs.getLong(j));
                }
            } catch (JSONException e) {
                Log.v("%s", name + " is not a member of any international organizations");
            }

            long continentId = object.getLong(CONTINENT_ID);
            list.add(new Country(id, name, orgsIds, continentId));
        }
        return list;
    }

    /**
     * Common base class for all the entities read from JSON file. The entities are {@link Country},
     * {@link Organization}, and {@link Continent}
     * 
     * @author Red Planet
     * 
     */
    abstract class BaseEntity {

        String name;
        long id;
        List<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

        private BaseEntity(long id, String name) {
            this.id = id;
            this.name = name;
        }

        public long getId() {
            return id;
        }

        // Insert all the data within a transaction
        abstract public List<ContentProviderOperation> getOperations();

        public String getName() {
            return name;
        }
    }

    public class Country extends BaseEntity {

        private List<Long> orgsIds;
        private long continentId;

        public Country(long id, String name, List<Long> orgsIds, long continentId) {
            super(id, name);
            this.orgsIds = new ArrayList<Long>();
            this.orgsIds.addAll(orgsIds);
            this.continentId = continentId;
        }

        @Override
        public List<ContentProviderOperation> getOperations() {
            ContentValues values = new ContentValues();
            // TODO: fill ContentValues with the data which will be inserted
            return operations;
        }

    }

    public class Organization extends BaseEntity {

        private Organization(long id, String name) {
            super(id, name);
        }

        @Override
        public List<ContentProviderOperation> getOperations() {
            ContentValues values = new ContentValues();
            // TODO: fill ContentValues with the data which will be inserted
            return operations;
        }
    }

    public class Continent extends BaseEntity {

        private Continent(long id, String name) {
            super(id, name);
        }

        @Override
        public List<ContentProviderOperation> getOperations() {
            ContentValues values = new ContentValues();
            // TODO: fill ContentValues with the data which will be inserted
            return operations;
        }
    }
}

<强> JsonParserHelper。

此类获取由readX方法填充的数组并填充我的数据库。

public class JsonParserHelper {

    public void insert(Context context, List<? extends BaseEntity> entities)
            throws OperationApplicationException, RemoteException {
        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
        for (BaseEntity entity : entities) {
            operations.addAll(entity.getOperations());
        }
        context.getContentResolver().applyBatch(DatabaseProvider.AUTHORITY, operations);
    }

}