【译】Android 噩梦 😱 之 BaseActivity

·  阅读 12975

原文: medium.com/gitconnecte…

我刚入行 Android 开发的时候,还没有 Fragments, RecyclerViews, ViewModels, 和 Coroutines(协程)。技术组件更新换代,但是唯一不变的是:BaseClass,存在于项目中的各种基类🥶

如果你没有见过 BaseActivity, BaseFragment 或者 BaseViewModel ,那你一定是幸运的🌟。

这些 BaseClass 基类对 “ (Don’t Repeat Yourself)禁止重复 ”这一原则的错误应用。

“Don’t repeat yourself” (DRY) 是软件开发中的一个原则,旨在使用抽象和数据标准化来减少软件开发中的重复工作。

一个常见的场景:当你需要在你的 App 中做追踪日志分析,或者需要在每个 Acticity 中注册一个 BroadcastReceiver 来发通知。

class BaseActivity: AppCompatActivity() {

    private lateinit var logoutReceiver: BroadcastReceiver

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        logoutReceiver = LogoutReceiver()

        registerReceiver(logoutReceiver, IntentFilter("ACTION_LOGOUT"))

    }

    

    override fun onStart() {

        super.onStart()

        traceEvent("Activity started")

    }



    override fun onStop() {

        traceEvent("Activity stopped")

        super.onStop()

    }



    private fun traceEvent(event: String) {

        //MyAnalytics.newEvent(event)

    }

    

    inner class LogoutReceiver: BroadcastReceiver() {

        override fun onReceive(context: Context?, intent: Intent?) {

            finish()

        }

    }

}
复制代码

上述代码看起来没啥问题,每个继承 BaseActivity 的子类不需要新写代码,通过继承具备了父类追踪日志和退出登录的能力。

但是不是每个 Activity 我都需要追踪日志和退出登录,对于这些 Activity 这两个功能就是多余的。

有人说我可以通过一个 flag 标记这两个功能是否开启,这是错误❌的做法。

我们可以使用委托模式( Delegation ,利用 Kotlin(Java 也可以,需要写一些额外的代码)和 Android Lifecycle 组件的摆脱 BaseClass 这个噩梦。

委托模式(delegation pattern) 软件设计模式 中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如 状态模式 策略模式 访问者模式 本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用 聚合 来替代 继承 ,它还使我们可以模拟 mixin 。——维基百科

我们可以创建一个接口,将实际实现交给委托类。得益于 Lifecycle 组件,我们可以将我们的逻辑和生命周期绑定。

我们只需要 2 步:

  1. 为每一个 Feature 创建它的接口和实现类。(遵循单一职责的原则)
  2. Activity/Fragment 实现接口,将接口的实现交给委托的实现类并且绑定 lifecycle 的生命周期
class MyActivity:

    AppCompatActivity(),

    AnalyticsDelegate by AnalyticsDelegateImpl(),

    LogoutDelegate by LogoutDelegateImpl()

{

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        

        registerAnalytics(lifecycle)

        registerLogout(this)

    }

}
复制代码

接口和委托实现类:

interface AnalyticsDelegate {

    fun registerAnalytics(lifecycle: Lifecycle)

}



class AnalyticsDelegateImpl: AnalyticsDelegate, DefaultLifecycleObserver {

    override fun registerAnalytics(lifecycle: Lifecycle) {

        lifecycle.addObserver(this)

    }



    override fun onStart(owner: LifecycleOwner) {

        traceEvent("Activity started")

    }



    override fun onStop(owner: LifecycleOwner) {

        traceEvent("Activity stopped")

    }



    private fun traceEvent(event: String) {

        //MyAnalytics.newEvent(event)

    }

}
复制代码
interface LogoutDelegate {

    fun registerLogout(activity: AppCompatActivity)

}



class LogoutDelegateImpl: LogoutDelegate, DefaultLifecycleObserver {

    private lateinit var activity: AppCompatActivity



    override fun registerLogout(activity: AppCompatActivity) {

        this.activity = activity

        this.activity.lifecycle.addObserver(this)

    }



    private lateinit var logoutReceiver: BroadcastReceiver

    override fun onCreate(owner: LifecycleOwner) {

        logoutReceiver = LogoutReceiver()

        activity.registerReceiver(logoutReceiver, IntentFilter("ACTION_LOGOUT"))

        //unregister missing for keeping the sample code smaller!

    }



    inner class LogoutReceiver: BroadcastReceiver() {

        override fun onReceive(context: Context?, intent: Intent?) {

            activity.finish()

        }

    }

}
复制代码

你有使用过委托模式吗?在评论中告诉我你有没有被 BaseActivity 折磨过!😎

分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改