通用或抽象类?

时间:2013-02-26 19:35:12

标签: java oop generics abstract-class

我的应用程序中有三个类UserGroupCompany,它们不属于同一个继承树,正如其名称所示。每个类都有一个构造函数,它接收许多(不同的)参数,即:User(String name, String password, int type)Group(String name, String name)Company(String name, int employees, boolean isValid)。每个构造函数所需的参数的数量对于所有类都不相同。我创建了一个类ReadDataFromFile来读取txt文件中的一些数据,并创建新的对象将数据作为参数传递给上面的构造函数。除了一个创建对象的方法之外,这个类的代码对于每种类型显然都是相同的。因此,创建三个不同的类是不合适的,但我最好以更好的设计方法为目标。

我的问题是,在这种情况下,适当的设计是一个Generic类,还是一个抽象类,并在其子类中实现一个不同createObject()的方法,假设来自txt文件的必要数据被放入到每个类型的长度不同的String数组中。我想按照Generic类的方法:class ReadDataFromFile<T>{},但我找不到如何处理不同的类型,因为每个类都需要调用不同的构造函数。我应该检查instanceof的类型吗?我应该将每个对象的类传递给方法吗?或者,还有更好的方法?

4 个答案:

答案 0 :(得分:2)

不明白为什么你把这个问题提出为“抽象泛型”,看起来常见的解决方案都是。

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]);
  }
}

答案 1 :(得分:0)

根据条件创建对象,例如“instanceof”验证:

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

答案 2 :(得分:0)

我想我会选择抽象设计,例如使用抽象工厂模式。

答案 3 :(得分:0)

答案简而言之,既不是:)是的,你确实需要抽象,但它不一定是你似乎倾向于的子类形式。 Prefer composition over inheritance?

答案很长:)我完全不了解您的域名,但是根据您所写的内容,我假设您有三个文件,users.txt,groups.txt和companies.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应该只读取文件中的数据,并将数据传递给另一个类,以实现一个策略来处理它。

这就是上述设计试图做的事情 - 将问题分开。