ãç¹å¥ã³ã©ã ãçŸå Žã§åœ¹ç«ã€ãã¶ã€ã³ãã¿ãŒã³å
¥é ãGoFã®ç¥æµãšçŸä»£C++ã®èšèšçŸåŠã
ãããããäœã®ããã«ããã®ãïŒãããå
žå3åé¡ã®å®è£
ã³ãŒããã¢ãã³C++ã§ã®ã¹ããŒããªé²åãšéå°èšèšã®çœ ãŸã§
ããã¶ã€ã³ãã¿ãŒã³ãšããèšèã¯èãããã©ããªãå¿
èŠãªã®ãïŒãããã€ãã©ã䜿ãã°ããã®ãïŒããšããçåã«çããŸããå»ºç¯ææ³ããGoFïŒGang of FourïŒã«ãã23ãã¿ãŒã³ãžã®ç³»èããªããžã§ã¯ãæåèšèšã®ååïŒSOLIDïŒããããŠçŸå Žã§é »åºãã代衚çãã¿ãŒã³ïŒSingleton, Factory Method, Adapter, Strategy, ObserverïŒããC++ã®å
·äœäŸã³ãŒãä»ãã§åŸ¹åºè§£èª¬ãããã«ã¢ãã³C++ã§ã®ã¹ããŒããªå®è£
æ³ããåå¿è
ãé¥ããã¡ãªããã¿ãŒã³äžæ¯ïŒéå°èšèšïŒããžã®åŠæ¹ç®ãŸã§ãäœç³»åããŸããã
1. ãããããã¶ã€ã³ãã¿ãŒã³ãšã¯äœãïŒ ãå
人ãã¡ã®ãååä»ãç¥æµè¢ãã
ãã¶ã€ã³ãã¿ãŒã³ãšã¯ãåãªãé£è§£ãªããã°ã©ãã³ã°æ§æã§ã¯ãããŸãããå
茩ããã°ã©ããã¡ã幟å€ã®å€±æãšãªãã¡ã¯ã¿ãªã³ã°ã®æ«ã«èŠåºãããåå©çšå¯èœãªèšèšã®å®ç³ïŒãã¹ããã©ã¯ãã£ã¹ïŒãã§ãã
ð§ ãã³ã®ã³å
茩
æå°å®ïŒããã°ã©ãã³ã°ã®èšäºãèšèšã¬ãã¥ãŒãèŠãŠãããšããããã¯Strategyãã¿ãŒã³ã«ãããããšããSingletonã䜿ããããšãã£ãåèªãé »ç¹ã«åºãŠããŸããããã£ãŠC++ã®æ°ããæ©èœãã©ã€ãã©ãªã®ååãªãã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
è¯ãççŒç¹ãããªããã³ã®ã³ïŒãã¶ã€ã³ãã¿ãŒã³ã¯èšèªæ©èœãã©ã€ãã©ãªã®åºæåè©ã§ã¯ãªãããªããžã§ã¯ãæåããã°ã©ãã³ã°ã«ãããŠãé »åºããåé¡ãã«å¯ŸããŠãå
人ãã¡ãç·šã¿åºãããåªããèšèšã®åçŽïŒã²ãªåœ¢ïŒãã®ããšããã
ð§ ãã³ã®ã³å
茩
èšèšã®åçŽâŠâŠïŒåçŽããããšãäœãå¬ãããã§ããããïŒèªåãªãã«åãã³ãŒããæžããŠããã°ãããã§ååãªæ°ãããã®ã§ããâŠâŠã
ð»ââïž ã·ãã¯ãå
ç
ãµãµãµããåãã³ãŒãããšã倿Žã«èããããã³ãŒããã¯å
šãå¥ç©ãªããããããã«ããã¿ãŒã³ãç¥ãæå€§ã®ã¡ãªããã¯ãããã°ã©ãå士ã®è¶
é«éãªææçéïŒå
±éèšèªïŒãã«ããããŸãã¯ãã®æŽå²ãšäŸ¡å€ããçŽè§£ããŠãããïŒ
### 1.1 èµ·æºãšæŽå²ïŒå»ºç¯ãããœãããŠã§ã¢ãžããããŠGoFã®èªç
ããã¶ã€ã³ãã¿ãŒã³ããšããæŠå¿µã¯ãå®ã¯ããã°ã©ãã³ã°ã®äžçã§çãŸãããã®ã§ã¯ãããŸããã
1970幎代ãéœåžèšç»å®¶ã»å»ºç¯å®¶ã§ãã**ã¯ãªã¹ããã¡ãŒã»ã¢ã¬ã°ã¶ã³ããŒïŒChristopher AlexanderïŒ**ãããäœã¿ãããè¡ã建ç©ã«ã¯ãå
±éããŠç¹°ãè¿ãçŸãã空éã®ãã¿ãŒã³ãããããšæå±ããã®ãçºç«¯ã§ãã
ããããœãããŠã§ã¢èšèšã«å¿çšãã1994幎ã«äžççãã¹ãã»ã©ãŒãšãªã£ãåèãïŒ
> **ããªããžã§ã¯ãæåã«ãããåå©çšã®ããã®ãã¶ã€ã³ãã¿ãŒã³ã**
> ïŒåé¡: *Design Patterns: Elements of Reusable Object-Oriented Software*ïŒ
èè
ã®4人ïŒãšãªãã¯ã»ã¬ã³ãããªãã£ãŒãã»ãã«ã ãã©ã«ãã»ãžã§ã³ãœã³ããžã§ã³ã»ããªã·ãã£ãŒã¹ïŒã¯èŠªæã𿬿ã蟌ããŠ**ãGoFïŒGang of Four: 4人ã®ã®ã£ã³ã°ïŒã**ãšåŒã°ãã圌ãããŸãšãã**23çš®é¡ã®èšèšãã¿ãŒã³**ããçŸä»£ã®ãœãããŠã§ã¢èšèšã®å
±éèŠæ ŒãšãªããŸããã
---
### 1.2 ãªããã¶ã€ã³ãã¿ãŒã³ãå¿
èŠãªã®ãïŒïŒ3倧ã¡ãªããïŒ
åå¿è
ã¯ãåãã°äœã§ãããããšèããã¡ã§ãããéçºèŠæš¡ã倧ãããªããšã仿§å€æŽããšããèæ³¢ãæŒãå¯ããŸãããã¶ã€ã³ãã¿ãŒã³ãåŠã¶æ¬è³ªçãªçç±ã¯3ã€ãããŸãã
#### â è»èŒªã®åçºæãšå°é·ã®åé¿
ãœãããŠã§ã¢ã®æŽå²ã«ãããŠãå
人ãã¡ãããªããšå
šãåãã仿§è¿œå ã§ã³ãŒããã¹ãã²ãã£åãããã1ç®æçŽãããç¡é¢ä¿ãªå Žæãå£ããããšããå°é·ãèžãã§ããŸããã
ãã¶ã€ã³ãã¿ãŒã³ã¯ããã®å°é·åãå®å
šã«è¿åããããã®**ãæ€èšŒæžã¿ã®èè£
éè·¯ã**ã§ãã
#### â¡ ããŒã ã®å
±éèšèªïŒå
±éããã£ãã©ãªãŒïŒã®ç²åŸ
ãããããçŸå Žã§æãçµ¶å€§ãªæ©æµã§ãã
- **ãã¿ãŒã³ãç¥ããªãäŒè©±**:
> ãAã¯ã©ã¹ã®äžã«BãšCã®ã€ã³ã¹ã¿ã³ã¹çæãçŽæžããããšå·®ãæ¿ãã倧å€ã ãããçæçšã®å¥ã¯ã©ã¹ãäœã£ãŠãããããå
±éåºåºã¯ã©ã¹ã®ãã€ã³ã¿ãè¿ãããã«ããŠãåŒã³åºãåŽã¯å
·è±¡åãç¥ããªãããã«ãããã
- **ãã¿ãŒã³ãç¥ã£ãŠããäŒè©±**:
> ããã㯠**Factory Method** ã«ãããã
ãã£ãäžèšã§ãèšèšã®æå³ã»æ§é ã»äŸåé¢ä¿ãããŒã å
šå¡ã®é ã«å¯žåéããå
±æãããŸããææçéã®ã³ã¹ããåçã«äžããã®ã§ãã
#### ⢠ãªããžã§ã¯ãæåã®ååïŒSOLIDïŒã®å
·çŸå
åªããã³ãŒãã®ååãšããŠæåãª**SOLIDåå**ïŒç¹ã«ãéæŸééåå: OCPãããäŸåæ§é転åå: DIPãïŒããããããã¹ããŒã¬ã³ãã§çµããããã**ãå
·äœçã«ã©ãã¯ã©ã¹ãçµãã°å®çŸã§ããã®ãïŒããšããçãã®ã«ã¿ãã°**ããããã¶ã€ã³ãã¿ãŒã³ãªã®ã§ãã
2. ãã¶ã€ã³ãã¿ãŒã³ã®3倧åé¡ ãç®çå¥ã«æŽçãã23ã®å°å³ã
GoFã®23ãã¿ãŒã³ã¯ããã®åœ¹å²ãšç®çã«ãã£ãŠãçæïŒCreationalïŒããæ§é ïŒStructuralïŒããæ¯ãèãïŒBehavioralïŒãã®3ã€ã®å€§ã°ã«ãŒãã«äœç³»åãããŠããŸãã
ð§ ãã³ã®ã³å
茩
23åãïŒïŒæå°å®ãæ°ç±³ã®åã23åå
šéšãä»ããæèšããªãããããªããã§ããããâŠïŒååãèŠãã ãã§ããŸããâŠïŒ
ð»ââïž ã·ãã¯ãå
ç
å®å¿ããïŒ23åãã¹ãŠãæèšããå¿
èŠã¯ãŸã£ãããªããããã©ã³ãšã³ãžãã¢ã§ãæ¥åžžçã«äœ¿ãã®ã¯ãã®ãã¡ã®5ã7åçšåºŠããã倧äºãªã®ã¯ãäžžæèšãã§ã¯ãªãã3ã€ã®åœ¹å²ïŒåé¡ïŒãã®æèŠãæŽãããšãããïŒ
### ãã¶ã€ã³ãã¿ãŒã³ 3倧åé¡ã®é³¥ç°å³
| åé¡ | ç®çïŒäœã解決ãããïŒïŒ | 代衚çãªGoFãã¿ãŒã³ |
| :--- | :--- | :--- |
| **çæã«é¢ãããã¿ãŒã³**<br>*(Creational)* | ãªããžã§ã¯ãã®**ãã€ã³ã¹ã¿ã³ã¹åïŒnewïŒã**ãæè»ã«ããå
·è±¡ã¯ã©ã¹ãšã®çµå床ãäžãã | **Singleton**, **Factory Method**, Abstract Factory, Builder, Prototype |
| **æ§é ã«é¢ãããã¿ãŒã³**<br>*(Structural)* | ã¯ã©ã¹ããªããžã§ã¯ããçµã¿åãããŠã**æè»ã§å€§ããªæ§é **ããã£ãããšçµã¿ç«ãŠã | **Adapter**, **Composite**, Decorator, Facade, Proxy, Bridge, Flyweight |
| **æ¯ãèãã«é¢ãããã¿ãŒã³**<br>*(Behavioral)* | ãªããžã§ã¯ãå士ã®**ã飿ºã»ã¡ãã»ãŒãžäŒéã»åœ¹å²åæ
ã**ãæŽçãã倿Žã屿åãã | **Strategy**, **Observer**, **State**, Command, Template Method, Iterator, Visitor |
---
### ååé¡ã®çŽæçã€ã¡ãŒãž
```
ãçæç³» (Creational)ã
ãã©ãçã¿åºããïŒã
çŽæ¥ new ããã®ããããçææ¹æ³ãé èœããããå¯äžã®ååšãä¿èšŒããã
äŸ: ã¢ã³ã¹ã¿ãŒçæå·¥å Žãèšå®ããŒã¿ã®å¯äžã€ã³ã¹ã¿ã³ã¹
ãæ§é ç³» (Structural)ã
ãã©ãç¹ãåããããïŒã
圢ã®åããªãã€ã³ã¿ãŒãã§ãŒã¹ã倿ããããéšåãæããŠ1ã€ã®ããã«èŠããã
äŸ: å€ãã©ã€ãã©ãªã®å€æãã©ã°ããã©ã«ããšãã¡ã€ã«ã®é局管ç
ãæ¯ãèãç³» (Behavioral)ã
ãã©ãåããåããïŒã
ã¢ã«ãŽãªãºã ãéšååããŠå·®ãæ¿ããããç¶æ
å€åã仲éã«äžæéç¥ããã
äŸ: AIã®è¡åãã¿ãŒã³ã®å·®ãæ¿ããã€ãã³ãéç¥ãªã¹ããŒ
```
3. çŸå Žã§é »åºããå
žåçãã¿ãŒã³ãšC++ã³ãŒãå®è·µ
å®åã»ã²ãŒã éçºã§ãããã ãã¯çµ¶å¯Ÿã«æŒãããŠããã¹ãããšèšããè¶
éèŠãã¿ãŒã³ããC++ã®å
·äœçã³ãŒããšãšãã«ãã¹ã¿ãŒããŸãããã
### â ãçæç³»ãMeyers' SingletonïŒã·ã³ã°ã«ãã³ïŒ
#### ç®çãšäœ¿ãã©ãã
- **ç®ç**: ããã°ã©ã å
šäœã§**ã絶察ã«1ã€ã ãããååšããªãã€ã³ã¹ã¿ã³ã¹ã**ãä¿èšŒããã©ãããã§ãã¢ã¯ã»ã¹ã§ããããã«ããã
- **䜿ãã©ãã**: èšå®ãã¡ã€ã«ç®¡çïŒConfigManagerïŒããªãŒãã£ãªãšã³ãžã³ïŒSoundManagerïŒããã°èšé²ïŒLoggerïŒãªã©ã
#### C++ã«ããããã¹ããã©ã¯ãã£ã¹ïŒMeyers' SingletonïŒ
ãã€ãŠã®C++03ã§ã¯ãã¹ã¬ããã»ãŒãã«ããããã«è€éãªäºéãã§ãã¯ãããã³ã°ïŒDouble-Checked LockingïŒãæžãå¿
èŠããããŸãããããã**C++11以éã§ã¯ãã颿°ã®éçããŒã«ã«å€æ°ã®åæåã¯ã¹ã¬ããã»ãŒãã§ããããšããèšèªä»æ§ïŒMagic StaticïŒãå®ããããŸãã**ã
ãããå©çšããã®ããåèãEffective C++ãã®èè
ã¹ã³ããã»ã¡ã€ã€ãŒãºãæå±ãã**ãMeyers' Singletonã**ã§ãã
```cpp
#include <iostream>
#include <string>
class SoundManager {
public:
// ã³ããŒãšä»£å
¥ãæç€ºçã«çŠæ¢ïŒå¯äžæ§ã®æ
ä¿ïŒ
SoundManager(const SoundManager&) = delete;
SoundManager& operator=(const SoundManager&) = delete;
SoundManager(SoundManager&&) = delete;
SoundManager& operator=(SoundManager&&) = delete;
// å¯äžã®ã€ã³ã¹ã¿ã³ã¹ãååŸããéç颿°
static SoundManager& getInstance() {
// C++11èŠæ Œã«ãããåååŒã³åºãæã«ã¹ã¬ããã»ãŒãã«1床ã ãåæåããã
static SoundManager instance;
return instance;
}
void playBgm(const std::string& trackName) {
std::cout << "⪠BGMåçäž: " << trackName << std::endl;
}
private:
// ã³ã³ã¹ãã©ã¯ã¿ã private ã«ããŠå€éšããã®çŽæ¥çæãçŠæ¢
SoundManager() {
std::cout << ">> SoundManager åæåå®äº" << std::endl;
}
~SoundManager() = default;
};
// äœ¿ãæ¹
int main() {
// ã©ãããã§ãåãã€ã³ã¹ã¿ã³ã¹ã«ã¢ã¯ã»ã¹ã§ãã
SoundManager::getInstance().playBgm("battle_theme.ogg");
SoundManager::getInstance().playBgm("victory_fanfare.ogg");
return 0;
}
```
---
### â¡ ãçæç³»ãFactory MethodïŒãã¡ã¯ããªã¡ãœããïŒ
#### ç®çãšäœ¿ãã©ãã
- **ç®ç**: åŒã³åºãå
ãå
·è±¡ã¯ã©ã¹åïŒ`new Goblin()`, `new Dragon()`ïŒãçŽæ¥èšè¿°ããã®ãé¿ãã**çæããžãã¯ãåé¢ã»é èœ**ããã
- **䜿ãã©ãã**: ãããäžã®æµãã£ã©ã¯ã¿ãŒã®åçåºçŸããã¡ã€ã«æ¡åŒµåã«å¿ããç»åããŒããŒã®éžæã
```cpp
#include <iostream>
#include <memory>
#include <string>
// å
±éã€ã³ã¿ãŒãã§ãŒã¹
class Monster {
public:
virtual ~Monster() = default;
virtual void attack() = 0;
};
class Slime : public Monster {
public:
void attack() override { std::cout << "ã¹ã©ã€ã ãäœåœããããŠããïŒïŒåŒ±ïŒ" << std::endl; }
};
class Dragon : public Monster {
public:
void attack() override { std::cout << "ãã©ãŽã³ãçŒç±ã®çãåããïŒïŒåŒ·ïŒ" << std::endl; }
};
// ãã¡ã¯ããªïŒçæã¯ã©ã¹ïŒ
class MonsterFactory {
public:
// C++11以éã¯çãã€ã³ã¿ã§ã¯ãªã std::unique_ptr ãè¿ãã®ãéå
static std::unique_ptr<Monster> createMonster(const std::string& type) {
if (type == "slime") {
return std::make_unique<Slime>();
} else if (type == "dragon") {
return std::make_unique<Dragon>();
}
return nullptr;
}
};
// äœ¿ãæ¹ïŒåŒã³åºãåŽã¯å
·äœç㪠Slime ã Dragon ã®åå®çŸ©ãç¥ãå¿
èŠããªã
int main() {
auto m1 = MonsterFactory::createMonster("slime");
if (m1) m1->attack();
auto m2 = MonsterFactory::createMonster("dragon");
if (m2) m2->attack();
return 0;
}
```
---
### â¢ ãæ§é ç³»ãAdapterïŒã¢ããã¿ïŒ
#### ç®çãšäœ¿ãã©ãã
- **ç®ç**: ãäžèº«ã®æ©èœã¯äœ¿ãããããã€ã³ã¿ãŒãã§ãŒã¹ïŒé¢æ°åãåŒæ°ïŒãåããªããæ¢åã®ã¯ã©ã¹ãã**倿ãã©ã°ãåãŸããŠç®çã®ã€ã³ã¿ãŒãã§ãŒã¹ã«é©å**ãããã
- **䜿ãã©ãã**: ã¬ã¬ã·ãŒãªå€ãèªç€Ÿã³ãŒãããå€éšãµãŒãããŒãã£è£œã©ã€ãã©ãªãèªç€Ÿã·ã¹ãã ã®èšèšã«åãããŠçµã¿èŸŒã¿ãããšãã
```cpp
#include <iostream>
#include <memory>
// èªç€Ÿã²ãŒã ãšã³ãžã³ãèŠæ±ããææ°ã€ã³ã¿ãŒãã§ãŒã¹
class IModernAudio {
public:
virtual ~IModernAudio() = default;
virtual void playAudio(float volume) = 0;
};
// å°å
¥ãããå€éšã®å€ãã¬ã¬ã·ãŒé³æºã©ã€ãã©ãªïŒæ¹å€äžå¯ïŒ
class LegacySoundLib {
public:
// 颿°åãåŒæ°ïŒ0-100ã®æŽæ°ïŒãèªç€ŸèŠæ ŒãšåããªãïŒ
void execute_sound_playback(int volumePercent) {
std::cout << "[Legacy Lib] é³å£°åç Volume: " << volumePercent << "%" << std::endl;
}
};
// ã¢ããã¿ïŒäž¡è
ã®æºãåãã倿ãã©ã°
class AudioAdapter : public IModernAudio {
private:
LegacySoundLib m_legacyLib; // å§è²ïŒåæïŒã§ä¿æ
public:
void playAudio(float volume) override {
// float(0.0f - 1.0f) ã int(0 - 100) ã«å€æããŠä»²ä»
int convertedVol = static_cast<int>(volume * 100.0f);
m_legacyLib.execute_sound_playback(convertedVol);
}
};
int main() {
// ã¯ã©ã€ã¢ã³ãã³ãŒã㯠IModernAudio ã ããèŠãŠæäœã§ãã
std::unique_ptr<IModernAudio> audio = std::make_unique<AudioAdapter>();
audio->playAudio(0.85f); // å
éšã§å€æãããŠå€ãã©ã€ãã©ãªãåãïŒ
return 0;
}
```
---
### â£ ãæ¯ãèãç³»ãStrategyïŒã¹ãã©ããžãŒïŒ
#### ç®çãšäœ¿ãã©ãã
- **ç®ç**: ã¢ã«ãŽãªãºã ïŒæŠç¥ã»èšç®æ¹æ³ã»AIæèãªã©ïŒãã¯ã©ã¹ãšããŠéšååãã**å®è¡æã«èªç±èªåšã«å·®ãæ¿ãå¯èœ**ã«ããã
- **䜿ãã©ãã**: ãã£ã©ã¯ã¿ãŒã®ç§»åã»æ»æã¢ã«ãŽãªãºã ãã²ãŒã ã®é£æåºŠå¥AIã«ãŒãã³ã決æžåŠçæ¹åŒïŒã¯ã¬ã«/PayPay/çŸéïŒã®åãæ¿ãã
```cpp
#include <iostream>
#include <memory>
// æŠç¥ã€ã³ã¿ãŒãã§ãŒã¹
class AttackStrategy {
public:
virtual ~AttackStrategy() = default;
virtual void executeAttack() = 0;
};
// å
·äœçãªæŠç¥A: è¿æ¥å£æ
class SwordAttack : public AttackStrategy {
public:
void executeAttack() override { std::cout << "å£ãæ¿ããæ¯ãäžãããïŒ [è¿æ¥ç©ç]" << std::endl; }
};
// å
·äœçãªæŠç¥B: é è·é¢éæ³
class MagicAttack : public AttackStrategy {
public:
void executeAttack() override { std::cout << "巚倧ãªç«çãæã¡æŸã£ãïŒ [é è·é¢éæ³]" << std::endl; }
};
// æŠç¥ãå©çšãããã£ã©ã¯ã¿ãŒ
class Player {
private:
std::unique_ptr<AttackStrategy> m_strategy;
public:
void setStrategy(std::unique_ptr<AttackStrategy> strategy) {
m_strategy = std::move(strategy);
}
void attack() {
if (m_strategy) {
m_strategy->executeAttack();
}
}
};
int main() {
Player player;
// ç¶æ³ã«å¿ããŠæŠç¥ãåãæ¿ãã
player.setStrategy(std::make_unique<SwordAttack>());
player.attack(); // 壿»æ
player.setStrategy(std::make_unique<MagicAttack>());
player.attack(); // éæ³æ»æã«å³åº§ã«å€åïŒ
return 0;
}
```
#### ð¡ ã¢ãã³C++ã§ã®é²åïŒ`std::function` ã«ããã¯ã©ã¹ã¬ã¹Strategy
ã¢ãã³C++ïŒC++11以éïŒã§ã¯ãããããåºåºã¯ã©ã¹ã掟çã¯ã©ã¹ãäœããªããŠãã`std::function` ãšã©ã ãåŒã䜿ãããšã§**è¶
軜éã«Strategyãã¿ãŒã³ãå®çŸ**ã§ããŸãïŒ
```cpp
#include <iostream>
#include <functional>
class ModernPlayer {
public:
// 颿°ãªããžã§ã¯ããšããŠæŠç¥ãä¿æïŒä»®æ³é¢æ°ã®ãã€ã©ãŒãã¬ãŒããäžèŠïŒïŒ
using AttackFunc = std::function<void()>;
void setAttackAction(AttackFunc action) {
m_attackAction = action;
}
void attack() {
if (m_attackAction) m_attackAction();
}
private:
AttackFunc m_attackAction;
};
int main() {
ModernPlayer player;
// ã©ã ãåŒã§ãã®å Žã§æŠç¥ãæž¡ããïŒ
player.setAttackAction([]() { std::cout << "åŒç¢ã§ç²Ÿå¯å°æïŒ" << std::endl; });
player.attack();
return 0;
}
```
4. ã¢ãã³C++ã§ã®é²åãšããã¿ãŒã³äžæ¯ïŒéå°èšèšïŒãã®çœ
ãã¶ã€ã³ãã¿ãŒã³ã¯åŒ·åãªæŠåšã§ãããäœ¿ãæ¹ã誀ããšã³ãŒãããŒã¹ãç Žæ»
ããããæ¯ãã«ããªããŸãã
ð§ ãã³ã®ã³å
茩
æå°å®âŠâŠå®ã¯åçœããããŸãããã¿ãŒã³ãåŠãã§å¬ãããªã£ãŠããã£ã10è¡ã§æžãããã°ã©ã ã«FactoryãšSingletonãšObserverãå
šéšçµã¿èŸŒãã ããã¯ã©ã¹ã8åã«å¢ããŠãèªåã§ãäœãã©ãã§åããŠããã®ãåãããªããªã£ãŠããŸããŸããâŠâŠã
ð»ââïž ã·ãã¯ãå
ç
ã¬ããïŒèª°ããäžåºŠã¯éãééå瀌ãããªïŒãããæ¥çã§ã¯ãé»éã®ãã³ããŒçå矀ããããã¿ãŒã³äžæ¯ïŒPatternitisïŒããšåŒã¶ããæå
ã«éæ§ããããšãç®ã«å
¥ããã¹ãŠã®ãã®ãéã«èŠããŠå©ããããªãããšããå¿çããïŒ
### 4.1 ãã¿ãŒã³äžæ¯ãšãéå°èšèšïŒOver-engineeringïŒãã®ææ
ãã¶ã€ã³ãã¿ãŒã³ãèŠãããŠã®æ°äººãæãé¥ããããã®ã**ãéå°ãªæœè±¡åã**ã§ãã
- ãå°æ¥ãæµã®çš®é¡ã100çš®é¡ã«å¢ãããããããªãããFactoryãäœã£ãŠãããã
- ãå°æ¥ãç»é¢åºåå
ãVRã«ãªããããããªãããBridgeãšAdapterãæãã§ãããã
ãã®çµæã**ãå®éã«ã¯æµã¯2çš®é¡ããåºããVRã«ã察å¿ããªãã£ãã**ãšãããªãã«ãªããæ®ã£ãã®ã¯**ç¡é§ã«é£è§£ã§ã¹ãããå®è¡ãããŸãŸãªããªãè¿·å®®ã³ãŒã**ã§ãã
> **èšèšã®éå: YAGNIååïŒYou Aren't Gonna Need ItïŒ**
> ãä»å¿
èŠãªæå°éã®ã·ã³ãã«ãã§äœããå°æ¥å¿
èŠã«ãªã£ããã®æã«ãåããŠãªãã¡ã¯ã¿ãªã³ã°ããŠãã¿ãŒã³ãé©çšããã°ããã
---
### 4.2 C++ç¹æã®èœãšã穎ïŒGoFãã¿ãŒã³ãšå®è¡æã³ã¹ãïŒvtableã»ããŒãïŒ
GoFã®ãã¶ã€ã³ãã¿ãŒã³åèïŒ1994幎ïŒã¯ãäž»ã«**SmalltalkãJava**ãšãã£ãããã¹ãŠããªããžã§ã¯ãåç
§ã§ãããã¬ããŒãžã³ã¬ã¯ã·ã§ã³åæãã®èšèªææ³ã®åœ±é¿ã匷ãåããŠããŸãã
ãããã**C++ã¯ããŒããªãŒããŒãããååããä¿¡æ¡ãšãããã€ããã©ãŒãã³ã¹èšèª**ã§ããC++ã§GoFãã¿ãŒã³ãé¡é¢éãã«é©çšãããšã以äžã®ä»£åãæ¯æãããšã«ãªããŸãã
1. **ä»®æ³é¢æ°ããŒãã«ïŒvtableïŒéæ¥åç
§ã®ã³ã¹ã**:
- ãã¹ãŠã®ãã¿ãŒã³ãåºåºã¯ã©ã¹ã® `virtual` 颿°ã§å®è£
ãããšãCPUã®ã€ã³ã©ã€ã³å±éãé»å®³ãããåå²äºæž¬ãã¹ããã£ãã·ã¥ãã¹ãèªçºããŸãã
2. **é »ç¹ãªããŒãå²ãåœãŠïŒ`new` / `make_unique`ïŒ**:
- å°ããªãªããžã§ã¯ããããŒãäžã«ã°ãæããšãã¡ã¢ãªæçåãšãã£ãã·ã¥å±ææ§ã®äœäžãæããŸãã
#### ð ã¢ãã³C++æµã®è§£æ±ºã¢ãããŒã
| äŒçµ±çGoFã®ã¢ãããŒã | ã¢ãã³C++ïŒC++17/20ïŒã®ã¢ãããŒã | ã¡ãªãã |
| :--- | :--- | :--- |
| **åçããªã¢ãŒãã£ãºã **<br>(`virtual` 颿° + ç¶æ¿) | **éçããªã¢ãŒãã£ãºã **<br>(ãã³ãã¬ãŒã, ã³ã³ã»ãã, CRTP) | ä»®æ³é¢æ°åŒã³åºãã³ã¹ããŒããã³ã³ãã€ã«æã€ã³ã©ã€ã³åã§çé |
| **Strategy ãã¿ãŒã³**<br>(å
·è±¡æŠç¥ã¯ã©ã¹ã倿°äœæ) | **`std::function` ã ã©ã ãåŒ** | ã¯ã©ã¹å®çŸ©äžèŠãã³ãŒããçãèŠéããè¯ã |
| **Visitor ãã¿ãŒã³**<br>(è€éãªããã«ãã£ã¹ããã) | **`std::variant` + `std::visit`** | ç¶æ¿é¢ä¿ã®ãªãå®å
šãªåå®å
šãã¿ãŒã³ãããã³ã° |
| **Singleton ãã¿ãŒã³**<br>(ã°ããŒãã«å¯èŠæ§ã»åäžã€ã³ã¹ã¿ã³ã¹) | **äŸåæ§æ³šå
¥ïŒDI: åç
§æž¡ãïŒ** | ãã¹ã¿ããªãã£ãåäžããé ãã倧åçµåãé²ãã |
5. ãŸãšãïŒè¯ãèšèšè
ã®ããã®ãã§ãã¯ãªã¹ã
ãã¿ãŒã³ã¯ãæèšããŠåŽããåªæãã§ã¯ãªããå
人ãšå¯Ÿè©±ããããã®ãéå
·ç®±ãã§ãã
### ãã¿ãŒã³é©çšåã®ã»ã«ããã§ãã¯ãªã¹ã
ã³ãŒããæžããšãã以äžã®è³ªåãèªåã«æããããŠã¿ãŠãã ããã
- [ ] **Q1. ãã®æœè±¡åã¯ãä»ãå¿
èŠãïŒ**
- åãªãåŠæ³ã®å°æ¥äºæž¬ïŒYAGNIéåïŒã§ã¯ãªããïŒ
- [ ] **Q2. 2ã3åã®éè€ãå®éã«çºçãããïŒ**
- æåãããã¿ãŒã³ãåœãŠã¯ããã®ã§ã¯ãªãããŸãã¯ã·ã³ãã«ã«æžããéè€ã仿§å€æŽã®çã¿ãæããç¬éã«é©çšããã®ããã¹ãïŒRule of ThreeïŒã
- [ ] **Q3. C++ã®æ§èœèŠä»¶ãæºãããŠãããïŒ**
- ã²ãŒã ã®æ¯ãã¬ãŒã 60FPSã§åŒã°ããã¿ã€ããªã«ãŒãå
ã§ãäžçšæã«ä»®æ³é¢æ°ãããŒãå²ãåœãŠãè¡ã£ãŠããªããïŒ
- [ ] **Q4. ããŒã å
šå¡ããã®æå³ãçè§£ã§ãããïŒ**
- èªå·±æºè¶³ã®ããªãããŒãªã³ãŒãã«ãªã£ãŠããªããïŒ
### ã·ãã¯ãæå°å®ã®éèš
> ããã¶ã€ã³ãã¿ãŒã³ãç¥ã£ãŠããè
ã¯ãèšèšã®ããã£ãã©ãªãŒãè±å¯ã§ããã
> ã ã**çã«åªããèšèšè
ãšã¯ãããã¿ãŒã³ã䜿ããã«æžããªããã©ããŸã§ãã·ã³ãã«ã«æžããããšãã§ããè
**ã§ãããã
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
- ãã¿ãŒã³ã®æ¬è³ªã¯ãå
±éèšèªã: èšèšã®æå³ãäžèšã§ããŒã ã«äŒããè»èŒªã®åçºæãšå°é·ãåé¿ããããã®å
人ã®ç¥æµè¢ã
- å
žå3倧åé¡ãæŒããã: çæç³»ïŒSingleton, FactoryïŒãæ§é ç³»ïŒAdapterïŒãæ¯ãèãç³»ïŒStrategy, ObserverïŒã®åœ¹å²ã®éããçè§£ããã
- ã¢ãã³C++ã§è³¢ã䜿ã: ä»®æ³é¢æ°ã®æ¿«çšã«æ³šæããstd::function ããã³ãã¬ãŒããã©ã ãåŒãçµã¿åããããŒããªãŒããŒããããªé©çšãæèããã
- ãã¿ãŒã³äžæ¯ïŒéå°èšèšïŒã«æ³šæ: YAGNIååãèžã«ããŸãã¯ã·ã³ãã«ã«æžããå¿
èŠæ§ãçããã¿ã€ãã³ã°ã§ãªãã¡ã¯ã¿ãªã³ã°ããã
ð ç解床ãã§ãã¯ã¯ã€ãº
Q1. GoFãã¶ã€ã³ãã¿ãŒã³ã®3倧åé¡ïŒçæã»æ§é ã»æ¯ãèãïŒã®ãã¡ããæ¯ãèãã«é¢ãããã¿ãŒã³ïŒBehavioralïŒãã«åé¡ããããã®ã¯ã©ãã§ããïŒ
- 1. Singleton ãã¿ãŒã³
- 2. Strategy ãã¿ãŒã³
- 3. Adapter ãã¿ãŒã³
- 4. Factory Method ãã¿ãŒã³
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒStrategy ãã¿ãŒã³
Strategy ã Observer ã¯ãªããžã§ã¯ãéã®ã¢ã«ãŽãªãºã ã責任ã®å§è²ãã€ãã³ãéç¥ãªã©ã®åçãªå調é¢ä¿ãå®çŸ©ãããæ¯ãèãïŒBehavioralïŒããã¿ãŒã³ã§ããSingleton ã Factory ã¯çæç³»ãAdapter ã¯æ§é ç³»ã«åé¡ãããŸãã
Q2. C++11以éã§ãã¹ã¬ããã»ãŒã㪠Singletonããæãå®å
šãã€ã·ã³ãã«ã«å®è£
ããææ³ïŒMeyers' SingletonïŒãšããŠæ£ãããã®ã¯ã©ãã§ããïŒ
- 1. ã°ããŒãã«å€æ°ãšããŠã€ã³ã¹ã¿ã³ã¹ãäºåå®çŸ©ããŠãã
- 2. getInstance() 颿°å
ã®ããŒã«ã«éç倿°ïŒstatic MyClass instance;ïŒãšããŠå®çŸ©ãããã®åç
§ãè¿ã
- 3. std::mutex ã䜿ã£ãŠæåã§äºéãã§ãã¯ãããã³ã°ïŒDCLPïŒãçµã
- 4. ããŒãäžã« new ããŠãã€ã³ã¿ã volatile 修食ãã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒgetInstance() 颿°å
ã®ããŒã«ã«éç倿°ïŒstatic MyClass instance;ïŒãšããŠå®çŸ©ãããã®åç
§ãè¿ã
C++11ã®èšèªä»æ§ã«ãããŠã颿°ã®ããŒã«ã«éç倿°ã®åæåã¯ã¹ã¬ããã»ãŒãã§ããããšæèšãããããã颿°å
ã® `static T instance;` ãè¿ãã ãã§ãã¥ãŒããã¯ã¹ã®æç€ºçããã¯ãªãã«å®å
šå®å
šãªã·ã³ã°ã«ãã³ãå®çŸããŸãã
Q3. ãã¶ã€ã³ãã¿ãŒã³ãé©çšããéãåå¿è
ãé¥ããã¡ãªããã¿ãŒã³äžæ¯ïŒéå°èšèšïŒããé²ãããã®é©åãªæéã¯ã©ãã§ããïŒ
- 1. ãã¹ãŠã®ã¯ã©ã¹ã«å¿
ãGoFã®ããããã®ãã¿ãŒã³ã1ã€ä»¥äžé©çšãã
- 2. ããã€ã䜿ããããããªãããšããå°æ¥äºæž¬ã§äœããïŒYAGNIååïŒããŸãã¯ã·ã³ãã«ã«æžããéè€ã倿Žã®çã¿ãçºçããæ®µéã§ãªãã¡ã¯ã¿ãªã³ã°ãšããŠé©çšãã
- 3. ãã¹ãŠã®é¢æ°åŒã³åºããä»®æ³é¢æ°ããŒãã«çµç±ã«ãã
- 4. ãã¶ã€ã³ãã¿ãŒã³ã®äœ¿çšããããžã§ã¯ãå
šäœã§äžåçŠæ¢ãã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒããã€ã䜿ããããããªãããšããå°æ¥äºæž¬ã§äœããïŒYAGNIååïŒããŸãã¯ã·ã³ãã«ã«æžããéè€ã倿Žã®çã¿ãçºçããæ®µéã§ãªãã¡ã¯ã¿ãªã³ã°ãšããŠé©çšãã
ãã¶ã€ã³ãã¿ãŒã³ã¯ç®çã§ã¯ãªãææ®µã§ããæåããéåºŠã«æœè±¡åãããšå¯èªæ§ãšå®è¡é床ãäœäžããŸããYAGNIïŒYou Aren't Gonna Need ItïŒãæèãã3åéè€ããæïŒRule of ThreeïŒã仿§å€æŽãçããã¿ã€ãã³ã°ã§é©çšããã®ããã¹ããã©ã¯ãã£ã¹ã§ãã
ð»ââïž ã·ãã¯ãC++ã©ã ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ã·ã¹ãã
ãã©ãŠã¶ã§JavaScriptãæå¹ã«ãããšããã©ãŠã¶å
ã€ã³ããŒããŒã²ãŒã ãšãã¥ã¬ãŒã¿ãã¡ã¢ãªãããå¯èŠåãUMLã¯ã©ã¹å³ã察話å解説ãç解床ã¯ã€ãºãèµ·åããŸãã
ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ãéå§ãã â