안드로이드 프로젝트를 진행하다 보면 일부 코드를 재사용하기 위해 BaseClass를 상속받아 사용하는 경우가 있었습니다. BaseActivity, BaseFragment, BaseViewModel, BaseListAdapter, BaseDialog 등등..
소규모 프로젝트에서는 다소 편리할 수도 있지만, 이는 생산성이 떨어지는 안티패턴입니다. 그 이유는 다음과 같습니다.
open
키워드를 사용해야합니다.)1. 상속(Inheritance)
다른 곳으로 부터 클래스를 얻는 관계입니다. 예를 들자면 개(Dog)는 동물(Animal)이다 처럼 is-a
로 표현합니다. 객체지향 프로그래밍에서는 다중 상속을 금지하고 있습니다.
2. 연관(Association)
한 쪽이 다른 한쪽의 일부분인 관계입니다. 예를 들어 엔진을 가지고 있는 자동차 처럼 has-a
로 표현합니다.
Kotlin의 Delegation을 사용하면 됩니다. 특정 클래스가 필요로 하는 기능들만을 각각 위임하는것이죠.
예를들어, 퍼미션을 요청하는 메서드를 액티비티에 위임하고 싶다면 다음과 같이 작성합니다.
interface PermissionDelegation {
fun requestPermission(context: Context, permission: String)
}
class PermissionDelegationImpl : PermissionDelegation {
override fun requestPermission(context: Context, permission: String) {
val permissionListener: PermissionListener = object : PermissionListener {
override fun onPermissionGranted() {
//권한요청성공
}
override fun onPermissionDenied(deniedPermissions: List<String>) {}
}
TedPermission.with(context)
.setPermissionListener(permissionListener)
.setRationaleMessage(context.resources.getString(R.string.permission_3))
.setDeniedMessage(context.resources.getString(R.string.permission_1))
.setPermissions(Manifest.permission.ACCESS_FINE_LOCATION)
.check()
}
}
이렇게 하면 확연히 책임이 분리된 것을 볼 수 있습니다.
이제 Kotlin의 by
키워드를 사용하여 간단하게 퍼미션 요청기능을 위임할 수 있습니다.
class MainActivity : AppCompatActivity(),
PermissionDelegation by PermissionDelegationImpl() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
...
}
...
}
이렇게 필요한 기능들을 각각 위임하게 된다면, 책임이 분리되어 간결해지고 디버깅도 쉬워집니다.
https://kotlinlang.org/docs/delegation.html
https://prokash-sarkar.medium.com/delegation-pattern-an-effective-way-of-replacing-androids-baseactivity-with-native-kotlin-support-b00dee007d69
https://medium.com/@mobidroid92/hello-delegates-goodby-base-classes-c8aeedc2b855