How Gaode’s GBF Framework Eliminates Glue Code with Domain‑Driven Design

This article explains how Gaode's Information Business team tackled fragmented portal implementations across multiple industries by adopting the Gaode Business Framework (GBF) and domain‑driven design, achieving unified architecture, reduced duplication, improved reusability, and enhanced system stability and maintainability.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
How Gaode’s GBF Framework Eliminates Glue Code with Domain‑Driven Design

Background

The Gaode Information Business US team maintains portal pages for various industries (food, hotel, travel, entertainment, real estate, etc.). Each portal evolves independently, resulting in isolated development, glue code, inconsistent solution chains, duplicated logic, and rising maintenance costs.

Goals

Provide stable, unified implementations for fixed scenarios.

Improve design quality, maintainability, and reduce failure risk.

Eliminate duplicate work and lower development cost.

Enhance knowledge management and team collaboration.

Clarify system boundaries to reduce internal friction.

Design Overview

GBF (Gaode Business Framework) adopts domain‑driven design (DDD) to structure business logic into clear domains, abilities, and services, enabling cross‑industry and cross‑scenario reuse.

1. What is GBF?

GBF is a lightweight framework that bridges business identity and scene strategy, inspired by TMF, and provides a standardized way to define domains, abilities, and processes.

2. Why Use GBF?

Higher precision in problem analysis through domain segmentation.

Facilitates knowledge sharing and evolution.

Improves code reuse and reduces development cost.

Enhances system stability by isolating domains.

Implementation Steps

0. Define GBF

GBF introduces concepts of Domain , Ability , and Process Node to organize code.

1. Repository Layer

@FetcherClient(name = "sug-fetcher")
public interface SugFetcher {
    @FetcherMethod(name = "quicklink")
    QuerySugResult<QuickLinkPO> getQuickLink(@RequestParam QuickLinkReqParam reqParam);
}
public interface QuickLinkRepo {
    @Annotation(title = "获取金刚位")
    QuickLinkPO getQuickLink(QuickLinkReqParam reqParam);
}

@Service
public class QuickLinkRepoImpl implements QuickLinkRepo {
    @Resource
    SugFetcher sugFetcher;
    @Override
    public QuickLinkPO getQuickLink(QuickLinkReqParam reqParam) {
        return Optional.ofNullable(sugFetcher.getQuickLink(reqParam))
            .map(QuerySugResult::getData)
            .orElse(null);
    }
}

2. Domain Service

@DomainService(name = "运营领域金刚位服务", domain = OperationDomain.class)
public interface IQuickLinkDomainService {
    QuickLinkDO getQuickLink(BaseRequest baseRequest);
}

@Service
public class QuickLinkDomainService implements IQuickLinkDomainService {
    @Resource
    QuickLinkRepo quickLinkRepo;
    @Resource
    IQuickLinkAbility quickLinkAbility;
    @Override
    public QuickLinkDO getQuickLink(BaseRequest baseRequest) {
        QuickLinkReqParam param = quickLinkAbility.buildQueryParam(baseRequest);
        QuickLinkPO po = quickLinkRepo.getQuickLink(param);
        return quickLinkAbility.buildQuickLinkDO(po);
    }
}

3. Ability Definition

@DomainAbility(name = "金刚位ability", domain = OperationDomain.class)
public interface IQuickLinkAbility {
    @ActionExtensible(name = "构建金刚位请求参数")
    QuickLinkReqParam buildQueryParam(BaseRequest request);
    @ActionExtensible(name = "构建金刚位DO")
    QuickLinkDO buildQuickLinkDO(QuickLinkPO po);
}
@Component
public class DefaultQuickLinkAction implements IQuickLinkAbility {
    @Override
    @Action(name = "构建金刚位请求参数")
    public QuickLinkReqParam buildQueryParam(BaseRequest request) {
        return new QuickLinkReqParam(request);
    }
    @Override
    @Action(name = "构建金刚位DO")
    public QuickLinkDO buildQuickLinkDO(QuickLinkPO po) {
        return Optional.ofNullable(po)
            .map(QuickLinkPO::getItems)
            .map(Collection::stream)
            .map(stream -> stream.map(p -> QuickLinkDO.ItemDO.builder()
                .title(p.getTitle())
                .icon(p.getIcon())
                .iconHeight(p.getIconHeight())
                .iconWidth(p.getIconWidth())
                .logInfo(p.getLogInfo())
                .toolTips(p.getToolTips())
                .schema(p.getSchema())
                .build())
                .collect(Collectors.toList()))
            .map(QuickLinkDO::new)
            .orElse(null);
    }
}

4. Node Service

@ProcessNode(name = "QuickLinkService")
public class QuickLinkNodeService extends AbstractCommonNodeService<QuickLinkDO, BaseRequest> {
    @Autowired
    IQuickLinkDomainService quickLinkDomainService;
    @Override
    public QuickLinkDO doInvoke(BaseRequest request) {
        return quickLinkDomainService.getQuickLink(request);
    }
}

5. Process Registration

// In ProcessConfig
BaseNodeConfigBuilder quickLinkNode = new NodeConfigBuilder()
    .preJoinPoint(new JoinPoint<PortalParam, BaseRequest>() {
        @Override
        public BaseRequest join(PortalParam request) { return request; }
    })
    .nodeBeanName(BeanUtil.getBeanName(QuickLinkNodeService.class));

@Bean
public ProcessConfig portalProcess() {
    return new ProcessConfigBuilder()
        .request(Request.class)
        .response(CommonResponse.class)
        .nodes(userNode)
        .nodes(filterTabNode)
        .nodes(feedNode)
        .nodes(bannerNode)
        .nodes(quickLinkNode)
        .build();
}

6. Controller

@RestController
@RequestMapping("/process")
public class ProcessController {
    @GetMapping("/portal/{biz}")
    @ResponseBody
    public Result<Response> portal(@PathVariable String biz, PortalParam param) {
        NodeService<Response, Request> process = BeanUtil.getSpringBean(ProcessRegister.genericBeanName(PortalProcessConfig.BEAN_NAME));
        param.setBizId(biz);
        return process == null ? ProcessResult.fail("未找到流程") : process.invoke(param);
    }
}

Conclusion

By applying domain‑driven design through GBF, the US team achieved unified system design, reduced glue code, improved reuse, lowered development and maintenance costs, and enhanced knowledge sharing and stability across multiple industry portals.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendSoftware ArchitectureMicroservicesDomain-Driven DesignFramework
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.