[Refactoring Guru: Builder](https://refactoring.guru/design-patterns/builder)
> [!info]
> **Builder** is a creational design pattern that lets you construct complex objects step by step.
> The pattern allows you to produce different types and representations of an object using the same construction code.
Example: [FormSchema: buildFormSchema](https://github.com/kunkunsh/kunkun/blob/c39e98258c3bf287e17ce3d3d143459b590d0976/packages/ui/src/utils/form.ts#L16)
In this example, we build a valibot schema from `FormSchema` (an object).
valibot schema cannot be serialized and deserialized in IPC. When extension renders a form with `FormSchema`, I have to construct a valibot schema to validate the date entered in frontend.
This is a simple example of the #builder-design-pattern .
```ts
export function buildFormSchema(form: FormSchema.Form): v.ObjectSchema<any, undefined> {
if (!form) return v.object({})
let schema = v.object({})
console.log("begin buildFormSchema", form)
for (const field of form.fields) {
console.log("field", field)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let fieldSchema: any = undefined
if (field.nodeName === FormNodeNameEnum.Input) {
fieldSchema = v.string()
} else if (field.nodeName === FormNodeNameEnum.Number) {
fieldSchema = v.number()
} else if (field.nodeName === FormNodeNameEnum.Select) {
fieldSchema = v.string()
} else if (field.nodeName === FormNodeNameEnum.Boolean) {
fieldSchema = v.boolean()
} else if (field.nodeName === FormNodeNameEnum.Date) {
fieldSchema = v.date()
} else {
console.warn(`Unknown field type: ${field.nodeName}`)
}
fieldSchema = addDefaultToSchema(fieldSchema, field)
if ((field as FormSchema.BaseField).optional) {
fieldSchema = v.nullable(v.optional(fieldSchema))
}
if ((field as FormSchema.BaseField).description) {
fieldSchema = v.pipe(fieldSchema, v.description((field as FormSchema.BaseField).description!))
}
if (fieldSchema) {
schema = v.object({ ...schema.entries, [field.key]: fieldSchema })
}
}
return schema
}
```