我可以创建一个抽象来隐藏我的“检查缓存”吗?逻辑?

发布于 2025-01-13 23:52:39 字数 2354 浏览 4 评论 0原文

我有 getResponse() 方法,可以根据从数据库获取的数据(或预先保存在 SavedData 对象中)构建响应。我想找到一种方法从我的 getResponse() 方法中抽象出“检查保存的数据”逻辑。理想情况下,我想找出一种方法,让我的 getResponse() 方法甚至不知道 SavedData 存在,它只是隐藏在某个界面后面。这里有一个好的抽象可以用来清理这段代码吗?

以下只是伪代码。对于 getResponse() JSON 对象中返回的每个字段,他们首先检查该字段是否已保存在某个 SavedData 中,如果有则使用它,否则,他们需要查询数据库中的字段。

interface ResponseGetter {
  public Response getResponse(String userID, SavedData savedData);
}

class A implements ResponseGetter {
  public Response getResponse(String userID, SavedData savedData) {           
      List<String> foo;
      int bar;
      String bizz;

      foo = savedData.get(userID, "foo");
      if (foo == null) {
        foo = loadFooFromDB(userID);
      }
      bar = savedData.get(userID, "bar");
      if (bar == null) {
        bar = loadBarFromDB(userID);
      }
      bizz = savedData.get(userID, "bizz");
      if (bizz == null) {
        bizz = loadBizzFromDB(userID);
      }

      JSONObject json = new JSONObject();
      json.put("foo", foo);
      json.put("bar", bar);
      json.put("bizz", biz);
      return new Response(json);
  }

  private List<String> loadFooFromDB(String userID) {
     List<String> returnList = new ArrayList<String>();
     DB db = this.getDB();
     String query = "SELECT foo FROM SomeTable WHERE user_id=" + userID;
     Results results = db.executeQuery(query);
     for (Result result : results) {
         returnList.add(result.toString());
     }

     return returnList;
  }
}

class B implements ResponseGetter {
  public Response getResponse(String userID, SavedData savedData) {           
      List<String> baz;
      int qux;
      String corge;

      baz = savedData.get(userID, "baz");
      if (baz == null) {
        baz = loadBazFromDB(userID);
      }
      qux = savedData.get(userID, "qux");
      if (qux == null) {
        qux = loadQuxFromDB(userID);
      }
      corge = savedData.get(userID, "corge");
      if (corge == null) {
        corge = loadCorgeFromDB(userID);
      }
      
    
      JSONObject json = new JSONObject();
      json.put("baz", baz);
      json.put("qux", qux);
      json.put("corge", corge);
        
      return new Response(json);
  }
}

I have getResponse() methods which build a response from data fetched from the database (or pre-saved in a SavedData object). I would like to find a way to abstract out the "check savedData" logic from my getResponse() methods. Ideally, I want to figure out a way where my getResponse() methods don't even know SavedData exists, it is just hidden behind some interface. Is there a good abstraction here I can use to clean up this code?

The following is just pseudo-code. For each field which is returned in the getResponse() JSON object, they first check if that field has been saved in some SavedData and use it if it has, otherwise, they need to query the DB for the field.

interface ResponseGetter {
  public Response getResponse(String userID, SavedData savedData);
}

class A implements ResponseGetter {
  public Response getResponse(String userID, SavedData savedData) {           
      List<String> foo;
      int bar;
      String bizz;

      foo = savedData.get(userID, "foo");
      if (foo == null) {
        foo = loadFooFromDB(userID);
      }
      bar = savedData.get(userID, "bar");
      if (bar == null) {
        bar = loadBarFromDB(userID);
      }
      bizz = savedData.get(userID, "bizz");
      if (bizz == null) {
        bizz = loadBizzFromDB(userID);
      }

      JSONObject json = new JSONObject();
      json.put("foo", foo);
      json.put("bar", bar);
      json.put("bizz", biz);
      return new Response(json);
  }

  private List<String> loadFooFromDB(String userID) {
     List<String> returnList = new ArrayList<String>();
     DB db = this.getDB();
     String query = "SELECT foo FROM SomeTable WHERE user_id=" + userID;
     Results results = db.executeQuery(query);
     for (Result result : results) {
         returnList.add(result.toString());
     }

     return returnList;
  }
}

