Android: шаблон репозитория, что является лучшим решением для создания объекта? - PullRequest
2 голосов
/ 27 марта 2019

Этот вопрос касается дизайна ООП (класса / интерфейса).

Я занимаюсь разработкой библиотеки Android, а не приложения.Приложение будет использовать эту библиотеку.Эта библиотека разработана по шаблону репозитория.

Один репозиторий и 2 источника данных (локальный, удаленный).

Поскольку локальный источник данных использует «SharedPreference», ему необходим Context.

Ниже представлен интерфейс моего репозитория и реализуются.

interface MyRepository {

    fun create(String data)

    fun get(key: String): String
}

class MyRepositoryImpl(
        private val localDataSource: LocalDataSource,
        private val remoteDataSource: RemoteDataSource
): MyRepository {

    fun create(String data) {
        localDataSource.create(data);
        remoteDataSource.create(data);
    }

    fun get(key: String): String {
        // temp code
        return localDataSource.get(key)
    }

    companion object {

        private var instance: MyRepository? = null

        fun getInstance(context: Context): MyRepository {
            if (instance == null) {
                val localDataSource: LocalDataSource = LocalDataSourceImpl.getInstance(context)
                val remoteDataSource: RemoteDataSource = RemoteDataSourceImpl.getInstance()
                instance = MyRepositoryImpl(localDataSource, remoteDataSource)
            }

            return instance!!
        }

    }
}

MyRepositoryImpl реализован по шаблону Singleton.Потому что это должно быть использовано в любом месте приложения.Таким образом, разработчики приложения должны иметь возможность получить экземпляр MyRepository, например:

val myRepository = MyRepositoryImpl.getInstance(context)
val data = myRepository.get("key")

Но выглядит странно ... "getInstance (context)".Я думаю, что это не очень хороший подход.Есть еще какой-нибудь умный дизайн, пожалуйста?

1 Ответ

1 голос
/ 27 марта 2019

В Kotlin вы можете использовать ключевое слово object для реализации одноэлементного шаблона потокобезопасным способом.Нет необходимости определять метод getInstance в вашем объекте-компаньоне.Просто определите ваш MyRepository класс как объект, как показано ниже.Перегрузив оператор вызова, вы сможете передать контекст, полезный для инициализации ваших экземпляров localDataSource и remoteDataSource.

object MyRepository  {
    private lateinit var localDataSource: LocalDataSource
    private lateinit var remoteDataSource: RemoteDataSource

    operator fun invoke(context: Context): MyRepository {
        //...
        localDataSource = LocalDataSourceImpl.getInstance(context)
        remoteDataSource = RemoteDataSourceImpl.getInstance(context)
        return this
    }
}

Этот код будет скомпилирован в следующий код Java (блок статической инициализации):

public final class MyRepository {
   public static final MyRepository INSTANCE;

   private SomeSingleton() {
      INSTANCE = (MyRepository) this;
   }

   static {
      new MyRepository();
   }
}

Таким образом, вы сможете получить экземпляр вашего класса MyRepository, напримеробычный необъектный класс, просто выполнив:

val repo = MyRepository(this) // this is your context

Каждый метод, который вы определяете в классе MyRepository, будет доступен так же, как статический метод Java, так что вы сможете вызыватьэто как:

MyRepository.myMethod()

Подробнее здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...