首页 > 解决方案 > 类和方法的单一职责?

问题描述

有一个抽象类Layer:

export abstract class Layer {
    protected layers: any[] = [];
    abstract get(): Promise<Layer[]>;
}

具体类:

export class CommonLayers extends Layer {
    async get(): Promise<Layer[]> {

    if (!hasRole('admin')) return;
   
    /* items belows could be loaded from server, now it is empty array  

    this.layers.push({
      title: "Title",
      items: [],
      count: 3,
    });

    return this.layers;
  }
}  

使用:

async getLayers(): Promise<any[]> {
    // let thematicLayers = await new ThematicLayers();
    let customLayers = await new CommonLayers();
    return [...thematicLayers, ...customLayers];
}

我不喜欢这部分代码:

this.layers.push({
          title: "Title",
          items: [],
          count: 3,
        });
    
return this.layers;

这个方法做了一些事情。

  1. 检查用户是否具有管理员角色
  2. 如果有,则从响应中获取数据
  3. 准备数据
  4. 将数据设置为this.layers
  5. 退货this.layers

我认为这种方法有很多责任。因此,当程序员调用该方法时,get()他假定它只是返回数据。而且它看起来不可读!

如何解决?

标签: javascripttypescript

解决方案


您需要一种从服务器获取数据的方法。这需要检查用户是否是管理员(注意这应该真的发生在后端,但无论如何),并且没有理由不返回获取的数据。就目前而言,我认为这里没有问题。

问题是您是正确的,Array.prototype.push在异步函数或.then回调中使用是代码异味,除了同步访问属性之外,您没有提供任何获取数据的方法(这将使您面临各种计时错误) 或调用从服务器获取的方法(不必要的 http 调用)。

真的没有办法让这个圈子变平方,我只想说你应该一直保持异步:

class Foo {
  // this should be a specific type rather than any
  protected layers: Promise<any[]> = Promise.resolve([])

  // I strongly recommend picking a method name other than 'get'
  async get(): Promise<any[]> {
    if (!hasRole('admin')) return [];
    const response = await fetch(someURL);
    this.layers = response.json();
    return this.layers;
  }
}

操场

这对调用者来说不太方便,但不一定有可靠的方法来解决它。

如果您使用返回的数据在前端执行任何逻辑,我拆分为第二种(或更多)方法。但是,如果您所做的只是获取它(以成为管理员为条件),那么我认为这很好。


推荐阅读