Prototype Design Pattern
1. 위젯 테마/스타일 복제
dart
class ButtonStyle implements Cloneable<ButtonStyle> {
final Color backgroundColor;
final Color textColor;
final double borderRadius;
final EdgeInsets padding;
ButtonStyle({
required this.backgroundColor,
required this.textColor,
required this.borderRadius,
required this.padding,
});
@override
ButtonStyle clone() {
return ButtonStyle(
backgroundColor: backgroundColor,
textColor: textColor,
borderRadius: borderRadius,
padding: padding,
);
}
// 특정 속성만 변경하는 메서드
ButtonStyle copyWith({
Color? backgroundColor,
Color? textColor,
double? borderRadius,
EdgeInsets? padding,
}) {
return ButtonStyle(
backgroundColor: backgroundColor ?? this.backgroundColor,
textColor: textColor ?? this.textColor,
borderRadius: borderRadius ?? this.borderRadius,
padding: padding ?? this.padding,
);
}
}
// 사용법
ButtonStyle primaryStyle = ButtonStyle(
backgroundColor: Colors.blue,
textColor: Colors.white,
borderRadius: 8.0,
padding: EdgeInsets.all(16),
);
// 기본 스타일을 복제해서 변형
ButtonStyle secondaryStyle = primaryStyle.copyWith(
backgroundColor: Colors.grey,
);
ButtonStyle dangerStyle = primaryStyle.copyWith(
backgroundColor: Colors.red,
);2. 게임 아이템/캐릭터 복제
dart
abstract class Cloneable<T> {
T clone();
}
class GameCharacter implements Cloneable<GameCharacter> {
String name;
int level;
int hp;
int mp;
List<String> skills;
Map<String, int> stats;
GameCharacter({
required this.name,
required this.level,
required this.hp,
required this.mp,
required this.skills,
required this.stats,
});
@override
GameCharacter clone() {
return GameCharacter(
name: name,
level: level,
hp: hp,
mp: mp,
skills: List.from(skills), // 깊은 복사
stats: Map.from(stats), // 깊은 복사
);
}
}
// 사용법: RPG 게임에서 몬스터 생성
class MonsterFactory {
static final Map<String, GameCharacter> _templates = {
'goblin': GameCharacter(
name: 'Goblin',
level: 1,
hp: 50,
mp: 10,
skills: ['Attack', 'Run'],
stats: {'strength': 8, 'defense': 5},
),
'orc': GameCharacter(
name: 'Orc',
level: 5,
hp: 120,
mp: 20,
skills: ['Heavy Attack', 'Roar'],
stats: {'strength': 15, 'defense': 10},
),
};
static GameCharacter createMonster(String type) {
final template = _templates[type];
if (template == null) throw Exception('Unknown monster type');
return template.clone(); // 템플릿 복제
}
}
// 게임에서 사용
GameCharacter goblin1 = MonsterFactory.createMonster('goblin');
GameCharacter goblin2 = MonsterFactory.createMonster('goblin');
// 각각 독립적인 인스턴스3. 복잡한 UI 설정 복제
dart
class ChatBubbleConfig implements Cloneable<ChatBubbleConfig> {
final Color backgroundColor;
final Color textColor;
final BorderRadius borderRadius;
final EdgeInsets margin;
final EdgeInsets padding;
final TextStyle textStyle;
final bool showTimestamp;
final bool showAvatar;
ChatBubbleConfig({
required this.backgroundColor,
required this.textColor,
required this.borderRadius,
required this.margin,
required this.padding,
required this.textStyle,
required this.showTimestamp,
required this.showAvatar,
});
@override
ChatBubbleConfig clone() {
return ChatBubbleConfig(
backgroundColor: backgroundColor,
textColor: textColor,
borderRadius: borderRadius,
margin: margin,
padding: padding,
textStyle: textStyle,
showTimestamp: showTimestamp,
showAvatar: showAvatar,
);
}
ChatBubbleConfig copyWith({
Color? backgroundColor,
Color? textColor,
// ... 다른 속성들
}) {
return ChatBubbleConfig(
backgroundColor: backgroundColor ?? this.backgroundColor,
textColor: textColor ?? this.textColor,
// ... 나머지 속성들
borderRadius: borderRadius,
margin: margin,
padding: padding,
textStyle: textStyle,
showTimestamp: showTimestamp,
showAvatar: showAvatar,
);
}
}
// 사용법: 채팅 앱에서 메시지 스타일
class ChatTheme {
static final ChatBubbleConfig baseConfig = ChatBubbleConfig(
backgroundColor: Colors.grey[200]!,
textColor: Colors.black,
borderRadius: BorderRadius.circular(12),
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
padding: EdgeInsets.all(12),
textStyle: TextStyle(fontSize: 16),
showTimestamp: true,
showAvatar: true,
);
// 내 메시지 스타일
static ChatBubbleConfig get myMessage => baseConfig.copyWith(
backgroundColor: Colors.blue[500],
textColor: Colors.white,
);
// 상대방 메시지 스타일
static ChatBubbleConfig get otherMessage => baseConfig.clone();
// 시스템 메시지 스타일
static ChatBubbleConfig get systemMessage => baseConfig.copyWith(
backgroundColor: Colors.yellow[100],
textColor: Colors.grey[700],
showAvatar: false,
);
}4. 폼 필드 설정 복제
dart
class FormFieldConfig implements Cloneable<FormFieldConfig> {
final InputDecoration decoration;
final TextInputType keyboardType;
final bool obscureText;
final String? Function(String?)? validator;
final int? maxLines;
FormFieldConfig({
required this.decoration,
required this.keyboardType,
this.obscureText = false,
this.validator,
this.maxLines = 1,
});
@override
FormFieldConfig clone() {
return FormFieldConfig(
decoration: decoration,
keyboardType: keyboardType,
obscureText: obscureText,
validator: validator,
maxLines: maxLines,
);
}
}
// 사용법: 회원가입 폼
class FormConfigs {
static final FormFieldConfig _baseConfig = FormFieldConfig(
decoration: InputDecoration(
border: OutlineInputBorder(),
filled: true,
fillColor: Colors.grey[50],
),
keyboardType: TextInputType.text,
);
static FormFieldConfig get email => _baseConfig.clone()
..keyboardType = TextInputType.emailAddress
..decoration = _baseConfig.decoration.copyWith(
labelText: 'Email',
prefixIcon: Icon(Icons.email),
);
static FormFieldConfig get password => _baseConfig.clone()
..obscureText = true
..decoration = _baseConfig.decoration.copyWith(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
);
}플러터에서 언제 사용하면 좋은가?
테마/스타일 시스템: 기본 스타일을 만들고 변형된 버전들을 생성
게임 오브젝트: 같은 타입의 캐릭터/아이템을 대량 생성
폼 설정: 비슷한 입력 필드들의 설정을 재사용
설정/구성 객체: 복잡한 설정을 복사해서 일부만 수정
위젯 빌더: 비슷한 위젯들을 템플릿 기반으로 생성
Last updated