JS 设计模式 - 执行不同任务的接口

JS Design Patterns - Interface to perform different tasks

我的应用中有不同的方法来获取用户:

1. Fetch international users
2. Fetch users from same region
3. Fetch users from same city

目前,我已经为每个实现了1个方法:

 const fetchIntenationalUsers = async (limit = 10) => {
   const result = await db.collection("users").limit(limit).get();
   ...
   return parseUsers(result);
 }

 const fetchSameRegionUsers = async (region, limit = 10) => {
   const result = await db.collection("users").where("region", "==", region).limit(limit).get();
   ...
   return parseUsers(result);
 }

 const fetchSameCityUsers = async (city, limit = 10) => {
   const result = await db.collection("users").where("city", "==", city).limit(limit).get();
   ...
   return parseUsers(result);
 }

我想创建一个通用方法,例如:

const fetchUsers = (queryType = "international", location = {}, limit = 10) => {
   const queries = {
      "international": db.collection("users"),
      "region": db.collection("users").where("region", "==", location.region),
      "city": db.collection("users").where("city", "==", location.city),
   };

   const result = await queries[queryType].limit(limit).get();

   ...

   return parseUsers(result);
} 

但我不确定这是反模式还是设计模式。还有其他方法吗?

总体思路对我来说很好,但有一个问题:这一行:

const queries = {
  "international": db.collection("users"),
  "region": db.collection("users").where("region", "==", location.region),
  "city": db.collection("users").where("city", "==", location.city),
};

您在创建对象时调用 所有 这些数据库方法,而不仅仅是您需要的方法。 (您也没有处理未使用的方法可能引发的错误。)

稍微调整一下,考虑 return 查询的函数。您也可以预先 db.collection('users')

const users = db.collection("users");
const queries = {
   international: () => users,
   region: () => users.where("region", "==", location.region),
   city: () => users.where("city", "==", location.city),
};
const result = await queries[queryType]().limit(limit).get();

是的,我认为将它们全部放在一个“通用”方法中并引入 queryType 枚举是一种反模式。将来你会得到越来越多的查询类型,它会在 god method 中造成巨大的混乱。 (此外,它具有@CertainPerformance 的回答中提到的缺点)。

相反,我建议保留单独的函数(可以单独调用),但将代码的重复部分抽象为一个抽象辅助函数:

async function fetchUsers(addCondition, limit = 10) {
  const query = addCondition(db.collection("users")).limit(limit);
  const result = await query.get();
  …
  return parseUsers(result);
}

export const fetchInternationalUsers = (limit) => 
  fetchUsers(q => q, limit);

export const fetchSameRegionUsers = (region, limit) =>
  fetchUsers(q => q.where("region", "==", region), limit);

export const fetchSameCityUsers = async (city, limit) =>
  fetchUsers(q => q.where("city", "==", city), limit);