Как реализовать SOLID в разделении интерфейса - PullRequest
1 голос
/ 23 марта 2020

У меня есть interface, например:

interface ClientRequestListener {
    fun onLoadStub(name: String)
    fun onClientNeeded(id: String, email: String)
}

Но тогда, когда я реализую его в одном классе, мне просто нужен onClientNeeded, есть ли способ избежать необходимости переопределять эти два метода? Я пытался создать другой интерфейс, который расширяет этот, но все еще просит меня реализовать методы ..

Уточнение

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

РЕДАКТИРОВАТЬ

fun doSomeMagic(name: String, clientRequestListener: ClientRequestListener? = null) =
    LibraryRequest.getClient(name)
        .withListener(object : LibraryInterface() {
            override fun onLoadStub(name: String) {
                clientRequestListener?.onLoadStub(name)
            }

            override fun onClientNeeded(id: String, email: String) {
                clientRequestListener?.onClientNeeded(id, email)
            }
        })

Поэтому, когда я использую этот метод, я делаю что-то вроде этого:

doSomeMagic("Charls", object : ClientRequestListener {
  override fun onClientNeeded(name: String) {
    //I'm not doing nothing here
  }

  override fun onClientNeeded(id: String, email: String) {
    //Do something with the id and email
  }
})

Итак, что я хотел бы сделать, это что-то только для вызова onClientNeeded там вместо них обоих.

Ответы [ 2 ]

1 голос
/ 23 марта 2020

Здесь вы можете изменить несколько параметров:

a) Вы можете создать абстрактный класс, который обеспечит реализацию по умолчанию (пустую) реализации ненужного метода и заставит вас переопределить только тот метод, который вы ' Вы заинтересованы в:

abstract class AbsClientRequestListener {
    override fun onLoadStub(name: String) {
    }
    abstract fun onClientNeeded(id: String, email: String)
}

b) Если у вас есть иерархия классов, вы можете предоставить реализацию по умолчанию в вашем базовом классе и оставить onClientNeeded невыполненной для подклассов:

interface ClientRequestListener {
    fun onLoadStub(name: String)
    fun onClientNeeded(id: String, email: String)
}

abstract class BaseClient: ClientRequestListener {
    override fun onLoadStub(name: String) {
        // Leave empty
    }
}

class Client:BaseClient() {
    override fun onClientNeeded(id: String, email: String) {
        // Put required implementation
    }
}

c) Или вы можете просто использовать этот интерфейс как есть и каждый раз предоставлять пустую реализацию:)

РЕДАКТИРОВАТЬ

В вашем конкретном случае c Вы можете добавить класс ClientRequestListenerAdapter:

abstract class ClientRequestListenerAdapter : ClientRequestListener {
    override fun onLoadStub(name: String) {
    }
}

И использовать его следующим образом:

doSomeMagic("Charls", object : ClientRequestListenerAdapter {
  override fun onClientNeeded(id: String, email: String) {
    //Do something with the id and email
  }
})

Никаких изменений в функции doMagic не требуется.

1 голос
/ 23 марта 2020

Вы должны предоставить реализацию для метода onLoadStub в классе abastract. Это значение должно просто генерировать исключение UnsupportedOperationException. Затем вы можете расширить этот абстрактный класс в своих реализациях.

abstract class AbstractClientRequestListener : ClientRequestListener {
override fun onLoadStub(name: String) {
    throw UnsupportedOperationException("unsupported")
    }
}

class ClientRequestListenerImpl : AbstractClientRequestListener() {
    override fun onClientNeeded(id: String, email: String) {
       TODO("not implemented")
    }
}
...