android 部件库_android中的功能部件

本文探讨了Android中的功能部件库,翻译自https://proandroiddev.com/feature-components-in-android-6c193a65d73f,深入解析了如何在Android应用中使用和构建组件。
摘要由CSDN通过智能技术生成

android 部件库

Creating loosely-coupled Reactive Feature Components

创建松耦合的React性特征组件

总览 (Overview)

Re-usability is a pattern that solves the problem of duplication. It can be as simple as creating Functions, Classes, Interfaces to more complex UI-Components and Feature-Components.

可重用性是解决重复问题的一种模式。 它可以像创建功能,类,到更复杂的UI组件功能组件的接口一样简单。

The article focuses initially on the re-usability of UI-Views(UIComponents) and then the FeatureComponents. Emphasis is on the Dependency-Inversion Principle, where both the Low-level(Feature Component) and High-level component (One incorporating the low-level components) both depend on abstraction, to create loosely-coupled systems.

本文首先关注UI-Views( UIComponents )的可重用性,然后是FeatureComponents的可重用性。 重点在于依赖关系反转原理 ,其中低级(功能组件)和高级组件(一个包含低级组件的组件)都依赖抽象,以创建松耦合的系统。

窥视UI组件[UI级] (A peek into UI Component [UI-level])

Before proceeding to Feature Components, we’ll start with a brief overview of UI-Components(re-usability of Views).

在继续进行功能组件之前,我们将首先简要概述UI组件(视图的可重用性)。

Image for post
UI Component design. Low-level component and High-level Component
UI组件设计。 底层组件和高层组件

Data is sent downwards from HLC → LLC, while the Events are sent from the LLC → HLC.

数据从HLC→LLC向下发送,而事件从LLC→HLC发送。

Low-Level Component (UIComponent): It only renders itself based on the data provided by the High-level component. And propagates the events to the High-level component(👇). It’s devoid of business-logic.

低级组件(UIComponent):仅根据高级别组件提供的数据进行渲染。 并将事件传播到高级组件(👇)。 它没有业务逻辑。

class UIComponent(
  private val data: ComponentData,
  private val eventDispatch: UIComponentEventDispatch) {
  
  // Renders based on the data provided by HLC
  fun render(view: UIComponentView) {
    view.data = data
    view.invalidate()
  }
  
  fun onRandomEvent(payLoad: Data) {
    // Sends the event to the HLC
    eventDispatch.handleEvent1(payLoad)
  }
}


interface UIComponentEventDispatch {
  fun handleEvent1(payLoad: Data)
}

High-level Component: Provides the data for the UI-Components(LLC), and handles the events from the UIComponent(👇). Example: Click events. It holds all the business logic. It is a single source of truth that holds the state/data for all the UI-Component.

高级组件 :提供UI组件(LLC)的数据,并处理UIComponent(👇)中的事件。 示例:单击事件。 它包含所有业务逻辑。 它是保存所有UI组件的状态/数据的唯一事实来源。

class HighLevelComponent {
  // Provides the data for UI component and passes the handler for handling events from UIComponent dispatch
  val uiComponent = UIComponent(data, UIComponentEventHandler())
  
  // Handles the events from the UIComponent.
  inner class UIComponentEventHandler: UIComponentEventDispatch {
    fun handleEvent1(payLoad: Data) { ... }
  }
  
  fun renderPage() {
    uiComponent.render(uiComponentView)
  }
}

React性特征组件 (Reactive Feature Component)

UIComponents are useful when there is re-usability of UI-views, while Feature Component has larger functionality.

当UI视图具有可重用性,而Feature Component具有更大的功能时,UIComponent很有用。

  • Apart from receiving the data, it also produces the data itself.

    除了接收数据之外,它还产生数据本身。
  • Contains its own business-logic.

    包含自己的业务逻辑。
  • Needs lesser hand-holding than UIComponent and is useful for designing SDKs and standalone features.

    与UIComponent相比,需要的握持较少,并且对设计SDK和独立功能很有用。

Why Reactive Feature Component?:- With multiple Components producing data, we need a way to synchronize them. Ex: Data produced by FC1 might affect FC2.

为什么使用React式特征组件?:-随着多个组件产生数据,我们需要一种同步它们的方法。 例如:FC1产生的数据可能会影响FC2。

We will take a bottom-up approach, where we Design and Implement the Low-level Feature components first, and later look their incorporation into the High-level Component.

我们将采用一种自下而上的方法,在该方法中,我们首先设计和实现低级功能组件,然后再将其合并到高级组件中。

低层特征组件(LLC)的设计。 (Design of Low-level Feature Components(LLC).)

