【问题标题】:Best practice in android class constructorandroid类构造函数的最佳实践
【发布时间】:2014-01-17 18:01:17
【问题描述】:

我应该在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.

哪一种方法是正确的?

【问题讨论】:

  • 所有都是“正确的”,这是广泛的。但public Compilation(Cursor c) 是我的方式。

标签: java android class constructor dependencies


【解决方案1】:

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

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

如果您将构造函数参数从 Class 替换为 Interface 并因此创建我们称之为 Dependency injection 的东西,第二个会更好。但是有更好的方法在 Android 上进行依赖注入(例如,查看 @ 987654322@)

在我看来,第三个是最合适的,因为您不会创建任何依赖项。也许为了简化此类类的创建(并使代码更“企业化”),您可以创建一个工厂类来创建编译类的实例(更多关于这个here

然而,最后这不是关于 Android 最佳实践的问题,而是关于软件设计决策的问题,这在很大程度上取决于您要做什么!

【讨论】:

    【解决方案2】:

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

    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
    }
    
    }
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我实际上并没有实例化数据库,它是一个单例,从我正在调用的 getInstance() 方法中可以看出。
      【解决方案4】:

      这在一定程度上取决于您的数据库的实现 - 如果您使用的是内容提供程序,等等。

      从它们将起作用的角度来看,所有提供的示例都是“正确的”。那说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();  
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-17
        • 2017-09-13
        • 2022-11-04
        • 1970-01-01
        • 1970-01-01
        • 2021-02-13
        • 2010-11-14
        相关资源
        最近更新 更多