3

简单的问题。查看我的代码,我注意到在我的类或方法中多次声明了很多变量......例如:

public Long dbInsertCheckin(final String Class) {
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
...
}

public class SmashDataSource {
    final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    final SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
    final SimpleDateFormat timeFormat = new SimpleDateFormat("HHmm");
...
}

这让我想到,与其声明“dateformat”、“sdf”或“timeformat”或我在多个地方使用的其他内容,不如在我的应用程序类中全局声明这些,然后在任何地方引用它们是否更有意义我想喜欢

public class MyApp extends Application {
public final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public final SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
    public final SimpleDateFormat timeFormat = new SimpleDateFormat("HHmm");

并稍后在其他类中引用它们:

MyApp.dateformat
Myapp.sdf

从性能/内存使用的角度来看,这会更好吗?有什么理由不这样做吗?对我来说,似乎多次声明它们会消耗更多内存,而不是一次最终声明......但我不知道编译器是如何进行优化的。

4

5 回答 5

3

使用全局变量并没有错。通常避免使用它们以保持事物的灵活性和封装性。但是像工厂模式这样的一些设计模式很适合静态/全局类。它还避免了代码重复。

(但是我可能会避免使用我的Application类,所以我的全局字段仅在需要时使用,但这是一个实现细节。)

我可能会做这样的事情。它使事情保持灵活,同时也将事情放在一个地方,以便它们在您的应用程序中保持一致。

public class MyGlobals
{
    private static SimpleDateFormat dateFormat;


    public static SimpleDateFormat getDateFormat()
    {
        if(dateFormat== null)
        {
            dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        return dateFormat;

    }
}

然后你可以在其他类中使用它:

MyGlobals.getDateFormat();

====


以下是来自开发文档的一些信息:

http://developer.android.com/guide/faq/framework.html#3

对于短期共享复杂的非持久性用户定义对象,建议采用以下方法:

单例类

您可以通过使用单例来利用您的应用程序组件在同一进程中运行这一事实。这是一个设计为只有一个实例的类。它有一个名为 getInstance() 的静态方法,它返回实例;第一次调用此方法时,它会创建全局实例。因为所有调用者都获得相同的实例,所以他们可以将其用作交互点。例如,活动 A 可以检索实例并调用 setValue(3);稍后的活动 B 可能会检索实例并调用 getValue() 以检索最后设置的值。

公共静态字段/方法

使数据可跨活动/服务访问的另一种方法是使用公共静态字段和/或方法。您可以从应用程序中的任何其他类访问这些静态字段。要共享一个对象,创建对象的活动会设置一个静态字段以指向该对象,任何其他想要使用该对象的活动只需访问该静态字段。

对象弱引用的 HashMap

您还可以使用弱引用的 HashMap 到具有长键的对象。当一个 Activity 想要将一个对象传递给另一个 Activity 时,它只需将该对象放入映射中并通过 Intent Extras 将密钥(这是一个基于计数器或时间戳的唯一 Long)发送给接收者 Activity。接收者活动使用此键检索对象。

持久对象

即使应用程序似乎继续运行,系统也可能会选择终止其进程并稍后重新启动它。如果您有数据需要从一个活动调用持续到下一个活动调用,则需要将该数据表示为在通知活动可能会消失时由活动保存的状态。

对于共享复杂的持久性用户定义对象,建议采用以下方法:

Application Preferences
Files
contentProviders
SQLite DB

如果共享数据需要跨应用程序进程可能被终止的点保留,则将该数据放在持久存储中,如应用程序首选项、SQLite DB、文件或内容提供程序。有关如何使用这些组件的更多详细信息,请参阅数据存储。

于 2012-09-26T17:13:25.857 回答
1

是的,在一个地方定义它们是个好主意——不仅因为它更干净,而且因为这样在全球范围内更改它们更容易,而无需遍历整个代码库。就个人而言,我会选择这样的东西:

public static final LONG_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

但是,在这种特殊情况下,您需要小心,因为SimpleDateFormat对象不是线程安全的。这意味着,如果您要在整个应用程序中共享一个实例,则需要采取一些额外的步骤来避免并发问题。有关详细信息,请参阅以下内容之一:

SimpleDateFormat 线程安全

证明 SimpleDateFormat 不是线程安全的

“Java DateFormat 不是线程安全的”这会导致什么?

于 2012-09-26T17:07:34.223 回答
1

这一切都归结为您需要什么以及您当前的环境。

如果您能负担得起一点重构,恕我直言,最好的方法是创建一个包含所有此类变量的上下文类。您可以利用重构会话,甚至将其他配置参数移动到该类并将其作为 Singleton:

public class MyApplicationContext {
    //Constants and other global variables (I'd make the strings global, rather than
    //The time formats in this case.
    public final String TIME_FORMAT = "HHmm";

    //Context variables (taken from your source of choice)
    private String someConfigurationPath = "...";

    //Getters & Setters
}
于 2012-09-26T17:07:58.450 回答
1

全局变量可以作为代码异味的指标。

也许可以在使用相同简单日期格式的不同位置找到一种模式。这可能是重构代码并将所有公共部分移动到一个地方的机会,例如组合成一个新方法(如 printDate(aDate)),而不是 SimpleDateFormat 的多个实例化和进一步包围的重复代码。

于 2012-09-28T20:32:32.243 回答
0

我会,这完全取决于会发生什么变化,但是如果您将所有配置变量都作为静态变量,您可以只在一个地方更改日期格式,而其他所有的都不需要更改。

有时对于日期格式之类的内容,最好将日期字符串放在 stings.xml 文件中,以便您可以根据每个国家/地区/语言更改日期格式。

于 2012-09-26T17:00:30.203 回答