For demonstration purposes, we build a Flight Booking screen. It includes the following four Low-level Feature Components DateSelection, FlightsSelection, HotelSelection, and SummaryComponent.

出于演示目的,我们构建了“航班预订”屏幕。 它包括以下四个低级功能组件DateSelectionFlightsSelectionHotelSelectionSummaryComponent。

Image for post
Booking screen Wireframe
预订画面线框

The design of the FeatureComponent looks like this(👇)

FeatureComponent的设计如下所示(👇)

Image for post
Design of Feature Components. Also showing the different terminologies.
特征组件的设计。 还显示了不同的术语。

Let’s look at the Flight Feature Component

让我们看一下飞行功能组件

1. EventDispatcher (1. EventDispatcher)

Dispatches the events to High-level-Component. This is like a channel through which events are sent to the outside world(HLC).

将事件调度到高级组件。 这就像将事件发送到外界(HLC)的渠道。

interface EventDispatcher


/**
 * Dispatches the events from the FlightFeatureComponent. This is like a channel through which we sent events to the outside world
 * There are two types of event
 * 1. Change in FeatureState needs to be propagated
 * 2. Other events like Clicks that are controlled by the parent and not handled by the current FeatureComponent
 */
interface FlightEventDispatcher : EventDispatcher {
    fun onFlightSelection(flight: Flight)
}
  • onFlightSelection a flight selection event is sent to the outside world. This may then be used by another FeatureComponent.

    onFlightSelection航班选择事件发送到外界。 然后,另一个FeatureComponent可以使用它。

2. EventReceiver (2. EventReceiver)

Feature Component receives the events from the High-level component.

功能组件从高级组件接收事件。

interface EventReceiver


interface FlightEventReceiver : EventReceiver {
    // Change in date will let the FlightComponent to update itself.
    // Makes an API call to fetch the flights for the specified date
    fun dateChange(date: Date)


    fun onRemoveSelection()
}

This is a gateway through which it receives events from the HLC.

这是一个网关,通过它从HLC接收事件。

  • dateChangeA change in date from another component is received. On reception, it fetches the flights for the said date.

    dateChange收到另一个组件的日期更改。 在接收时,它将获取所述日期的航班。

  • onRemoveSelection clears the selected flight.

    onRemoveSelection清除选定的航班。

3.用户界面 (3. UI)

The Feature Component has its own UI.

功能组件具有自己的UI。

interface UI<V : ViewGroup> {
    fun render(view: V)
}


interface FeatureComponent<V:ViewGroup>:  UI<V>
  • Every FeatureComponent extends the UI interface, implying that they define their own UI.

    每个FeatureComponent都扩展了UI界面,这意味着它们定义了自己的UI。
  • HLC attaches it. render is a public API for the HLC to render the FeatureComponent by passing the view(More detail later in Implementation 👇).

    HLC将其附加。 render是HLC通过传递视图来渲染FeatureComponent的公共API(稍后在实现Implementation中进行详细介绍)。

底层组件的实现。 (Implementation of Low-level components.)

定义FeatureComponent合同 (Defining the FeatureComponent Contract)

interface FeatureComponent<V: ViewGroup, E: EventDispatcher> : UI<V> {
    val eventDispatcher: E
}
  • All FeatureComponents implement this interface. It is generic on EventDispatcher.

    所有FeatureComponents都实现此接口。 它在EventDispatcher上是通用的。

1. EventDispatcher

1. EventDispatcher

class FlightFeatureComponent(
    override val eventDispatcher: FlightEventDispatcher
) : FeatureComponent<FlightView, FlightEventDispatcher> {
    
    fun onFlightSelected(flight: Flight) {
        eventDispatcher.onFlightSelection(flight)
    }
}
  • EventDispatcher is a dependency of the Feature Component.

    EventDispatcher是功能组件的依赖项。

  • The component passes on the events to this interface. In this case, it sends the selectedFlight event.

    组件将事件传递到此接口。 在这种情况下,它将发送selectedFlight事件。

2. EventReceiver (2. EventReceiver)

class FlightFeatureComponent(
    override val eventDispatcher: FlightEventDispatcher
) : FeatureComponent<FlightView, FlightEventDispatcher>, FlightEventReceiver {


    private val store: FlightStore = TODO("Business logic implementation of Feature component")
    
    override fun dateChange(date: Date) {
        store.dispatchActions(FetchFlights(date))
    }


    override fun onRemoveSelection() {
        store.dispatchActions(FlightAction.RemoveSelectedFlight)
    }
}
  • Flight FeatureComponent implements the FlightEventReceiver interface. This provides it the capability to receive events from the HLC.

    Flight FeatureComponent实现了FlightEventReceiver接口。 这使它能够从HLC接收事件。

  • In this case, it receives dateChange and removeSelection events and passes them to its business layer(store).

    在这种情况下,它接收dateChangeremoveSelection事件,并将它们传递到其业务层( store )。

