You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.1 KiB
6.1 KiB
InputComponentFactory 重构说明
重构目标
减少 InputComponentFactory
的参数输入,提高代码的可维护性和可读性。根据二维码类型创建专门的输入配置结构体,而不是一次性传递所有不相关的参数。
重构成果
1. 创建专门的配置结构体
为每种输入组件类型创建了专门的配置结构体,只包含必要的参数:
EmailInputConfig
- 邮件输入配置(5个参数)WiFiInputConfig
- WiFi输入配置(3个参数)ContactInputConfig
- 联系人输入配置(8个参数)LocationInputConfig
- 位置输入配置(3个参数)CalendarInputConfig
- 日历输入配置(5个参数)SocialInputConfig
- 社交输入配置(2个参数)PhoneInputConfig
- 电话输入配置(2个参数)URLInputConfig
- URL输入配置(1个参数)TextInputConfig
- 文本输入配置(1个参数)
2. 专门的工厂方法
每种配置都有对应的工厂方法,参数清晰明确:
// 邮件输入组件
static func createEmailInput(with config: EmailInputConfig) -> AnyView
// WiFi输入组件
static func createWiFiInput(with config: WiFiInputConfig) -> AnyView
// 联系人输入组件
static func createContactInput(with config: ContactInputConfig) -> AnyView
3. 简化的主工厂方法
主方法现在只需要基本的参数,内部根据类型创建相应的配置:
// 重构前:需要传递所有参数
static func createInputComponent(
for qrCodeType: QRCodeType,
content: Binding<String>,
emailAddress: Binding<String>,
emailSubject: Binding<String>,
// ... 30+ 个参数
) -> AnyView
// 重构后:只需要基本参数
static func createInputComponent(
for qrCodeType: QRCodeType,
content: Binding<String>,
isContentFieldFocused: FocusState<Bool>
) -> AnyView
使用方法
方法1:使用专门的工厂方法(推荐)
// 创建邮件输入组件
let emailConfig = EmailInputConfig(
emailAddress: $emailAddress,
emailSubject: $emailSubject,
emailBody: $emailBody,
emailCc: $emailCc,
emailBcc: $emailBcc
)
let emailComponent = InputComponentFactory.createEmailInput(with: emailConfig)
// 创建WiFi输入组件
let wifiConfig = WiFiInputConfig(
ssid: $ssid,
password: $password,
encryptionType: $encryptionType
)
let wifiComponent = InputComponentFactory.createWiFiInput(with: wifiConfig)
方法2:使用主工厂方法(自动配置)
// 自动创建邮件输入组件,使用默认配置
let component = InputComponentFactory.createInputComponent(
for: .mail,
content: $content,
isContentFieldFocused: $isContentFieldFocused
)
方法3:混合使用(灵活配置)
// 先创建自定义配置
let customEmailConfig = EmailInputConfig(
emailAddress: $customEmailAddress,
emailSubject: $customEmailSubject,
emailBody: $customEmailBody,
emailCc: $customEmailCc,
emailBcc: $customEmailBcc
)
// 然后创建组件
let customEmailComponent = InputComponentFactory.createEmailInput(with: customEmailConfig)
重构优势
- 参数管理清晰:每种类型只包含必要的参数,不会混淆
- 类型安全:配置结构体确保参数类型正确
- 可维护性:修改特定组件类型时,只需要修改对应的配置结构体
- 可扩展性:添加新的组件类型时,只需添加新的配置结构体
- 代码复用:配置结构体可以在其他地方复用
- 默认值支持:主工厂方法提供合理的默认配置
配置结构体设计原则
1. 单一职责
每个配置结构体只负责一种输入类型的参数管理
2. 必要参数
只包含该输入类型真正需要的参数,避免冗余
3. 类型一致
所有参数都使用 Binding<T>
类型,保持一致性
4. 可扩展性
结构体设计支持未来添加新的参数
实际应用场景
场景1:创建邮件二维码
@State private var emailAddress = ""
@State private var emailSubject = ""
@State private var emailBody = ""
let emailConfig = EmailInputConfig(
emailAddress: $emailAddress,
emailSubject: $emailSubject,
emailBody: $emailBody,
emailCc: .constant(""),
emailBcc: .constant("")
)
let emailComponent = InputComponentFactory.createEmailInput(with: emailConfig)
场景2:创建WiFi二维码
@State private var ssid = ""
@State private var password = ""
@State private var encryptionType = WiFiInputView.WiFiEncryptionType.wpa
let wifiConfig = WiFiInputConfig(
ssid: $ssid,
password: $password,
encryptionType: $encryptionType
)
let wifiComponent = InputComponentFactory.createWiFiInput(with: wifiConfig)
场景3:动态创建组件
@State private var selectedQRType: QRCodeType = .text
@State private var content = ""
var body: some View {
InputComponentFactory.createInputComponent(
for: selectedQRType,
content: $content,
isContentFieldFocused: $isContentFieldFocused
)
}
注意事项
- 所有
FocusState
参数在工厂方法中使用默认值 - 如果需要自定义
FocusState
,建议直接创建对应的视图组件 - 配置结构体使用
let
声明,确保不可变性 - 工厂方法返回
AnyView
类型,确保类型擦除
未来改进方向
- 泛型支持:考虑使用泛型来进一步减少代码重复
- 配置验证:添加配置参数的验证逻辑
- 样式定制:支持自定义样式和主题配置
- 国际化:配置结构体支持多语言参数
- 持久化:支持配置的保存和恢复
总结
通过这次重构,我们成功地将一个参数复杂的工厂方法转换为多个职责清晰、参数明确的配置结构体。新的设计具有以下优势:
- 参数清晰:每种类型只包含必要的参数
- 类型安全:配置结构体确保参数类型正确
- 易于使用:调用者只需要关注相关的参数
- 易于维护:修改特定类型时影响范围有限
- 易于扩展:添加新类型变得简单
这种设计模式为项目的长期维护和功能扩展奠定了坚实的基础。