android类构造函数的最佳实践

时间:2014-01-17 18:01:17

标签: java android class constructor dependencies

我应该在android中初始化我的类的正确方法是什么,该类名为Compilation,并且它的所有值都在db中。

我可以做以下事情:

1

public Compilation(int id)
{
    // get db singleton here and fill all values
    // however I feel this is bad OO because nobody knows I am doing this
}

2

public Compilation(int id, SQLiteDatabase db)
{
    // use the provided db to get the info
    // however now all calling classes will have to get the db for me
}

3

// get all compilations at once
SQLiteDatabase db = DatabaseHelper.getInstance().getReadableDatabase();
Cursor c = db.rawQuery("SELECT * FROM Compilation", null);

while(c.moveToNext())
{
    // get all params here
    Compilation comp = new Compilation (a,b,c,d,e);
}

public Compilation(a,b,c,d,e)
{
    // just assign all the values given to private vars
}

The problem I see with this is that now the Compilation class is no longer so self contained, it needs another class to initialise it.

哪一个是正确的方法呢?

4 个答案:

答案 0 :(得分:1)

软件设计的一般规则告诉我们,我们应该创建对软件系统其他部分具有最小依赖性的类。这样我们最终得到了可以重复使用的类。

您提出的第一个替代方案是最差的,因为它会对一个特定的数据提供程序(sqlite)产生非常严格的依赖关系。维护这样的类可能是一场噩梦(想象一下Android的下一个版本将带有sqlite或mysql :)并且你想切换到mysql)

如果要将构造函数参数从类替换为接口,从而创建一些我们称之为Dependency injection的东西,那么第二个更好一些。但是有更好的方法在Android上进行依赖注入(请查看例如Dagger

第三个似乎是最合适的,因为你没有创造任何依赖。也许为了简化这些类的创建(并使代码更加“企业”),你可以创建一个工厂类来创建编译类的实例(更多关于这个here

最后,这不是关于Android最佳实践的问题,而是关于软件设计决策的问题,这些决策高度依赖于您要做的事情!

答案 1 :(得分:1)

您的所有选项都是正确的,但我认为基于工厂的方法可以正常使用。我在不同的场合使用它。我刚刚写下了这种替代方法的骨架。

public class CompilationFactory
{

// DB instance and/or cache implementation (HashMap based or via 3rd party lib)

static 
{
    // DB init stuff here 
    // if your app logic allows it you can also cache Compilation to avoid 
    // reading the DB multiple times
}

public static Compilation compilationForId(int id)
{
    // either read your Compilation from the DB or from the precomputed cache
}

}

答案 2 :(得分:0)

我不会这样做,我会使用一个空构造函数,然后使用一个Application(http://developer.android.com/reference/android/app/Application.html)并从Application中为我自己提供数据库,这样我就不必继续实例化了。如果你正在做一个学校项目,可能会太先进,但是啊..

答案 3 :(得分:0)

这在很大程度上取决于数据库的实现 - 如果您正在使用内容提供商等等。

从它们起作用的角度来看,所有提供的示例都是“正确的”。说3号对我来说是个红旗。如果没有进一步的代码来澄清你冒险不止一次调用“getReadableDatabase”,这是不可能的。

除此之外,很难确切知道在这里推荐什么。有很多方法可以做到这一点,根据你的项目性质,它们对你来说可能有些过分。

我打算在假设您有一个管理编译的类的情况下进行操作。在这种情况下,类似的东西和简单易懂的东西如下:

public class CompliationManager() {

    private ArrayList<Compilation> myCompilations = new ArrayList<Compilation>();
    SQLiteDatabase db; 
    public CompilationManager() {
     db = DatabaseHelper.getInstance().getReadableDatabase();
    }
    public void loadCompliations() {

      Cursor c = db.rawQuery("SELECT * FROM Compilation", null);
      while(c.moveToNext()) {
         Compilation comp = new Compilation(c);
         myCompilations.add(comp);
      }    
      c.close();
    }    

}


public class Compilation() {

    public Compilation(Cursor c) {
      // do the actual retrival, setting of fields etc...
      getCompilationFromCursor();  
    }

}