美文网首页
Bloc分包

Bloc分包

作者: shz_Minato | 来源:发表于2020-01-24 17:46 被阅读0次

    Bloc的代码书写规范

    Bloc的分包

    我们之前有一张图片,如下所示:


    image

    我们可以看到:UI将事件给Bloc,Bloc将事件转为状态还给UI。这个工程以及完成了分离:业务层和UI层。但是呢还有一个问题:数据在哪里?如果按照上图的话,数据应该在Bloc这一层,那么就出现了一个问题:业务逻辑和数据糅合到了一起,我们理想状态应该是:数据和业务逻辑也尽可能分开。如下图所示:


    image

    在Bloc的模式下我们的应用可以被分为三个部分:数据 层、业务逻辑层、UI层。下面我们看一下 具体应该怎么写每一层。

    数据层

    数据层:从一个或多个数据源取和操作数据。数据源有:数据库、网络、文件等。数据层虽然是应用的最底层,但是也可以分为两部分:数据的获取和数据的包装。

    数据获取

    数据获取是为了渠道最为原始的数据,比如从网络get数据,数据库的增删改查,文件的读写等等。表现在代码上就是 某一个具体的方法。

    class DataProvider {
        Future<RawData> readData() async {
            // Read from DB or make network request etc...
        }
    }
    
    

    数据包装

    数据包装是为了将一个数据或多个数据 糅合到一起,直接和Bloc进行交互,并且将原始数据进行处理后再交给 Bloc。体现在代码上:

    class Repository {
        final DataProviderA dataProviderA;
        final DataProviderB dataProviderB;
    
        Future<Data> getAllDataThatMeetsRequirements() async {
            final RawDataA dataSetA = await dataProviderA.readData();
            final RawDataB dataSetB = await dataProviderB.readData();
    
            //通过两个数据 拿到业务层需要的数据
            final Data filteredData = _filterData(dataSetA, dataSetB);
            return filteredData;
        }
    }
    
    

    Bloc---业务逻辑层

    Bloc接受来自用户的 事件,根据事件去和上述的数据层交互,在根据交互的结果 生成对应的状态交给UI层。一个Bloc可能会依赖多个数据包装类。体现在代码上:

    class BusinessLogicComponent extends Bloc<MyEvent, MyState> {
        //数据包装
        final Repository repository;
        
        //事件转为状态
        Stream mapEventToState(event) async* {
            if (event is AppStarted) {
                try {
                    //和数据层交互
                    final data = await repository.getAllDataThatMeetsRequirements();
                    yield Success(data);
                } catch (error) {
                    yield Failure(error);
                }
            }
        }
    }
    
    

    我们知道一个Bloc可能会依赖别他的Bloc,那怎么做到这一点呢?可以通过构造方法传参,也可以通过依赖注入。比如:

    class MyBloc extends Bloc {
      final OtherBloc otherBloc;
      StreamSubscription otherBlocSubscription;
    
      MyBloc(this.otherBloc) {
        otherBlocSubscription = otherBloc.listen((state) {
        });
      }
    
      @override
      Future<void> close() {
        otherBlocSubscription.cancel();
        return super.close();
      }
    }
    
    

    UI层--表现层

    表现层其实就是渲染和用户交互,知道在什么样的状态下渲染出什么样的自己,知道将用户的交互事件传递给Bloc就可以了。比如:

    class PresentationComponent {
        final Bloc bloc;
    
        PresentationComponent() {
            bloc.add(AppStarted());
        }
    
        build() {
         
        }
    }
    
    

    总结

    以上就是Bloc应用的理想分层,这样看来Bloc是一个中转站:接受事件,分发事件,事件map状态。

    Bloc命名

    事件命名

    事件最好命名为过去式,因为从Bloc的角度看,事件已经发生了。

    比较常用的方式:Bloc对象+名次+动词(事件)

    比如:

    CounterStarted ------计数器开始了
    CounterIncremented -------计数器增加了

    CounterDecremented -------计数器减少了

    状态命名

    状态最好命名为名词,因为一个状态就是在某一时刻的一个应用快照。

    比较常用的方式:Bloc对象+动词+状态,并且一般情况下状态为:Initial | Success | Failure | InProgress

    比如:

    CounterInitial -----计数器初始

    CounterLoadInProgress -----计数器加载中

    CounterLoadSuccess ------计数器加载成功

    CounterLoadFailure ------计数器加载失败

    相关文章

      网友评论

          本文标题:Bloc分包

          本文链接:https://www.haomeiwen.com/subject/yuocthtx.html