|
|
# InputComponentFactory 重构说明
|
|
|
|
|
|
## 重构目标
|
|
|
减少 `InputComponentFactory` 的参数输入,提高代码的可维护性和可读性。根据二维码类型创建专门的输入配置结构体,而不是一次性传递所有不相关的参数。
|
|
|
|
|
|
## 重构成果
|
|
|
|
|
|
### 1. 创建专门的配置结构体
|
|
|
为每种输入组件类型创建了专门的配置结构体,只包含必要的参数:
|
|
|
|
|
|
- `EmailInputConfig` - 邮件输入配置(5个参数)
|
|
|
- `WiFiInputConfig` - WiFi输入配置(3个参数)
|
|
|
- `ContactInputConfig` - 联系人输入配置(8个参数)
|
|
|
- `LocationInputConfig` - 位置输入配置(3个参数)
|
|
|
- `CalendarInputConfig` - 日历输入配置(5个参数)
|
|
|
- `SocialInputConfig` - 社交输入配置(2个参数)
|
|
|
- `PhoneInputConfig` - 电话输入配置(2个参数)
|
|
|
- `URLInputConfig` - URL输入配置(1个参数)
|
|
|
- `TextInputConfig` - 文本输入配置(1个参数)
|
|
|
|
|
|
### 2. 专门的工厂方法
|
|
|
每种配置都有对应的工厂方法,参数清晰明确:
|
|
|
|
|
|
```swift
|
|
|
// 邮件输入组件
|
|
|
static func createEmailInput(with config: EmailInputConfig) -> AnyView
|
|
|
|
|
|
// WiFi输入组件
|
|
|
static func createWiFiInput(with config: WiFiInputConfig) -> AnyView
|
|
|
|
|
|
// 联系人输入组件
|
|
|
static func createContactInput(with config: ContactInputConfig) -> AnyView
|
|
|
```
|
|
|
|
|
|
### 3. 简化的主工厂方法
|
|
|
主方法现在只需要基本的参数,内部根据类型创建相应的配置:
|
|
|
|
|
|
```swift
|
|
|
// 重构前:需要传递所有参数
|
|
|
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:使用专门的工厂方法(推荐)
|
|
|
```swift
|
|
|
// 创建邮件输入组件
|
|
|
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:使用主工厂方法(自动配置)
|
|
|
```swift
|
|
|
// 自动创建邮件输入组件,使用默认配置
|
|
|
let component = InputComponentFactory.createInputComponent(
|
|
|
for: .mail,
|
|
|
content: $content,
|
|
|
isContentFieldFocused: $isContentFieldFocused
|
|
|
)
|
|
|
```
|
|
|
|
|
|
### 方法3:混合使用(灵活配置)
|
|
|
```swift
|
|
|
// 先创建自定义配置
|
|
|
let customEmailConfig = EmailInputConfig(
|
|
|
emailAddress: $customEmailAddress,
|
|
|
emailSubject: $customEmailSubject,
|
|
|
emailBody: $customEmailBody,
|
|
|
emailCc: $customEmailCc,
|
|
|
emailBcc: $customEmailBcc
|
|
|
)
|
|
|
|
|
|
// 然后创建组件
|
|
|
let customEmailComponent = InputComponentFactory.createEmailInput(with: customEmailConfig)
|
|
|
```
|
|
|
|
|
|
## 重构优势
|
|
|
|
|
|
1. **参数管理清晰**:每种类型只包含必要的参数,不会混淆
|
|
|
2. **类型安全**:配置结构体确保参数类型正确
|
|
|
3. **可维护性**:修改特定组件类型时,只需要修改对应的配置结构体
|
|
|
4. **可扩展性**:添加新的组件类型时,只需添加新的配置结构体
|
|
|
5. **代码复用**:配置结构体可以在其他地方复用
|
|
|
6. **默认值支持**:主工厂方法提供合理的默认配置
|
|
|
|
|
|
## 配置结构体设计原则
|
|
|
|
|
|
### 1. 单一职责
|
|
|
每个配置结构体只负责一种输入类型的参数管理
|
|
|
|
|
|
### 2. 必要参数
|
|
|
只包含该输入类型真正需要的参数,避免冗余
|
|
|
|
|
|
### 3. 类型一致
|
|
|
所有参数都使用 `Binding<T>` 类型,保持一致性
|
|
|
|
|
|
### 4. 可扩展性
|
|
|
结构体设计支持未来添加新的参数
|
|
|
|
|
|
## 实际应用场景
|
|
|
|
|
|
### 场景1:创建邮件二维码
|
|
|
```swift
|
|
|
@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二维码
|
|
|
```swift
|
|
|
@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:动态创建组件
|
|
|
```swift
|
|
|
@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` 类型,确保类型擦除
|
|
|
|
|
|
## 未来改进方向
|
|
|
|
|
|
1. **泛型支持**:考虑使用泛型来进一步减少代码重复
|
|
|
2. **配置验证**:添加配置参数的验证逻辑
|
|
|
3. **样式定制**:支持自定义样式和主题配置
|
|
|
4. **国际化**:配置结构体支持多语言参数
|
|
|
5. **持久化**:支持配置的保存和恢复
|
|
|
|
|
|
## 总结
|
|
|
|
|
|
通过这次重构,我们成功地将一个参数复杂的工厂方法转换为多个职责清晰、参数明确的配置结构体。新的设计具有以下优势:
|
|
|
|
|
|
1. **参数清晰**:每种类型只包含必要的参数
|
|
|
2. **类型安全**:配置结构体确保参数类型正确
|
|
|
3. **易于使用**:调用者只需要关注相关的参数
|
|
|
4. **易于维护**:修改特定类型时影响范围有限
|
|
|
5. **易于扩展**:添加新类型变得简单
|
|
|
|
|
|
这种设计模式为项目的长期维护和功能扩展奠定了坚实的基础。 |