design-patterns
BK-CI 项目设计模式实践指南,涵盖工厂模式、策略模式、观察者模式、装饰器模式、模板方法等在项目中的实际应用。当用户学习设计模式、重构代码、设计可扩展架构或理解项目设计时使用。
Install
mkdir -p .claude/skills/design-patterns && curl -L -o skill.zip "https://mcp.directory/api/skills/download/2169" && unzip -o skill.zip -d .claude/skills/design-patterns && rm skill.zipInstalls to .claude/skills/design-patterns
About this skill
Skill 27: BK-CI 项目设计模式实践指南
概述
本指南总结了 BK-CI 项目中广泛使用的设计模式及其实际应用场景,帮助开发者理解项目架构并遵循统一的设计模式规范。
1. 工厂模式(Factory Pattern)
1.1 简单工厂(Simple Factory)
应用场景:创建特定类型的对象,通过类型参数决定实例化哪个类。
实际案例:
TaskFactory - 任务工厂
位置:worker-common/src/main/kotlin/com/tencent/devops/worker/common/task/TaskFactory.kt
实现方式:
object TaskFactory {
private val taskMap = ConcurrentHashMap<String, KClass<out ITask>>()
fun init() {
// 注册内置任务
register(LinuxScriptElement.classType, LinuxScriptTask::class)
register(WindowsScriptElement.classType, WindowsScriptTask::class)
register(MarketBuildAtomElement.classType, MarketAtomTask::class)
// 通过反射扫描并注册插件任务
val reflections = Reflections("com.tencent.devops.plugin.worker.task")
val taskClasses = reflections.getSubTypesOf(ITask::class.java)
taskClasses?.forEach { taskClazz ->
val taskClassType = taskClazz.getAnnotation(TaskClassType::class.java)
taskClassType?.classTypes?.forEach { classType ->
register(classType, taskClazz.kotlin)
}
}
}
fun create(type: String): ITask {
val clazz = taskMap[type] ?: return EmptyTask(type)
return clazz.primaryConstructor?.call() ?: EmptyTask(type)
}
}
使用方式:
// 根据 element 类型创建对应的任务实例
val task = TaskFactory.create(element.getClassType())
task.run(buildTask, param, elementId)
特点:
- 使用 Kotlin
object实现单例 - 支持反射扫描自动注册
- 支持优先级覆盖(
priority字段) - 使用
ConcurrentHashMap保证线程安全
ScmFactory - 代码库工厂
位置:common-scm/src/main/kotlin/com/tencent/devops/scm/ScmFactory.kt
实现方式:
object ScmFactory {
private val gitApi = GitApi()
private val svnApi = SVNApi()
fun getScm(
projectName: String,
url: String,
type: ScmType, // CODE_SVN, CODE_GIT, CODE_TGIT, CODE_GITLAB, CODE_P4
// ... 其他参数
): IScm {
return when (type) {
ScmType.CODE_SVN -> CodeSvnScmImpl(...)
ScmType.CODE_GIT -> CodeGitScmImpl(...)
ScmType.CODE_TGIT -> CodeTGitScmImpl(...)
ScmType.CODE_GITLAB -> CodeGitlabScmImpl(...)
ScmType.CODE_P4 -> CodeP4ScmImpl(...)
else -> throw TaskExecuteException(
errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
errorMsg = "Unknown repo($type)"
)
}
}
}
使用场景:根据代码库类型(SVN、Git、GitLab、P4)创建对应的 SCM 实现。
其他工厂实例
| 工厂类 | 位置 | 用途 |
|---|---|---|
ApiFactory | worker-common/api/ApiFactory.kt | 创建 Worker 端 API 客户端 |
CommandFactory | worker-common/task/script/CommandFactory.kt | 创建脚本命令执行器 |
AtomRunConditionFactory | worker-common/task/market/AtomRunConditionFactory.kt | 创建插件运行条件处理器 |
PathFilterFactory | common-webhook/service/code/filter/PathFilterFactory.kt | 创建 Webhook 路径过滤器 |
DigestFactory | common-api/factory/DigestFactory.kt | 创建摘要算法实现 |
1.2 抽象工厂(Abstract Factory)
应用场景:创建一系列相关对象的工厂。
实际案例:
BkApiHandleFactory - API 处理器工厂
位置:common-web/src/main/kotlin/com/tencent/devops/common/web/factory/BkApiHandleFactory.kt
实现方式:
object BkApiHandleFactory {
private val handleMap = ConcurrentHashMap<String, BkApiHandleInterface>()
fun registerHandle(handle: BkApiHandleInterface) {
handleMap[handle.code()] = handle
}
fun getHandle(code: String): BkApiHandleInterface? {
return handleMap[code]
}
}
// 使用示例:根据 API 类型获取对应的处理器
interface BkApiHandleInterface {
fun code(): String // 返回 API 类型标识
fun handle(request: BkApiRequest): BkApiResponse
}
2. 单例模式(Singleton Pattern)
2.1 Kotlin Object 单例
应用场景:全局唯一实例,提供统一访问点。
实现方式:使用 Kotlin object 关键字。
实际案例:
// 工厂单例
object TaskFactory { ... }
object ScmFactory { ... }
object ApiFactory { ... }
// 工具类单例
object JsonUtil { ... }
object DateTimeUtil { ... }
特点:
- 线程安全(由 JVM 保证)
- 延迟初始化(首次访问时初始化)
- 无法被继承
2.2 Spring 单例
应用场景:业务服务类,通过 Spring 容器管理生命周期。
实现方式:
@Service // 默认单例
class PipelineService { ... }
@Component // 默认单例
class UserArchivedPipelinePermissionCheckStrategy { ... }
特点:
- Spring 容器管理
- 支持依赖注入
- 支持 AOP 增强
3. 建造者模式(Builder Pattern)
3.1 Kotlin Data Class + 命名参数
应用场景:构建复杂对象,提供清晰的构造参数。
实现方式:
data class PipelineTriggerEventBuilder(
var projectId: String? = null,
var pipelineId: String? = null,
var userId: String? = null,
var triggerType: String? = null,
var triggerUser: String? = null,
var eventSource: String? = null,
// ... 更多字段
) {
fun build(): PipelineTriggerEvent {
return PipelineTriggerEvent(
projectId = projectId ?: throw IllegalArgumentException("projectId is required"),
pipelineId = pipelineId ?: throw IllegalArgumentException("pipelineId is required"),
// ... 其他字段
)
}
}
使用方式:
val event = PipelineTriggerEventBuilder()
.apply {
projectId = "demo"
pipelineId = "p-12345"
userId = "admin"
triggerType = "MANUAL"
}
.build()
3.2 Fluent Builder(链式调用)
实际案例:
class Ansi(private var builder: StringBuilder) {
fun bold(): Ansi {
builder.append("\u001B[1m")
return this
}
fun fgRed(): Ansi {
builder.append("\u001B[31m")
return this
}
fun reset(): Ansi {
builder.append("\u001B[0m")
return this
}
fun toString(): String = builder.toString()
}
// 使用
val text = Ansi(StringBuilder())
.bold()
.fgRed()
.append("Error: ")
.reset()
.append("Build failed")
.toString()
4. 策略模式(Strategy Pattern)
4.1 接口 + 实现类
应用场景:根据运行时条件选择不同的算法实现。
实际案例:
流水线权限检查策略
位置:process/biz-process/src/main/kotlin/com/tencent/devops/process/strategy/
接口定义:
interface IUserPipelinePermissionCheckStrategy {
fun checkUserPipelinePermission(
userId: String,
projectId: String,
pipelineId: String,
permission: AuthPermission,
message: String? = null
)
}
实现类:
@Component
class UserNormalPipelinePermissionCheckStrategy : IUserPipelinePermissionCheckStrategy {
override fun checkUserPipelinePermission(...) {
// 正常流水线的权限检查逻辑
}
}
@Component
class UserArchivedPipelinePermissionCheckStrategy : IUserPipelinePermissionCheckStrategy {
override fun checkUserPipelinePermission(...) {
// 归档流水线的权限检查逻辑
}
}
策略工厂:
object UserPipelinePermissionCheckStrategyFactory {
fun getStrategy(archived: Boolean): IUserPipelinePermissionCheckStrategy {
return if (archived) {
SpringContextUtil.getBean(UserArchivedPipelinePermissionCheckStrategy::class.java)
} else {
SpringContextUtil.getBean(UserNormalPipelinePermissionCheckStrategy::class.java)
}
}
}
使用方式:
val strategy = UserPipelinePermissionCheckStrategyFactory.getStrategy(pipeline.archived)
strategy.checkUserPipelinePermission(userId, projectId, pipelineId, AuthPermission.VIEW)
4.2 数据迁移策略
位置:misc/biz-misc/src/main/kotlin/com/tencent/devops/misc/strategy/
接口定义:
interface MigrationStrategy {
fun migrate(projectId: String, pipelineId: String): Boolean
}
实现类示例:
PipelineInfoMigrationStrategy- 流水线基本信息迁移PipelineSettingMigrationStrategy- 流水线设置迁移TemplatePipelineMigrationStrategy- 模板流水线迁移PipelineYamlInfoMigrationStrategy- YAML 流水线迁移- 共计 20+ 个迁移策略实现类
特点:
- 每个策略负责特定数据的迁移
- 通过 Spring 容器管理
- 支持组合多个策略执行
5. 责任链模式(Chain of Responsibility)
5.1 Handler + HandlerChain
应用场景:将请求沿着处理器链传递,直到某个处理器处理它。
实际案例:
研发商店创建处理链
位置:store/biz-store/src/main/kotlin/com/tencent/devops/store/common/handler/
接口定义:
interface Handler<T : HandlerRequest> {
/**
* 能否满足运行条件
*/
fun canExecute(handlerRequest: T): Boolean
/**
* 核心处理逻辑
*/
fun execute(handlerRequest: T)
/**
* 执行总入口
*/
fun doExecute(handlerRequest: T, chain: HandlerChain<T>) {
if (canExecute(handlerRequest)) {
execute(handlerRequest)
}
chain.handleRequest(handlerRequest) // 传递给下一个处理器
}
}
interface HandlerChain<T : HandlerRequest> {
fun nextHandler(handlerRequest: T): Handler<T>?
fun handleRequest(handlerRequest: T) {
val handler = nextHandler(handlerRequest)
handler?.doExecute(handlerRequest, this)
}
}
处理器链实现:
class StoreCreateHandlerChain(
private val handlerList: MutableList<Handler<StoreCreateRequest>>
) : HandlerChain<StoreCreateRequest> {
override fun nextHandler(handlerRequest: StoreCreateRequest): Handler<StoreCreateRequest>? {
return handlerList.removeFirstOrNull()
}
}
具体处理器:
class StoreCreateParamCheckHandler : Handler<StoreCreateRequest> {
override fun canExecute(handlerRequest: StoreCreateRequest): Boolean = true
override fun execute(handlerRequest: StoreCreateRequest) {
// 参数校验逻辑
if (handlerRequest.atomCode.isBlank()) {
throw InvalidParamException("Atom code is blank")
}
}
}
class StoreCreatePreBusHandler : Handler<StoreCreateRequest> {
override fun canExecute(handlerRequest: StoreCreateRequest): Boolean = true
override fun execute(handlerRequest: StoreCreateRequest) {
// 前置业务逻辑
}
}
class StoreCreateDataPersistHandler : Handler<StoreCreateRequest> {
override fun canExecute(handlerRequest: StoreCreateRequest): Boolean = true
override fun execute(handlerRequest: StoreCreateRequest) {
// 数据持久化
}
}
使用方式:
val handlerList = mutableListOf(
StoreCreateParamCheckHandler(),
StoreCreatePreBusHandler(),
StoreCr
---
*Content truncated.*
More by TencentBlueKing
View all skills by TencentBlueKing →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
pdf-to-markdown
aliceisjustplaying
Convert entire PDF documents to clean, structured Markdown for full context loading. Use this skill when the user wants to extract ALL text from a PDF into context (not grep/search), when discussing or analyzing PDF content in full, when the user mentions "load the whole PDF", "bring the PDF into context", "read the entire PDF", or when partial extraction/grepping would miss important context. This is the preferred method for PDF text extraction over page-by-page or grep approaches.
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.