分解分解二_清洁分解

分解分解二


The decomposition problem was encountered by the NullGravity mobile development team and below how we solved it and what get in the end.
NullGravity移动开发团队遇到了分解问题,下面是我们如何解决它以及最终得到什么。
分解分解二_清洁分解

史前史 (Prehistory)


It was the fall of 2018, we were developing the next application for a telecom operator. But this time was different. The terms were quite tight and tied to the client’s marketing campaign. Android team has grown from 3 to 6-7 developers. Several tasks were taken in the sprint and the question was how to decompose them effectively.
那是2018年秋天,我们正在为电信运营商开发下一个应用程序。 但是这次不同了。 条款非常严格,并且与客户的营销活动相关。 Android团队从3名开发人员成长为6-7名开发人员。 在sprint中完成了几个任务,问题是如何有效地分解它们。
What do we mean when we speak effectively:
当我们有效讲话时,我们的意思是:
  1. The maximum number of parallel tasks.

    并行任务的最大数量。

    This makes it possible to use all available resources.

    这样就可以使用所有可用资源。

  2. Reducing the size of merge requests.

    减少合并请求的大小。

    They will not be watched for show, and you can still catch potential problems at the stage of code review.

    它们不会被显示,您仍然可以在代码检查阶段发现潜在的问题。

  3. Reduce the number of merge conflicts.

    减少合并冲突的数量。

    Tasks will merge faster and there is no need to switch the developer to resolve conflicts.

    任务将合并得更快,并且无需切换开发人员来解决冲突。

  4. An opportunity to collect statistics of expenses of time.

    收集时间费用统计信息的机会。
  5. Automate task creation in Jira.

    在Jira中自动创建任务。

我们如何解决这个问题? (How did we solve the problem?)


We divide all subtasks into the following types:
我们将所有子任务分为以下类型:
  • Data

    数据
  • Domain

  • Empty

    空的
  • UI

    用户界面
  • Item

    项目
  • Custom

    自订
  • Integration

    积分

Data and Domain correspond to layers in Clean Architecture. Empty, UI, Item and Custom refer to the presentation layer. Integration applies to both the domain and presentation layers.
数据和域对应于Clean Architecture中的层。 空,UI,项目和自定义是指表示层。 集成适用于域和表示层。
分解分解二_清洁分解
Figure 1. Location of tasks relative to Clean Architecture layers图1.任务相对于Clean Architecture层的位置
Let's look at each type individually.
让我们分别查看每种类型。

数据 (Data)


DTOs, API, work with database, datasource, etc.
DTO,API,与数据库,数据源等一起使用

(Domain)


Repository interface, business models, interactors.
存储库界面,业务模型,交互器。
As well as repository interface implemented in the data layer. Such a somewhat illogical, at first glance, separation made it possible to isolate tasks of the data and domain types as much as possible.
以及在数据层中实现的存储库接口。 乍看之下,这种有点不合逻辑的分离使得尽可能地隔离数据和域类型的任务成为可能。

用户界面 (UI)


Creating a basic screen layout and additional states, if they exist.
创建基本的屏幕布局和其他状态(如果存在)。

项目 (Item)


If the screen is a list of elements, then for each type you need to create a model — Item. To map Item to the layout, you need AdapterDelegate. We use the concept of
如果屏幕是元素列表,则需要为每种类型创建一个模型-项目。 要将Item映射到布局,您需要AdapterDelegate。 我们使用adapter delegates but with some 适配器委托的概念,但有一些improvements. 改进
Next, create an example of working with a list item in PresentationModel.
接下来,创建一个在PresentationModel中使用列表项的示例。

空的 (Empty)


Base classes required for tasks like ui or item: PresentationModel, Framgent, layout, DI module, AdapterDelagate factory. Binding interfaces and implementations. Create an entry point on the screen.
ui或item等任务所需的基类:PresentationModel,Framgent,布局,DI模块,AdapterDelagate工厂。 绑定接口和实现。 在屏幕上创建一个入口点。
The result of the task is the application screen. It contains Toolbar, RecyclerView, ProgressView, etc. that is, common interface elements, the addition of which could be duplicated by different developers and would lead to inevitable merge conflicts.
任务的结果是应用程序屏幕。 它包含工具栏,RecyclerView,ProgressView等,即常见的界面元素,其添加可能会被不同的开发人员复制,并导致不可避免的合并冲突。

自订 (Custom)


Implementation of custom UI component.
实现自定义UI组件。
An additional type is needed to separate the development of a new component from a task of type UI.
需要使用其他类型来将新组件的开发与UI类型的任务分开。

