반응형
가정)
나는 오리 연못 시뮬레이션 개임을 만드는 회사에 다니고 있다.
이 게임에서는 헤엄도 치고 꽥꽥거리는 소리도 내는 매우 다양한 오리 종류를 보여줄 수 있다.
.
.
.
public abstract class Duck {
//울기
abstract void quack();
//수영
abstract void swim();
}
오리의 종류들 마다 다르지만, 오리 객체를 상속 받아서, 울기와 수영하기 메소드를 @override하였다.
class JustDuck extends Duck {
@Override
void quack() {
//울기
}
@Override
void swim() {
//수영하기
}
}
.
.
.
가정)
작년부터 다른 경쟁사로부터의 압박이 점점 심해졌다.
다음 주에 회사에서 있을 주주총회 때 뭔가 정말 인상적인 것을 보여줘야만 한다..
나는 오리를 날수도 있게 메소드를 추가 하였고 JustDuck에서도 override 하게 만들었다.
public abstract class Duck {
//울기
abstract void quack();
//날기
abstract void swim();
abstract void fly();
}
class JustDuck extends Duck {
@Override
void quack() {
//울기
}
@Override
void swim() {
//수영하기
}
@Override
void fly() {
//날기
}
}
.
.
.
가정) 그런데 심각한 문제가 생겼다.
모든 오리가 날 수 있는게 아니였다.. 장난감오리는 날 수 없다.
어떻게 해결 할 것인가?.
상속을 사용하는 것은 올바른 해결책이 아니라는 것을 알 수 있다.
디자인 원칙 : 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리시킨다.
해결 방법 : 바뀌는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 "캡슐화" 합니다.
이렇게 하면, 나중에 바뀌지 않는 부분에는 영향을 미치지 않은 채로 그 부분만 고치거나 확장할 수 있다.
fly()와 quack()은 Duck클래스에서 오리마다 달라지는 부분입니다.
이러한 행동을 Duck 클래스로부터 갈라내기 위해서 그 두 메소드를 모두 Duck 클래스로부터 끄집어 내서,
각 행동을 나타낼 클래스 집합을 새로 만들도록 하겠습니다.
디자인 원칙 : 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
//상속(abstract)가능 클래스
public abstract class Duck {
//구성 (행동을 위임 받는 것.)
FlyBehavior flyBehavior;
public Duck() { }
public String howToFly() {
return flyBehavior.fly();
}
}
//인터페이스
public interface FlyBehavior {
//String을 반환하는 메소드
String fly();
}
//
public class CantFly implements FlyBehavior{
@Override
public String fly() {
return "날고 싶어도 못날아요~";
}
}
//날지못하는 행동을 가진 justDuck 클래스
class JustDuck extends Duck{
//오리클래스를 상속 받음. 상속을 받음으로서, flyBehavior 객체를 위임 받아, 행동을 구현.
public JustDuck() {
flyBehavior = new CantFly();
}
}
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Duck justDuck = new JustDuck();
justDuck.howToFly();
Log.d("abcd","날 수는 있니? "+justDuck.howToFly());
}
}
결과 : 날 수는 있니? 날고 싶어도 못날아요~
디자인 원칙 : 상속보다는 구성을 활용한다.
------------------- kotlin -------------------
open class Duck {
var flyBehavior:FlyBehavior? = null
fun howToFly() : String? {
return flyBehavior?.fly()
}
}
//
interface FlyBehavior {
fun fly() : String?
}
//
class CantFly : FlyBehavior{
override fun fly(): String {
return "날고 싶어도 못날아용~"
}
}
//
class JustDuck : Duck() {
init {
flyBehavior = CantFly()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val justDuck:Duck = JustDuck()
Log.d("abcd","결과 : "+justDuck.howToFly())
}
}
결과 : 날고 싶어도 못날아용~
반응형
'개발공부 > 디자인 패턴' 카테고리의 다른 글
자바 및 코틀린 팩토리(factory)패턴이란? (0) | 2022.01.15 |
---|---|
자바 및 코틀린 객체지향패턴 데코레이터(decorator)패턴 (0) | 2022.01.10 |
자바 및 코틀린 객체지향패턴 (Observer 패턴) (0) | 2022.01.06 |
책 이름 : Head First Design Pattern (0) | 2022.01.03 |
패턴을 공부하는 이유 (0) | 2021.08.03 |