2013-02-26 4 views
1

У меня в моем приложении три класса User, Group, Company, которые не принадлежат к одному и тому же дереву наследования, как показывают их имена. Каждый класс имеет конструктор, который получает несколько (разных) параметров, например: User(String name, String password, int type), Group(String name, String name), Company(String name, int employees, boolean isValid). Число парааметров, которое требуется каждому конструктору, не одинаково для всех классов. Я создал класс ReadDataFromFile, чтобы прочитать некоторые данные из txt-файлов и создать новые объекты, передающие данные в виде paaraameters для указанных выше конструкторов. Код этого класса, по-видимому, одинаковый для каждого типа, за исключением одного метода, который создает объекты. Следовательно, нецелесообразно создавать три разных класса, но мне лучше ориентироваться на лучший подход к дизайну.Общий или абстрактный класс?

Мой вопрос заключается в том, является ли подходящий дизайн по этому случаю общим классом или абстрактным классом и реализует в своем подклассе один метод, который отличается createObject(), предполагая, что необходимые данные, поступающие из файла txt, помещаются в строку массив с различной длиной для каждого типа. Я хотел бы следовать подходу Generic class: class ReadDataFromFile<T>{}, но я не могу найти, как я должен обрабатывать разные типы, поскольку каждый из них требует вызова другого конструктора. Должен ли я проверить тип с instanceof? Должен ли я передать методу класс каждого объекта? Или есть лучший способ?

+0

Возможно, вы исправляете то, что не сломано. – vijay

ответ

2

Не понимаю, почему вы задали вопрос как «абстрактное или generic« похоже, что общим решением будет оба.

public abstract class ReadFromFile<T> { 

    public T readFile(File file) { 
    String[] rawInput = doSomeStuffCommonToAll(); 
    return constructObject(rawInput); 
    } 

    abstract T constructObject(String[] rawInput); 
} 

public class UserFileReader extends ReadFromFile<User> { 

    @Override 
    User constructObject(String[] rawInput) { 
    return new User(rawInput[0], rawInput[1], Integer.parseInt(rawInput[2]); 
    } 
} 
+0

Это кажется хорошим решением. Я попробую. Я думал, что если бы это был способ проложить это только с помощью дженериков, чтобы избежать создания четырех классов. – arjacsoh

+0

Generics - это функция времени, используемая для компиляции только в Java. Они не могут ничего решить, чтобы решить проблему выбора того, какой путь кода выполнить на основе * во время выполнения * входов. – Affe

0

Создание ваши объекты в зависимости от условий, например, «InstanceOf» проверка:

if (objectData instanceof User){ 
User = new User(); 
user.setName(objectData.getString(1)); 
} //... 
+0

Что интерпретирует исходный ввод для создания 'objectData' в качестве экземпляра User? – Affe

0

Я думаю, я бы выбрал абстрактный дизайн и, например, использовать абстрактный узор фабрики.

0

Ответ Короче говоря, ни :) Да, вы действительно должны абстракцию, но он не должен быть в форме подклассов вы, кажется, склоняется к. Prefer composition over inheritance?

Долгий ответ :) Я точно не знаю ваш домен, но из того, что вы написали, я предполагаю, что у вас есть три файла: users.txt, groups.txt и company.txt с общим форматом, но с разные данные - что-то вроде CSV. Таким образом, вы можете достичь абстракции через композицию, сделав что-то вроде этого, что должно проиллюстрировать суть, даже если мои предположения ошибочны.

public class FileReader { 
    public static void read(File f, RowHandler rowHandler) { 
     //read each line, convert its contents to a map, and pass it to rowHandler 
    } 
} 

где

public interface RowHandler { 
    void handle(Map<String,String> row); 
} 

Это означает, что вы разделяете чтение и разбор каждой строки из того, что делать, чтобы с каждой проанализированной линии.

Чтобы создать пользователя объекты, которые вы можете сделать:

public class UserConstructor implements RowHandler { 
    private List<User> users = new ArrayList<User); 

    public void handle(Map<String,String> row) { 
     users.add(new User(row.get("name"), row.get("password"), Integer.parseInt(row.get("type))); 
    } 

    public List<User> getUsers() { 
     return users; 
    } 
} 

А потом соединить все это, делая

UserConstructor uc = new UserConstructor(); 
FileReader.readFile(new File("users.txt), uc); 
List<User> users = uc.users(); 

используется имя класса ReadDataFromFile. Это название предлагает одну цель, но ваш вопрос предполагает, что вы смешиваете в себе другую проблему - поэтому он читает файлы и создает объекты. ReadDataFromFile должен просто читать данные из файла и передавать данные в другой класс, чтобы реализовать стратегию, чтобы что-то с ней сделать.

То, что делает вышеуказанный проект, - держать проблемы отдельно.

Смежные вопросы