积分 (Integration)


Integration of domain and presentation layers.
域和表示层的集成。
As a rule, this is one of the most time-consuming tasks. It is necessary to reduce the two layers and refine the points that could have been missed in the previous stages.
通常,这是最耗时的任务之一。 有必要减少两层并优化在先前阶段可能遗漏的点。

任务顺序 (Task Order)


Tasks like data, empty and custom can be started immediately after the sprint starts. They are independent of other tasks.
冲刺开始后,可以立即启动数据,空白和自定义等任务。 它们独立于其他任务。
The domain task is executed after the data task.
域任务在数据任务之后执行。
The ui and item tasks after the empty task.
空任务后的ui和item任务。
The integration task is the last to be completed as it requires the completion of all previous tasks.
集成任务是最后要完成的任务,因为它需要完成所有先前的任务。
分解分解二_清洁分解
Figure 2. Timeline of task execution图2.任务执行的时间表
Despite the fact that some tasks are blocked by other tasks, they can be started at the same time or with a slight delay. Such tasks include domain, ui, and item. Thus, the development process is accelerated.
尽管某些任务被其他任务阻止,但它们可以同时启动或稍有延迟。 这些任务包括域,用户界面和项目。 因此,加快了开发过程。
分解分解二_清洁分解
Figure 3. Timeline of performing tasks with locks图3.使用锁执行任务的时间表
For each specific functionality, the set of tasks can vary. There may be a different number of tasks empty, ui, item and integration, and some types may simply be absent.
对于每种特定功能,任务集可以有所不同。 可能有不同数量的任务为空,用户界面,项目和集成,并且某些类型可能根本不存在。

流程自动化和统计信息收集 (Process automation and statistics collection)


To collect statistics when creating a task, label is assigned to it. This mechanism in the future will allow you to analyze the time spent on each type, and to form the average costs. The collected information can be applied when evaluating a new project.
要在创建任务时收集统计信息,请为其分配标签。 将来,这种机制将使您能够分析每种类型所花费的时间,并形成平均成本。 收集的信息可以在评估新项目时应用。
For automation, we also managed to find a solution. Since tasks are typical, why their description in Jira should be different. We developed templates for summary and description. At first it was just a json file, the Python parser of this file, and the Jira REST API was connected to generate tasks.
对于自动化,我们还设法找到了解决方案。 由于任务很典型,因此为什么在Jira中对它们的描述应该有所不同。 我们开发了用于摘要和描述的模板。 最初,它只是一个json文件,该文件的Python解析器,并且连接了Jira REST API来生成任务。
In this form, the script lasted almost a year. Today it has turned into a full-fledged desktop application written in Python using PyQt and MVP architecture.
以这种形式,脚本持续了将近一年。 如今,它已变成使用PyQt和MVP架构以Python编写的成熟的桌面应用程序。
Maybe MVP was overhead, but when the first version on Tkinter crashed MacOS version 10.14.6 and not all teams could use the application, we easily rewrote view for PyQt in half a day and it worked. Once again, we were convinced that the use of architectural approaches, even for such simple tasks, has its advantages. A screenshot of the JiraSubTaskCreator is shown in Figure 4.
也许MVP开销很大,但是当Tkinter上的第一个版本使MacOS版本10.14.6崩溃并且并非所有团队都可以使用该应用程序时,我们很容易在半天之内就重写了PyQt的视图,并且可以正常工作。 我们再次确信,即使对于如此简单的任务,使用架构方法也有其优势。 JiraSubTaskCreator的屏幕截图如图4所示。
分解分解二_清洁分解
Figure 4. The main screen of JiraSubTaskCreator图4. JiraSubTaskCreator的主屏幕

结论 (Conclusions)

  1. We have developed an approach to decomposition of tasks into subtasks minimally dependent on each other;

    我们已经开发出一种方法,可以将任务分解为彼此最小相关的子任务。
  2. Generated templates for describing tasks;

    生成用于描述任务的模板;
  3. We got small merge requests, which makes it possible to carefully review and change the code in isolation

    我们收到了一些小的合并请求,这使得可以单独仔细地检查和更改代码
  4. Reduced the number of conflicts with merge request;

    减少与合并请求的冲突数量;
  5. We got the opportunity to more accurately estimate and analyze the time spent on each type of task;

    我们有机会更准确地估计和分析在每种任务上花费的时间;
  6. Automated part of the routine work.

    日常工作的自动化部分。

翻译自: https://habr.com/en/post/489104/

分解分解二