---
# System prepended metadata

title: オブジェクト指向(Object Oriented)開発について

---

# オブジェクト指向(Object Oriented)開発について

複数のPCを統合的に管理できるソフトを開発したい。

仕様は以下のような感じ。

![](https://hackmd.io/_uploads/r16muQ0V2.png)

## ストラクチャー考案


まずは入力出力のところが必ず必要です。
無難にそこは`UI`のクラスを作成、操作関係のコードを入れる。

そして、少なくとも複数台のPCの内容を保存しないといけないので、`Computer`クラスも作成。

```cpp
class UI {};
class Computer {};
int main() {};
```

もちろん、これは不足の部分もあるんです。
例えば、現在の状態を保持しているクラスがないため、

今はこれで基本の構成要素の設計を完成とする。

## 各オブジェクトの関係性

ここからこれらの関係性か考えながら、先設計したクラスを充実しよう

1. UI

    まず、`UI`から見るとたくさんの`Computer`があります。
    そしてどの`Computer`が使用中なのかを表すため、使用中のindexが必要です。

    ```cpp
    class UI 
    {
        vector<Computer> computers;
        int currentComputerIndex = -1; // -1 mean no computer selected
    };
    ```

2. Computer

    `Computer`自体の機能は設計されてないのですが、一応区別できるために名前を付ける。
    ```cpp
    class Computer
    {
        string name;
    };
    ```

これで根本の部分は以上のコードで表せるでしょう

### 機能設計

ちょっと戻して前の仕様を見てみよう

![](https://hackmd.io/_uploads/H1ZGGHAVh.png)

`UI`がやるべきことは使用しているPCを切り替える機能と全部のPCを追加/削除する機能。
あと特にUIの表現は決められてない。そこは自由発揮してもいいでしょう。

では`UI`を実行する開始関数と各機能の関数を追加する。

```cpp
class UI 
{
    vector<Computer> computers;
    int currentComputerIndex;
    
    void listHelpMessage(){};
    void listComputer(){};
    void addComputer(){};
    void deleteComputer(){};
    // 使用するPCを切り替える
    void useComputer(){};
    // コマンドをどの関数に入るのを割り当てる
    void parseCommand(string command){};
    
    // 実行関数
    void exec(){};
    
    UI(){};
}
```

これで各関数（メソッド）はすべて割と簡単な役割になっていました。
例えば`useComputer`関数を呼び出す場合、今所持している`computers`の配列から探して同じ名前の`computer`のindexを`currentComputerIndex`に保存すればいいです。

```cpp
    void useComputer()
    {
        string computerName;
        cout << "Computer name: ";
        cin >> computerName;

        for (int i = 0; i < computers->size(); i++)
        {
            Computer *computer = &computers->at(i);
            if (computer->getName() == computerName)
            {
                currentComputerIndex = i;
                cout << computer->getName() + " selected" << endl;
                return;
            }
        }
        cout << "Computer not found" << endl;
    }
```


こんな感じで、ひとつの関数は自分の役割を果たしていれば、プログラム全体が動ける。
そしてプログラムの開発はこれに沿ってどんな機能はどのクラスの役割によってそのクラスに実装する。

## 結論

役割分類の仕方は人それぞれなので、その人のドメインノーハウによってよりいい分け方に近づける。

もちろん、一般の教科書が言った、継承(Inheritance)、カプセル化(Encapsulation)、多型(Polymorphism)、なども大事ですが、個人的にはそれはいろんな開発を積み上げてそれら共通の法則を整理したものです。
定義なんとなく分かればいいと思います、それを全部はっきり理解しなくても開発はできるから。


## ソースコード

main.cpp
```cpp=
#include <iostream>

#include "UI.cpp"

using namespace std;

// main function
int main()
{
    UI *ui = new UI();
    ui->exec();
};
```

UI.cpp
```cpp=
#pragma once
#include <iostream>
#include <string>
#include <vector>

#include "Computer.cpp"

using namespace std;

class UI
{

private:
    
    vector<Computer> *computers;
    int currentComputerIndex;
    
    void listHelpMessage()
    {
        string result = "";
        result += "help: list all command\n";
        result += "list: list all computer\n";
        result += "exit: exit program\n";
        result += "addComputer: add new computer\n";
        result += "deleteComputer: delete computer\n";
        result += "useComputer: select computer\n";
        cout << result << endl;
    }

    void listComputer()
    {
        string result = "";
        for (int i = 0; i < computers->size(); i++)
        {
            result += computers->at(i).getName() + "\n";
        }
        result += "Total: " + to_string(computers->size());
        cout << result << endl;
    }

    void addComputer()
    {
        string computerName;
        cout << "Computer name: ";
        cin >> computerName;
        Computer *computer = new Computer(computerName);
        computers->push_back(*computer);
        cout << "Computer added" << endl;
    }

    void deleteComputer()
    {
        string computerName;
        cout << "Computer name: ";
        cin >> computerName;

        for (int i = 0; i < computers->size(); i++)
        {
            Computer *computer = &computers->at(i);
            if (computer->getName() == computerName)
            {
                computers->erase(computers->begin() + i);
                cout << computer->getName() + " deleted" << endl;
                return;
            }
        }
        cout << "Computer not found" << endl;
    }

    void useComputer()
    {
        string computerName;
        cout << "Computer name: ";
        cin >> computerName;

        for (int i = 0; i < computers->size(); i++)
        {
            Computer *computer = &computers->at(i);
            if (computer->getName() == computerName)
            {
                currentComputerIndex = i;
                cout << computer->getName() + " selected" << endl;
                return;
            }
        }
        cout << "Computer not found" << endl;
    }

public:
    UI()
    {
        computers = new vector<Computer>();
        currentComputerIndex = -1;
    };

    void parseCommand(string command)
    {
        if (command == "help")
        {
            listHelpMessage();
        }
        else if (command == "list")
        {
            listComputer();
        }
        else if (command == "exit")
        {
            exit(0);
        }
        else if (command == "deleteComputer")
        {
            deleteComputer();
        }
        else if (command == "addComputer")
        {
            addComputer();
        }
        else if (command == "useComputer")
        {
            useComputer();
        }
        else
        {
            cout << command << " command not found" << endl;
            listHelpMessage();
        }
    };

    void exec()
    {
        string command;
        while (true)
        {
            if (currentComputerIndex >= 0)
            {
                cout << computers->at(currentComputerIndex).getName() << " ";
            }

            cout << ">> ";
            cin >> command;
            parseCommand(command);
        }
    };
};
```

Computer.cpp
```cpp=
#pragma once

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Computer
{
private:
    string name;

public:
    Computer(string computerName)
    {
        this->name = computerName;
    };

    string getName()
    {
        return this->name;
    };
};
```