class B implements ResponseGetter {
  public Response getResponse(String userID, SavedData savedData) {           
      List<String> baz;
      int qux;
      String corge;

      baz = savedData.get(userID, "baz");
      if (baz == null) {
        baz = loadBazFromDB(userID);
      }
      qux = savedData.get(userID, "qux");
      if (qux == null) {
        qux = loadQuxFromDB(userID);
      }
      corge = savedData.get(userID, "corge");
      if (corge == null) {
        corge = loadCorgeFromDB(userID);
      }
      
    
      JSONObject json = new JSONObject();
      json.put("baz", baz);
      json.put("qux", qux);
      json.put("corge", corge);
        
      return new Response(json);
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我会使用泛型和策略设计模式

我真的不知道你可以放弃哪些类型和类,因为你提供了伪代码。

如果我忘了写重要的东西,请评论。


但我会采用这样的方法:

interface ResponseGetter<R> {
R getResponse(String userId, String dataToCheck, SavedData<R> savedData, Function<String, R> lambda);
}

class DB<R> {
public R executeQuery(String query) {
    return null;
}
}

interface SavedData<R> {
    public R get(String userId, String name);
}

class SomeClass<R> implements ResponseGetter<R> {

    @Override
    public R getResponse(String userId, String dataToCheck, SavedData<R> savedData, Function<String, R> lambda) {
        R checkedData = savedData.get(userId, dataToCheck);
        return checkedData == null ? loadDataFromDB(userId, lambda) : checkedData;
    }

    public R loadDataFromDB(String userId, Function<String, R> lambda) {
        return lambda.apply(userId);
    }
}

class SavedDataImpl<R> implements SavedData<R> {

    @Override
    public R get(String userId, String name) {
        return null;
    }
}

class Main  {

    public static void main(String[] args) {

        // foo
        SomeClass<List<String>> someClass = new SomeClass<>();
        SavedDataImpl<List<String> savedDataImpl = new SavedDataImpl<>();
        DB<List<String>> db = new DB<>();

        List<String> foo = someClass.getResponse("1", "foo", savedDataImpl, (String userId) -> {
        List<String> result = db.executeQuery("SELECT foo FROM SomeTable WHERE user_id=" + userId);
        return result;
    });

    // bar
    SomeClass<Integer> someClassTwo = new SomeClass<>();
    SavedDataImpl<Integer savedDataImplTwo = new SavedDataImpl<>();
    DB<Integer> dbTwo = new DB<>();

    Integer bar = someClassTwo.getResponse("1", "bar", savedDataImplTwo, (String userId) -> {
        Integer result = dbTwo.executeQuery("SELECT bar FROM SomeTable WHERE user_id=" + userId);
        return result;
    });

    // bizz
    SomeClass<String> someClassThree = new SomeClass<>();
    SavedDataImpl<String savedDataImplThree = new SavedDataImpl<>();
    DB<String> dbThree = new DB<>();

    String bizz = someClassThree.getResponse("1", "bizz", savedDataImplThree, (String userId) -> {
        String result = dbThree.executeQuery("SELECT bizz FROM SomeTable WHERE user_id=" + userId);
        return result;
    });

    Map json = new HashMap();
    json.put("foo", foo);
    json.put("bar", bar);
    json.put("bizz", bizz);

}
}

这样你就可以抽象出如何获取数据和获取哪些数据的行为。

为了简单起见,我只是在地图中格式化了响应。

I would use generics and the Strategy Design Pattern.

I didn't really know what types and classes you could give up, since you provided a pseudo-code.

If I forgot to put something importante, please comment.


But I would go with something like this:

interface ResponseGetter<R> {
R getResponse(String userId, String dataToCheck, SavedData<R> savedData, Function<String, R> lambda);
}

class DB<R> {
public R executeQuery(String query) {
    return null;
}
}

interface SavedData<R> {
    public R get(String userId, String name);
}

class SomeClass<R> implements ResponseGetter<R> {

    @Override
    public R getResponse(String userId, String dataToCheck, SavedData<R> savedData, Function<String, R> lambda) {
        R checkedData = savedData.get(userId, dataToCheck);
        return checkedData == null ? loadDataFromDB(userId, lambda) : checkedData;
    }

    public R loadDataFromDB(String userId, Function<String, R> lambda) {
        return lambda.apply(userId);
    }
}

class SavedDataImpl<R> implements SavedData<R> {

    @Override
    public R get(String userId, String name) {
        return null;
    }
}

class Main  {

    public static void main(String[] args) {

        // foo
        SomeClass<List<String>> someClass = new SomeClass<>();
        SavedDataImpl<List<String> savedDataImpl = new SavedDataImpl<>();
        DB<List<String>> db = new DB<>();

        List<String> foo = someClass.getResponse("1", "foo", savedDataImpl, (String userId) -> {
        List<String> result = db.executeQuery("SELECT foo FROM SomeTable WHERE user_id=" + userId);
        return result;
    });

    // bar
    SomeClass<Integer> someClassTwo = new SomeClass<>();
    SavedDataImpl<Integer savedDataImplTwo = new SavedDataImpl<>();
    DB<Integer> dbTwo = new DB<>();

    Integer bar = someClassTwo.getResponse("1", "bar", savedDataImplTwo, (String userId) -> {
        Integer result = dbTwo.executeQuery("SELECT bar FROM SomeTable WHERE user_id=" + userId);
        return result;
    });

    // bizz
    SomeClass<String> someClassThree = new SomeClass<>();
    SavedDataImpl<String savedDataImplThree = new SavedDataImpl<>();
    DB<String> dbThree = new DB<>();

    String bizz = someClassThree.getResponse("1", "bizz", savedDataImplThree, (String userId) -> {
        String result = dbThree.executeQuery("SELECT bizz FROM SomeTable WHERE user_id=" + userId);
        return result;
    });

    Map json = new HashMap();
    json.put("foo", foo);
    json.put("bar", bar);
    json.put("bizz", bizz);

}
}

That way you are abstracting the behavior of the how to get the data and wich data to get.

I just formatted the response in a Map for simplicity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文