Design Pattern --- (1) Strategy Pattern
===
[TOC]
## Where is strategy pattern used?
Situation:
基底class是duck,大部分鴨子會飛但有些不會,若不使用pattern會寫出這樣的code

這樣會導致即使fly的飛行行為一樣但只要會飛就要實作一次在子class,即copy paste,沒有reuse是OO不樂見的
## Solution by strategy pattern
strategy pattern by UML description:

透過另一個interface去完成行為
## Implementation
### java
```java=
class duck
{
FlyBehavior fb ;
public duck(FlyBehavior fb)
{
setFlyBehavior(fb);
}
public void setFlyBehavior(FlyBehavior fb)
{
this.fb = fb ;
}
public void performFly()
{
this.fb.fly();
}
}
interface FlyBehavior
{
void fly();
}
class CanFlyBehavior implements FlyBehavior
{
@Override
public void fly()
{
//fly method
}
}
class CanNotFlyBehavior implements FlyBehavior
{
@Override
public void fly()
{
//do nothing
}
}
public class Main
{
public static void main(String[] args)
{
Duck d1 = new Mallardduck(new CanFlyBehavior());
Duck d2 = new Rubberduck(new CanNotFlyBehavior());
d1.performFly();
//flying
d2.performFly();
//not able to fly
//d1 is not able to fly if it hurt its wings.
d1.setFlyBehavior(new CanNotFlyBehavior());
d1.performFly();
//not able to fly
}
}
```
### c++
```cpp=
#include <iostream>
#include <vector>
using namespace std;
class FlyBehavior
{
public:
FlyBehavior(){}
virtual ~FlyBehavior(){}
virtual void fly()=0;
};
class CanFlyBehavior : public FlyBehavior
{
public:
CanFlyBehavior(){}
virtual ~CanFlyBehavior(){}
virtual void fly();
};
class CanNotFlyBehavior : public FlyBehavior
{
public:
CanNotFlyBehavior(){}
virtual ~CanNotFlyBehavior(){}
virtual void fly();
};
void CanFlyBehavior::fly()
{
cout << "I can fly\n";
}
void CanNotFlyBehavior::fly()
{
cout << "I cannot fly\n";
}
class duck
{
public:
duck(FlyBehavior* _fb):FB(_fb){}
~duck(){}
void setFlyBehavior(FlyBehavior* fb);
FlyBehavior* FB;
};
void duck::setFlyBehavior(FlyBehavior* _fb)
{
this->FB = _fb;
}
int main()
{
CanNotFlyBehavior* CNFB = new CanNotFlyBehavior() ;
CanFlyBehavior* CFB= new CanFlyBehavior();
duck* MallardDcuk = new duck(CFB);
duck* RubberDcuk = new duck(CNFB);
vector<duck*> ducks= {MallardDcuk, RubberDcuk} ;
for(auto& d : ducks)
{
d->FB->fly();
}
cout << "change behavior\n";
MallardDcuk->setFlyBehavior(CNFB);
RubberDcuk->setFlyBehavior(CFB);
for(auto& d : ducks)
{
d->FB->fly();
}
return 0;
}
```
## Reference
https://www.youtube.com/watch?v=v9ejT8FO-7I&list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc
###### tags: `Design Pattern` `Java` `教學`