You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
graph TD
A[Database 생성자 변경] --> B[UserService 수정 필요]
A --> C[OrderService 수정 필요]
A --> D[ProductService 수정 필요]
A --> E[... 모든 사용처 수정 필요]
style A fill:#ffcccc
style B fill:#ffcccc
style C fill:#ffcccc
style D fill:#ffcccc
style E fill:#ffcccc
Loading
엥 그럼 팩토리 패턴이 결국 프로토콜이랑 같은거 아님?
아니더라구요
프로토콜(Protocol)은 "어떤 메소드들을 구현해야 하는지"를 정의하고. 팩토리 패턴은 "객체를 어떻게 만들지"를 정의하는 생성 전략입니다.
// 프로토콜만 사용하는 경우
protocolAnimal{func makeSound()}classZoo{func addAnimal(){letanimal:Animal=Dog() // 여전히 Dog라는 구체 클래스에 의존
animal.makeSound()}}----------
// 팩토리 패턴을 함께 사용하는 경우
protocolAnimal{ // 프로토콜: "뭘 할 수 있는지" 정의
func makeSound()}classAnimalFactory{ // 팩토리 패턴: "어떻게 만들지" 정의
staticfunc createAnimal(type:String)->Animal{switch type {case"강아지":returnDog()case"고양이":returnCat()default:returnDog()}}}classZoo{func addAnimal(animalType:String){letanimal=AnimalFactory.createAnimal(type: animalType) // 느슨한 결합!
animal.makeSound()}}
프로토콜: "뭘 할 수 있는지" 정의 (능력 명세서)
팩토리 패턴: "어떻게 만들지" 정의 (생성 방법론)
팩토리 패턴은 프로토콜을 활용해서 객체 생성을 더 유연하게 만드는 방법인거죠~
팩토리 메소드 패턴 예시
기본 팩토리 패턴
classDatabaseFactory{staticfunc createDatabase()->Database{returnDatabase(connectionString:"default_connection", timeout:30)}}classUserService{letdatabase=DatabaseFactory.createDatabase()// 팩토리 사용
}classOrderService{letdatabase=DatabaseFactory.createDatabase()// 팩토리 사용
}
이제 Database의 생성 로직이 바뀌어도 DatabaseFactory만 수정하면 됩니다!
팩토리 패턴 적용 후 흐름도
graph TD
A[Database 생성자 변경] --> B[DatabaseFactory만 수정]
B --> C[변경 완료!]
D[UserService] --> E[DatabaseFactory.createDatabase 호출]
F[OrderService] --> E
G[ProductService] --> E
E --> H[Database 인스턴스 반환]
style A fill:#ffcccc
style B fill:#ccffcc
style C fill:#ccffcc
style E fill:#cceeff
style H fill:#e8f5e8
Loading
추상 팩토리 패턴?
추상 팩토리 패턴은 관련된 객체들의 그룹을 만드는 팩토리들을 한 번에 관리하는 패턴입니다. 팩토리 메소드 패턴에서 좀더 확장된? 느낌이에요
예시: UI 테마 시스템
다크 모드와 라이트 모드에 따라 다른 UI 컴포넌트를 만드는 시스템을 예로 들면
// Step 1: UI 컴포넌트 인터페이스들 정의
protocolButton{func render()->String}protocolTextField{func render()->String}
// Step 2: 라이트 테마 컴포넌트들
classLightButton:Button{func render()->String{return"라이트 모드 버튼 (흰색 배경, 검은색 텍스트)"}}classLightTextField:TextField{func render()->String{return"라이트 모드 텍스트필드 (흰색 배경, 검은색 텍스트)"}}
// Step 3: 다크 테마 컴포넌트들
classDarkButton:Button{func render()->String{return"다크 모드 버튼 (검은색 배경, 흰색 텍스트)"}}classDarkTextField:TextField{func render()->String{return"다크 모드 텍스트필드 (검은색 배경, 흰색 텍스트)"}}
// Step 4: 추상 팩토리 인터페이스
protocolUIFactory{func createButton()->Buttonfunc createTextField()->TextField}
// Step 5: 구체적인 팩토리들
classLightUIFactory:UIFactory{func createButton()->Button{returnLightButton()}func createTextField()->TextField{returnLightTextField()}}classDarkUIFactory:UIFactory{func createButton()->Button{returnDarkButton()}func createTextField()->TextField{returnDarkTextField()}}
// Step 6: 팩토리를 만드는 팩토리 프로듀서
enumTheme{case light
case dark
}classUIFactoryProducer{staticfunc getFactory(theme:Theme)->UIFactory{switch theme {case.light:returnLightUIFactory()case.dark:returnDarkUIFactory()}}}
// Step 7: 사용 예시
classLoginScreen{letfactory:UIFactoryinit(theme:Theme){self.factory =UIFactoryProducer.getFactory(theme: theme)}func createLoginForm(){letusernameField= factory.createTextField()letpasswordField= factory.createTextField()letloginButton= factory.createButton()print("로그인 화면 생성:")print("- \(usernameField.render())")print("- \(passwordField.render())")print("- \(loginButton.render())")}}
// 사용
letlightLoginScreen=LoginScreen(theme:.light)
lightLoginScreen.createLoginForm()print("\n")letdarkLoginScreen=LoginScreen(theme:.dark)
darkLoginScreen.createLoginForm()
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
프젝에 필요한 내용을 혼자서 정리한 글입니다.
제가 이해한게 틀릴 수 있고 궁금한점이나 이야기해보고 싶은 점 있으시면 그냥 지나가지말고 같이 이야기해보면 좋을것같습니다!!
팩토리 메소드 패턴이란?
팩토리 메소드 패턴은 객체를 만드는 방법을 인터페이스로 정의하고, 실제로 어떤 객체를 만들지는 서브 클래스가 결정하도록 하는 패턴입니다. 쉽게 말해, "객체 생성을 전담하는 공장"을 만드는 느낌s
왜 팩토리 패턴을 사용해야 할까?
객체 지향 프로그래밍의 원칙 중 하나는 OCP(Open-Closed Principle) 입니다. 즉, 확장에는 열려있고 수정에는 닫혀야 한다 는 건데,,, 중요한 건 "수정
"에 닫혀있다" 는 부분입니다.
기존 코드를 건드리지 않고도 새로운 기능을 추가할 수 있어야 한다는 말인데, 변경될 가능성이 높은 부분과 안정적인 부분을 분리하는 것이 중요하다는 겁니다
객체가 생성되는 부분은 변경될 가능성이 높습니다. 생성자가 바뀌거나, 새로운 타입의 객체가 추가되거나, 초기화 로직이 복잡해질 가능성이 있습니다.
그래서 객체 생성을 한 곳에서 관리해서 결합도를 낮추기 위해 팩토리 패턴을 사용!
결합도란?
결합도는 한 클래스가 다른 클래스에 얼마나 의존하고 있는지를 나타냅니다.
위 코드에서
UserService는Database에 강하게 결합되어 있습니다.Database의 생성자가 바뀌면UserService도 수정해주어야 하죠결합도가 높으면 뭐가문제죠?
Database클래스의 생성자가 바뀌는걸 가정한다면:그러면
Database를 사용하는 모든 곳에서 코드를 수정해야 해요:이런 식으로 여러 곳을 수정해야 하는 상황을 피하기 위해 팩토리 패턴을 사용하는 겁니다~
\현재는 이런느낌
graph TD A[Database 생성자 변경] --> B[UserService 수정 필요] A --> C[OrderService 수정 필요] A --> D[ProductService 수정 필요] A --> E[... 모든 사용처 수정 필요] style A fill:#ffcccc style B fill:#ffcccc style C fill:#ffcccc style D fill:#ffcccc style E fill:#ffcccc엥 그럼 팩토리 패턴이 결국 프로토콜이랑 같은거 아님?
아니더라구요
프로토콜(Protocol)은 "어떤 메소드들을 구현해야 하는지"를 정의하고. 팩토리 패턴은 "객체를 어떻게 만들지"를 정의하는 생성 전략입니다.
팩토리 패턴은 프로토콜을 활용해서 객체 생성을 더 유연하게 만드는 방법인거죠~
팩토리 메소드 패턴 예시
기본 팩토리 패턴
이제
Database의 생성 로직이 바뀌어도DatabaseFactory만 수정하면 됩니다!팩토리 패턴 적용 후 흐름도
graph TD A[Database 생성자 변경] --> B[DatabaseFactory만 수정] B --> C[변경 완료!] D[UserService] --> E[DatabaseFactory.createDatabase 호출] F[OrderService] --> E G[ProductService] --> E E --> H[Database 인스턴스 반환] style A fill:#ffcccc style B fill:#ccffcc style C fill:#ccffcc style E fill:#cceeff style H fill:#e8f5e8추상 팩토리 패턴?
추상 팩토리 패턴은 관련된 객체들의 그룹을 만드는 팩토리들을 한 번에 관리하는 패턴입니다. 팩토리 메소드 패턴에서 좀더 확장된? 느낌이에요
예시: UI 테마 시스템
다크 모드와 라이트 모드에 따라 다른 UI 컴포넌트를 만드는 시스템을 예로 들면
추상 팩토리 패턴 구조도
classDiagram class UIFactory { <<interface>> +createButton() Button +createTextField() TextField } class LightUIFactory { +createButton() Button +createTextField() TextField } class DarkUIFactory { +createButton() Button +createTextField() TextField } class Button { <<interface>> +render() String } class TextField { <<interface>> +render() String } class LightButton { +render() String } class DarkButton { +render() String } class LightTextField { +render() String } class DarkTextField { +render() String } class UIFactoryProducer { +getFactory(theme: Theme) UIFactory } UIFactory <|-- LightUIFactory UIFactory <|-- DarkUIFactory Button <|-- LightButton Button <|-- DarkButton TextField <|-- LightTextField TextField <|-- DarkTextField LightUIFactory --> LightButton LightUIFactory --> LightTextField DarkUIFactory --> DarkButton DarkUIFactory --> DarkTextField UIFactoryProducer --> UIFactoryUI 테마 생성 흐름도
sequenceDiagram participant Client participant LoginScreen participant UIFactoryProducer participant UIFactory participant UIComponents Client->>LoginScreen: new LoginScreen(.dark) LoginScreen->>UIFactoryProducer: getFactory(.dark) UIFactoryProducer->>UIFactory: new DarkUIFactory() UIFactoryProducer-->>LoginScreen: return factory Client->>LoginScreen: createLoginForm() LoginScreen->>UIFactory: createTextField() UIFactory->>UIComponents: new DarkTextField() UIFactory-->>LoginScreen: return textField LoginScreen->>UIFactory: createButton() UIFactory->>UIComponents: new DarkButton() UIFactory-->>LoginScreen: return button팩토리 패턴의 장단점
장점
단점
3줄요약
ref)
https://velog.io/@ellyheetov/Factory-Pattern
https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm
https://refactoring.guru/design-patterns/abstract-factory
https://www.youtube.com/watch?v=QrNVYepenws&ab_channel=%ED%94%84%EB%A6%AC%EB%A0%89
Beta Was this translation helpful? Give feedback.
All reactions