【问题标题】:Android modules and code orginizingAndroid 模块和代码组织
【发布时间】:2018-01-08 11:25:13
【问题描述】:

假设有人说你的应用中必须有这些模块,

  1. 如果用户已经注册,用户可以登录
  2. 用户可以发送消息
  3. 用户可以退出

他们所说的模块是什么意思 他们可以说您的应用程序必须具有这些功能,我理解模块是您的应用程序的一个组件,您可以独立构建、测试或调试。模块包含应用程序的源代码和资源。

我的问题是,如果他们这样说,那么我该如何以专业的方式组织我的代码?我是否必须为这些功能中的每一个制作单独的包?或者我必须为每个功能制作单独的模块,我对代码的组织感到困惑

【问题讨论】:

  • 仅在绝对需要时才将项目拆分为模块。对于像 Facebook 这样的大型应用程序来说这可能是有意义的,但对于 95% 的应用程序来说,单个模块就可以了,而且您不会遭受多个模块带来的开销。至于组织其余代码,this is a great article for inspiration——通常,按功能而不是按层打包(即登录将有一个包,消息将有一个包)将使您的代码库更容易导航。
  • 所以只有单个包中的类可以做到这一点?还是分开包装?我在问题中描述的功能只是示例,我们将在哪里需要包
  • 那么单元测试呢,我们如何组织我们的代码以便它可以轻松进行单元测试?
  • 我假设在需求 must have these modules in you app 中,术语 modul 仅表示 menu itemuser storyfeature 但不是作为实现和代码组织细节的模块,其中 lib/ jar/dll/android-studi-modul 代码必须编译进去。

标签: java android optimization module packages


【解决方案1】:

你需要做三件相当简单的事情。他们每个人都需要一个视图,有两个实体(用户和消息),并且会有一些帮助类或更多。这听起来像不到 10 个类。

这就像有 10 份文书工作。你会为 10 张纸买多少个组织者?你会把组织者放在几个柜子里?

就是这样。 KISS。只要项目很小,将所有东西都放在一个包中是最实用的。编写单元测试可以帮助您限制依赖关系,以便您可以在代码增长时将代码拆分为包甚至模块。将所有东西放在一个地方并不会阻止您进行测试或其他任何事情。没关系,当项目增长时它会变得很糟糕,因为没有可见的结构。发生这种情况时,您会更好地了解如何进行拆分。

