# 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