Angular抽象工厂:如何构建模板化服务生成工厂?
通用服务工厂实现方案
嘿Mark,我太懂这种重复写代码的糟心感了——每次新增实体都要复制粘贴几乎一样的服务代码,不仅费时间,后期改起来还得一个个找,简直是维护噩梦!针对你的需求,我们可以写一个通用的服务工厂函数,只需要传入服务名,就能自动生成带正确接口URL的服务实例,彻底消除冗余代码。
第一步:处理服务名生成接口URL
首先我们需要一个工具函数,把传入的服务名(比如DeltaRunAuditService)转换成对应的接口URL:
- 先移除末尾的
Service后缀 - 把剩余的驼峰命名转成全小写(如果需要更符合RESTful风格的短横线分隔,我也会附上线索)
function getBaseApiUrl(serviceName) { // 移除服务名末尾的"Service"后缀 const entityName = serviceName.replace(/Service$/, ''); // 方案1:直接转成全小写(比如DeltaRunAudit → deltarunaudit) const lowercaseEntity = entityName.toLowerCase(); // 方案2:驼峰转短横线分隔(更符合RESTful规范,比如DeltaRunAudit → delta-run-audit) // const kebabCaseEntity = entityName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); return `/api/${lowercaseEntity}`; // 用方案2的话就换成kebabCaseEntity }
第二步:编写服务工厂函数
接下来我们写核心的工厂函数,它会基于处理好的URL生成包含通用CRUD方法的服务对象:
function createEntityService(serviceName) { const baseUrl = getBaseApiUrl(serviceName); // 返回包含通用方法的服务实例 return { // 获取所有实体 getAll() { return fetch(baseUrl).then(res => res.json()); }, // 根据ID获取单个实体 getById(id) { return fetch(`${baseUrl}/${id}`).then(res => res.json()); }, // 创建新实体 create(entityData) { return fetch(baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(entityData) }).then(res => res.json()); }, // 更新实体 update(id, entityData) { return fetch(`${baseUrl}/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(entityData) }).then(res => res.json()); }, // 删除实体 delete(id) { return fetch(`${baseUrl}/${id}`, { method: 'DELETE' }); } }; }
第三步:使用工厂生成服务
现在你只需要一行代码就能生成新的服务,完全不用重复写模板代码:
// 生成DeltaRunAudit服务 const deltaRunAuditService = createEntityService('DeltaRunAuditService'); // 直接调用通用方法 deltaRunAuditService.getAll().then(data => console.log('所有审计记录:', data)); deltaRunAuditService.create({ runId: 123, status: 'completed' }); // 生成其他服务也是一样的逻辑 const userService = createEntityService('UserService'); userService.getById(456);
可选:类风格的工厂(如果习惯用类)
如果你更倾向于用类来组织服务,也可以改成类工厂:
function createEntityServiceClass(serviceName) { const baseUrl = getBaseApiUrl(serviceName); return class EntityService { getAll() { return fetch(baseUrl).then(res => res.json()); } getById(id) { return fetch(`${baseUrl}/${id}`).then(res => res.json()); } // 其他CRUD方法和上面一致... }; } // 使用方式 const DeltaRunAuditService = createEntityServiceClass('DeltaRunAuditService'); const auditService = new DeltaRunAuditService(); auditService.delete(789);
这样以后新增任何实体服务,只需要调用工厂函数传入服务名即可,所有通用逻辑都集中在工厂里,后期要修改方法(比如统一添加请求头、处理错误),只需要改工厂这一处就好,维护起来超方便!
内容的提问来源于stack exchange,提问作者Mark Gargan
相关产品推荐
相关产品推荐