【讨论】:

    【解决方案2】:

    模块化描述了将应用程序拆分为独立的部分并定义管理这些部分之间通信的 API。如果模块之间的所有通信都通过这些 API 进行,那么这些模块被称为松散耦合。这带来了一些好处,例如(简要地)……

    • 模块内的更改很容易,因为一个模块内部的更改不会影响任何其他模块
    • 能够单独开发、构建和测试每个模块
    • …在此处加载更多内容

    模块化可能涉及以下部分或全部:

    • 逻辑分离
    • 物理分离
    • 某种模块化系统,例如 OSGI 或 Project Jigsaw 在 Java 9 中生成的任何东西

    所以,这就是背景。在 Android 应用程序的上下文中(您的问题已标记),我建议一个模块就足够了,您应该使用打包来定义该模块内的逻辑分离。您会发现大量逐个功能包和逐层包的描述elsewhere,虽然阅读这些常用方法当然很有意义,但它们都以两个基本原则为基础:

    • 通用重用原则:包中的类一起重用。如果您重用包中的某个类,您就可以重用它们。
    • 通用闭包原则:包中的类应该一起闭包,以防止发生相同类型的更改。影响包的更改会影响该包中的所有类,而不会影响其他包。

    测试树的组织应反映主树的组织。如果主要包的因素很好,那么测试包也将如此。或者换一种说法,如果你发现编写测试用例变得更加困难,因为你不得不依赖似乎在错误位置的类和包,那么这清楚地表明你应该重新考虑你的打包方法。

    作为起点,您可以查看现有的开源 Android 应用,看看是否出现了常见模式。您还可以查看this answer 到相关的 SO 问题。但最终,您将最好地了解您的应用程序的细节,因此虽然众所周知/广泛使用的结构是一个很好的起点,但您可能必须随着您自己的应用程序的发展而改变它,并且在那个阶段重构工具和测试覆盖率将是很有用。

    【讨论】:

    • 如果有人说你应该遵循像数据层、视图层和控制器层这样的层方法,这些会是像数据包这样的包,它包含与数据相关的所有类等等,
    • 那么单元测试呢,我们如何组织我们的代码以便单元测试更容易?
    • “如果有人说你应该遵循像数据层、视图层和控制器层这样的层方法,这些会是像数据包这样的包,其中包含与数据相关的所有类等等”。是的,这就是“逐层打包”的样子。
    • 重构单元测试。来自其他答案之一的评论很好地总结了这一点:“模块化设计将始终使应用程序更具可测试性。在上面的示例中,所有 UI 逻辑都与数据逻辑分离,因此所有数据都可以很容易地被模拟。活动不关心从哪里来只要所有细节都隐藏在合适的界面后面,数据就会被拉取”。
    【解决方案3】:

    Module 可能意味着几件事,具体取决于上下文。通常,像这样的术语非常模糊。在 Java/Kotlin 中,它可以是类或包。就 Android 而言,它可以是应用程序的一个概念上(或功能上)独立的组件。此外,这些组件通常将驻留在单独的文件(类)和包中,因此存在语义重叠。

    让我们举个例子:

    1. 登录。
    2. 发送消息。
    3. 退出。

    在 Android 上,您可以这样建模:

    app
     ˪ ui
        ˪ SplashActivity
              ˪ SignInFragment
              ˪ SignUpFragment
     ˪ data
        ˪ db
           ˪ DatabaseManager
           ˪ models
               [model classes]
        ˪ api
           [classes responsible for network communication]
    

    这里有:

    • ui - 负责 UI 逻辑的模块/组件(同时也是包)。

    • SplashActivity - 负责管理有关登录/注册的逻辑。从概念上讲,我们也可以将其称为模块。物理上是一个类/文件。

    • data - 只负责数据操作的大模块/组件。同样,同时,物理上,一个包。

    • db - 专门负责数据库逻辑的子模块。

    等等。我要强调的一点是:模块将更多地用作抽象

    关于单元测试。模块化设计将始终使应用程序更具可测试性。在上面的示例中,所有 UI 逻辑都与数据逻辑分离,因此可以非常轻松地模拟所有数据。 Activity 不关心从哪里提取数据,只要所有细节都隐藏在合适的界面后面。 这是一个有点宽泛的问题,所以我向您推荐 Android 的应用程序架构指南,这正是关于模块化设计的:https://developer.android.com/topic/libraries/architecture/guide.html

    更新

    MVC 呢?

    Android 使用 MVC 的派生,称为 Model-View-Presenter。在 MVP 中,presenter 承担了“中间人”的功能(详情 here)。让我们举个例子:https://github.com/googlesamples/android-architecture/tree/todo-mvp。这个 Google 的简单待办事项应用程序展示了 MVP 设计。它的组织如下:

    todoapp
     ˪ data
         ˪ source
         ˪ Task.java (model)
     [...]
     ˪ tasks
        ˪ TasksActivity.java
        ˪ TasksFragment.java
        ˪ TasksPresenter.java
        [...]
    

    如您所见,此布局与我之前介绍的非常相似。数据(模型)逻辑保存在单独的包和 UI 逻辑(视图、演示器)中。当然,您可以进一步将 Presenter 与 View 分开,但是,这是一个非常简单的应用程序,类分离就足够了。

    如果您在组件之间进行了清晰的分离,例如在 MVP 中,则可以轻松地为每个组件独立地进行测试 - 只需模拟其他组件即可。再次,我建议阅读: https://developer.android.com/topic/libraries/architecture/guide.html,有一整节介绍如何测试每个组件。

    【讨论】:

    • 如果有人说你应该遵循像数据层、视图层和控制器层这样的层方法,这些会是像数据包这样的包,它包含与数据相关的所有类等等,
    • 那么单元测试呢,我们如何组织我们的代码以便单元测试更容易?
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    相关资源
    最近更新 更多