3.定义和管理UI (3. Defining and managing the UI)

class FlightFeatureComponent(
    override val eventDispatcher: FlightEventDispatcher
) : FeatureComponent<FlightView, FlightEventDispatcher>, FlightEventReceiver, FlightUiDelegate {


    private val uiState = MutableStateFlow(FlightsUiState.initState())
    private val store = FlightStore()
    
    override fun render(view: FlightView) {
        view.prepare(uiState, uiDelegate = this@FlightFeatureComponent)
    }
    
    override fun onFlightClick(flight: Flight) {
         store.updateSelectedFlight(flight)
    }
}
  • Flight FeatureComponent implements the UI interface on FlightView defining its own UI.

    Flight FeatureComponent在FlightView上实现了UI界面,定义了自己的UI。

Additionally, FeatureComponent additionally coordinates between its own business-layer and the view layer, by acting as a middle-man. (👇)

此外,FeatureComponent还通过充当中间人在其自己的业务层和视图层之间进行协调。 (👇)

Image for post
Interaction between Business-layer and View-layer of the Feature Component
功能组件的业务层和视图层之间的交互

高级组件的设计与实现(预订屏幕) (Design & Implementation of High-level Component(Booking screen))

Divide it into 2 parts — Business layer and View-Layer

将其分为两部分-业务层和视图层

1.业务层 (1. Business-layer)

class BookingScreenViewModel {
    ...
    val flightComponent = FlightFeatureComponent(eventDispatcher = FlightEventDispatchListener())


    // Listener to receive the events from the Component's EventReceiver
    inner class FlightEventDispatchListener : FlightEventDispatcher {
        override fun onFlightSelection(flight: Flight) {
            // Handle the flight selection in the business layer of the Booking screen (HLC)
        }
    }
    ...
}
  • It creates the Feature Components.

    它创建功能部件。
  • To receive events from the FeatureComponents(LLC), HLC implements the dispatcher (FlightEventDispatcher) in the form of inner class (FlightEventDispatchListener), which is then passed on as a dependency for component creation(👆).

    FeatureComponents(LLC),HLC 接收事件 以内部类( FlightEventDispatchListener )的形式实现调度程序( FlightEventDispatcher ),然后将其作为组件创建(👆)的依赖项传递。

class FlightFeatureComponent(): FlightEventReceiver


class BookingScreenViewModel {
    ...
    val flightComponent = FlightFeatureComponent(eventDispatcher = FlightEventDispatchListener())
    
    // An event to clear all the selections in the screen 
    fun clearSelections() {
        flightComponent.onRemoveSelection()
    }
    ...
}
  • To send events to Feature Component, HLC can directly call the methods of FlightComponent, as it has the capability to receive events. See clearSelections .

    要将事件发送到功能部件,HLC可以接收事件,因此可以直接调用FlightComponent的方法。 参见clearSelections

2. 视图层 (2. View-layer)

class BookingScreen : Fragment() {
    private val vm = MainViewModel()


    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        vm.flightComponent.render(flight_view)
    }
}
  • It is only responsible for rendering the FeatureComponents created by the business-layer.

    它仅负责呈现业务层创建的FeatureComponents。

结论略有调整 (Conclusion with minor tweaks)

What if HLC components have a large number of components? The HLC would be over-burdened with synchronizing and passing the events between different FeatureComponents.

如果HLC组件包含大量组件怎么办? 通过在不同FeatureComponents之间同步和传递事件,HLC将负担沉重。

  • A better approach would be to make the HLC a mediator for passing events to FeatureComponents.

    更好的方法是使HLC成为将事件传递给FeatureComponents的中介者。

  • Whenever it receives an event from one FeatureComponent, it passes the event blindly to other FeatureComponents.

    每当它从一个FeatureComponent接收到事件时,就会将该事件盲目传递给其他FeatureComponents。
  • All FeatureComponent receive all the events but chooses the events on which they want to react and ignore the rest.

    所有FeatureComponent都接收所有事件,但选择它们要对其作出React的事件,而忽略其余事件。
  • This way both are loosely coupled and any component can be attached to the HLC.

    这样,两者都可以松散耦合,并且任何组件都可以连接到HLC。

You can find the demonstration example here.

您可以在此处找到演示示例。

翻译自: https://proandroiddev.com/feature-components-in-android-6c193a65d73f

android 部件库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值