# reductor
**Repository Path**: chinasoft2_ohos/reductor
## Basic Information
- **Project Name**: reductor
- **Description**: 一个状态管理机工具
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 2
- **Created**: 2021-05-18
- **Last Updated**: 2021-09-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# reductor
## 项目介绍
- 项目名称:reductor
- 所属系列:openharmony的第三方组件适配移植
- 功能:Reductor可以帮助您使状态突变更易于阅读,编写和推理。它利用注释处理来验证正确性并在编译时生成样板代码,从而使您可以将简明的状态约简表示为纯Java函数。作为Redux,它基于三个原则(来自Redux文档):
真理的单一来源、状态为只读、使用纯函数进行更改,该实现的关键是保留Redux的原始概念以重用大多数现有方法,但提供良好的Java API并尽可能保留类型。
- 项目移植状态:主功能完成
- 调用差异:无
- 开发版本:sdk6,DevEco Studio2.2 Beta2
- 基线版本:Release v0.13.2
## 效果演示
## 安装教程
1.在项目根目录下的build.gradle文件中,
```
allprojects {
repositories {
maven {
url 'https://s01.oss.sonatype.org/content/repositories/releases/'
}
}
}
```
2.在entry模块的build.gradle文件中,
```
dependencies {
implementation('com.gitee.chinasoft_ohos:reductor:1.0.0')
......
}
```
在sdk6,DevEco Studio2.2 Beta2下项目可直接运行
如无法运行,删除项目.gradle,.idea,build,gradle,build.gradle文件,
并依据自己的版本创建新项目,将新项目的对应文件复制到根目录下
## 使用说明
**简单计数器**
```java
//state will be just integer
//define actions
@ActionCreator
interface CounterActions {
String INCREMENT = "INCREMENT";
String ADD = "ADD";
@ActionCreator.Action(INCREMENT)
Action increment();
@ActionCreator.Action(ADD)
Action add(int value);
}
//Define reducer
@AutoReducer
abstract class CounterReducer implements Reducer {
@AutoReducer.InitialState
int initialState() {
return 0;
}
@AutoReducer.Action(
value = CounterActions.INCREMENT,
from = CounterActions.class)
int increment(int state) {
return state + 1;
}
@AutoReducer.Action(
value = CounterActions.ADD,
from = CounterActions.class)
int add(int state, int value) {
return state + value;
}
public static CounterReducer create() {
return new CounterReducerImpl(); //Note: usage of generated class
}
}
//Now you can create store and dispatch some actions
public static void main(String[] args) {
//Now you can create store and dispatch some actions
Store counterStore = Store.create(CounterReducer.create());
//you can access state anytime with Store.getState()
System.out.println(counterStore.getState());
//no need to implement CounterActions, we can do it for you
CounterActions actions = Actions.from(CounterActions.class);
counterStore.dispatch(actions.increment());
counterStore.dispatch(actions.increment());
counterStore.dispatch(actions.add(5));
}
```
**高级用法**
**Combine Reducers**
对于一个store,您需要一个Reducer,但是通常状态是复杂的,分离逻辑,将其分离为多个Reducer是一种很好的做法。
您可以通过创建Reducer手动完成,Reducer将简化逻辑委托给“较小”的Reducer
```java
//Complex state
class Todo {
List items;
String searchQuery;
public Todo(List items, String searchQuery) {
this.items = items;
this.searchQuery = searchQuery;
}
}
//define reducer per sub-states
class ItemsReducer implements Reducer> {
@Override
public List reduce(List strings, Action action) {...}
}
class QueryReducer implements Reducer {
@Override
public String reduce(String filter, Action action) {...}
}
//define combined reducer
class TodoReducer implements Reducer {
private ItemsReducer itemsReducer = new ItemsReducer();
private QueryReducer queryReducer = new QueryReducer();
@Override
public Todo reduce(Todo todo, Action action) {
//composing new state based on sub-reducers
return new Todo(
itemsReducer.reduce(todo.items, action),
queryReducer.reduce(todo.searchQuery, action)
);
}
}
```
这种方法是可行的,但需要开发人员编写一些将sub-states分配给sub-reducers的调度样板。
这就是为什么Reductor可以为您做无聊的工作。只需使用“@CombinedState”生成
```java
//Complex state
@CombinedState
interface Todo {
List items();
String searchQuery();
}
//define reducer per sub-states
class ItemsReducer implements Reducer> {
@Override
public List reduce(List strings, Action action) {return null;}
}
class QueryReducer implements Reducer {
@Override
public String reduce(String filter, Action action) {return null;}
}
public static void main(String[] args) {
//Using generated TodoReducer
Reducer todoReducer = TodoReducer.builder()
.itemsReducer(new ItemsReducer())
.searchQueryReducer(new QueryReducer())
.build();
}
```
注意,@CombinedState注释类需要是接口或AutoValue抽象类
**AutoReducer**
注意:PCollections库用作持久性集合的实现。
```java
//
class ItemsReducer implements Reducer> {
@Override
public List reduce(List items, Action action) {
switch (action.type) {
case "ADD_ITEM": {
String value = (String) action.value;
return TreePVector.from(items)
.plus(value);
}
case "REMOVE_ITEM": {
String value = (String) action.value;
return TreePVector.from(items)
.minus(value);
}
case "REMOVE_BY_INDEX": {
int index = (int) action.value;
return TreePVector.from(items)
.minus(index);
}
default:
return items;
}
}
}
//AutoReducer annotated class should be abstract class which implement Reducer interface
@AutoReducer
abstract class ItemsReducer implements Reducer> {
//Each 'handler' should be annotated with @AutoReducer.Action
@AutoReducer.Action("ADD_ITEM")
List add(List state, String value) {
return TreePVector.from(state)
.plus(value);
}
@AutoReducer.Action("REMOVE_ITEM")
List remove(List state, String value) {
return TreePVector.from(state)
.minus(value);
}
@AutoReducer.Action("REMOVE_BY_INDEX")
List removeByIndex(List state, int index) {
return TreePVector.from(state)
.minus(index);
}
static ItemsReducer create() {
//Note: ItemsReducerImpl is generated class
return new ItemsReducerImpl();
}
}
```
编写reducer的这种方式是规范的,但有一些缺点:
*开关语句的样板代码
*不安全地转换action.value为预期的类型
这就是为什么Reductor必须@AutoReducer通过生成reduce方法来帮助开发人员
## 测试信息
CodeCheck代码测试无异常
CloudTest代码测试无异常
病毒安全检测通过
当前版本demo功能与原组件基本无差异
## 版本迭代
- 0.0.3-SNAPSHOT