2010-05-03 3 views
3

Я рассматриваю возможность создания одноэлементной оболочки для Контекста, поэтому мои объекты модели, если необходимо, могут открывать и читать из соединения с базой данных. Мои объекты модели не имеют доступа к Context, и я хотел бы избежать необходимости передавать ссылку на объект Context от объекта к объекту.Singleton wrapper for Context

Я планировал разместить в этом одиночном поле ссылку на Context, возвращенный Application.getApplicationContext(). Этот одноэлементный объект будет инициализирован в моем обычном экземпляре Application, прежде чем что-нибудь еще понадобится или будет иметь возможность использовать его.

Может ли кто-нибудь думать о причине не это?

ответ

0

Я не уверен, что я получаю вашу идею, но вот то, что работает для меня:

public class MyApp extends Application { 

private static MyApp instance; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     instance = this; 
     // ... 
    } 

    public static MyApp getInstance(){ 
     return instance; 
    } 

    // misc helper methods 
} 
+0

Я вложил свою реализацию этого в ответ на то, что я мог иметь форматирование и разрывы строк. Мой класс делает примерно то же, что и ваш. – skyler

2

Я хотел бы призвать вас думать о том, каким причинам у вас есть для не прохождения ссылки приложения контекст в ваши объекты модели.

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

  • Как одиночные лимиты ограничивают вашу способность правильно тестировать ваше приложение.
  • Singletons скрывает зависимости между различными объектами в коде - вы не можете определить зависимости от проверки интерфейсов.
  • У вас нет реального контроля над временем жизни одного синглета, он может существовать в течение всего срока службы вашего приложения. Вы действительно хотите потенциально поддерживать соединение с БД на всю жизнь своего приложения?
  • Безопасность потока вашего синглтона.

Если у вас есть веские причины не передавать ссылку на контекст другим частям вашего приложения, то, возможно, вам стоит рассмотреть некоторые другие шаблоны: фабрика может быть одним из возможных решений, а другое - сервисом.

+0

Спасибо за ваш ответ! К лучшему или к худшему я не использую никаких модульных тестов на данный момент, поэтому я проигнорирую ваше первое предупреждение. Скрытые зависимости, да, это может быть проблемой, но я думаю, что это относится и к другим шаблонам. Что касается времени жизни, я использую только ссылку на Контекст, а не на БД, а в приложении onDestroy() я могу выполнить любую очистку для обертки. И к третьему предупреждению я применил надлежащую синхронизацию с этой оболочкой. Что касается сервиса, я думаю, что привязка для этого немного перегружена, и пользовательская фабрика не может вернуть Контекст приложения. – skyler

+0

Это не означает, что ваши предупреждения недействительны, скорее, я думаю, что могу с уверенностью объяснить их, по большей части. К сожалению, ограничение персонажа может сделать ответы похожими и недружелюбными! – skyler

+0

Без проблем! Вы четко подумали о проблемах и довольны тем, что ограничения использования синглонов - это цена, которую вы счастливы заплатить в этом случае (а эй-все имеет цену, правда?) Я не полностью против одиночных игроков каким-либо образом, но я видел из первых рук тот ущерб, который их ненадуманное использование может иметь (в течение более чем одного случая). –

0

Вставить здесь, чтобы сохранить форматирование.

public class ContextContainer 
{ 
    private static boolean initialized; 
    private static Context context; 

    private ContextContainer() 
    { 
     // 
    } 

    public static synchronized void setApplicationContext(Context context) 
    { 
     if (!initialized) { 
      ContextContainer.context = context; 
      initialized = true; 
     } else { 
      throw new RuntimeException("ApplicationContext has already been set!"); 
     } 
    } 

    public static synchronized Context getApplicationContext() 
    { 
     return context; 
    } 
}
+0

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