100 lines
2.7 KiB
Plaintext
100 lines
2.7 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Kotlin features language support for the delegator pattern using `by` clauses.
|
|
Because this is a built-in language feature, it should be used
|
|
as an idiom instead of resorting to custom idioms.
|
|
|
|
=== What is the potential impact?
|
|
|
|
==== Readability and Understanding
|
|
|
|
This change makes it easier to understand the code
|
|
because this is how delegation is intended to be used in Kotlin.
|
|
When developers share common standards and idioms, they need to spend less effort understanding each other's code.
|
|
|
|
==== Code Redundancy
|
|
|
|
Using a built-in language feature or a standard API is always better than a custom implementation,
|
|
because the reimplementation of something that already exists is unnecessary.
|
|
|
|
== How to fix it
|
|
|
|
Remove all `override` functions from your class that delegate
|
|
to the function with the same signature in the delegee.
|
|
In the class header, add a `by` clause to delegate the entire interface to the delegee.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,kotlin]
|
|
----
|
|
interface Network { fun connect() }
|
|
|
|
class PoorNetwork : Network {
|
|
override fun connect() { println("cannot connect") }
|
|
}
|
|
|
|
class GoodNetwork : Network {
|
|
override fun connect() { println("connected") }
|
|
}
|
|
|
|
interface Graphics { fun render() }
|
|
|
|
class Nvidia : Graphics {
|
|
override fun render() { println("Neat 3D world") }
|
|
}
|
|
|
|
class AsusCardFrom2010 : Graphics {
|
|
override fun render() { println("~8 fps") }
|
|
}
|
|
|
|
abstract class OS : Network, Graphics
|
|
----
|
|
|
|
[source,kotlin,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
class Linux : OS() {
|
|
private val network = GoodNetwork()
|
|
override fun connect() = network.connect() // Noncompliant, explicit function delegation
|
|
private val graphics= Nvidia()
|
|
override fun render() = graphics.render() // Noncompliant, explicit function delegation
|
|
// ...
|
|
}
|
|
|
|
class Windows : OS() {
|
|
private val network = PoorNetwork()
|
|
override fun connect() = network.connect() // Noncompliant, explicit function delegation
|
|
private val graphics = AsusCardFrom2010()
|
|
override fun render() = graphics.render() // Noncompliant, explicit function delegation
|
|
// ...
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,kotlin,diff-id=1,diff-type=compliant]
|
|
----
|
|
class Linux:
|
|
OS(),
|
|
Network by GoodNetwork(), // Compliant, interface delegation using `by`
|
|
Graphics by Nvidia() // Compliant, interface delegation using `by`
|
|
{
|
|
// ...
|
|
}
|
|
class Windows:
|
|
OS(),
|
|
Network by PoorNetwork(), // Compliant, interface delegation using `by`
|
|
Graphics by AsusCardFrom2010() // Compliant, interface delegation using `by`
|
|
{
|
|
// ...
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* https://kotlinlang.org/docs/delegation.html[Kotlin Docs, Delegation]
|
|
|