LaravelでRepository Patternを採用した時に手間が発生

## なぜしたのか？
- Repository Patternを実装する際InterfaceとRepositoryのfileを作成する手間が発生しめんどーだと思ったから。

## 何をしたのか？
- Laravelでartisan コマンドを作成しInterfaceとRepositoryのfileをコマンドで作成できるようにしました
    - `php artisan make:command CommandName`で作成し、実装後に`app/Console/Kernel.php`に追記して使用できるようにします。

### 備考
- `php artisan make:repository RepositoryName`というコマンドを作成しようと思います
    - 本来ならば実装した方がいいですが今回は、Service Classは書いておらず、またPHPUnitも書いてません
- 今回は、InterfaceとRepositoryを同じディレクトリに作成します。
- [参考にしたサイト](https://bmf-tech.com/posts/Laravel5.3%E3%81%A6%E3%82%99%E8%87%AA%E4%BD%9Cartisan%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%88%E3%82%99.md)(ほぼ使わせていただいてます)

## 完成イメージ
```shell
projectName > php artisan make:repository Hoge

new directory name. or use directory name:
> Hoge # 入力
```
- 実行結果

```shell
app/Repositories/
└── Hoge
    ├── HogeInterface.php
    └── HogeRepository.php
```


## 作成したFile
- 今回1fileで書いています。

```php
<?php
declare(strict_types=1);

namespace App\Console\Commands;

use Illuminate\Console\Command;

/**
 * CreateRepositoryFileCommand class
 */
class CreateRepositoryFileCommand extends Command
{
    /**
     * @const string repository dir path
     */
    const REPOSITORIES_PATH = 'app/Repositories/';

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'make:repository {repositoryName : The name of repository}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create repository files';

    /**
     * @var string
     */
    private $fileName;

    /**
     * @var string
     */
    private $dirName;

    /**
     * @var string
     */
    private $repositoryFileName;

    /**
     * @var string
     */
    private $interfaceFileName;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->fileName = $this->argument('repositoryName');

        if (is_null($this->fileName)) {
            $this->error('Repository Name invalid');
        }
        $this->dirName = $this->ask('new directory name. or use directory name');

        if (is_null($this->dirName)) {
            $this->error('Directory required!');
        }

        if (!$this->isExistDirectory()) {
            $this->createDirectory();
        }

        $this->repositoryFileName = self::REPOSITORIES_PATH . $this->dirName . '/' . $this->fileName . 'Repository.php';
        $this->interfaceFileName = self::REPOSITORIES_PATH . $this->dirName . '/' . $this->fileName . 'Interface.php';
        if ($this->isExistFiles()) {
            $this->error('already exist');
            return;
        }

        $this->creatRepositoryFile();
        $this->createInterFaceFile();
        $this->info('create successfully');
    }

    /**
     * Repositoryのfileを作成する
     * @return void
     */
    private function creatRepositoryFile(): void
    {
        $content = "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Repositories\\$this->dirName;\n\class $this->fileName" . "Repository implements $this->fileName" . "Interface\n{\n}\n";
        file_put_contents($this->repositoryFileName, $content);
    }

    /**
     * Interfaceのfileを作成する
     * @return void
     */
    private function createInterFaceFile(): void
    {
        $content = "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Repositories\\$this->dirName;\n\ninterface $this->fileName" . "Interface\n{\n}\n";
        file_put_contents($this->interfaceFileName, $content);
    }

    /**
     * 同名fileの確認
     * @return bool
     */
    private function isExistFiles(): bool
    {
        return file_exists($this->repositoryFileName) && file_exists($this->interfaceFileName);
    }

    /**
     * directoryの存在確認
     * @return bool
     */
    private function isExistDirectory(): bool
    {
        return file_exists(self::REPOSITORIES_PATH . $this->dirName);
    }

    /**
     * 指定名でdirectoryの作成
     * @return void
     */
    private function createDirectory(): void
    {
        mkdir(self::REPOSITORIES_PATH . $this->dirName, 0755, true);
    }
}
```

## 作成されるfile

- あとはおすきなように書いてください。
    - ちなみに自分は、RepositoryでEloquent Modelを継承したclassをDIして使用しています。

```php
<?php
declare(strict_types=1);

namespace App\Repositories\Hoge;

interface HogeInterface
{
}

```

```php
<?php
declare(strict_types=1);

namespace App\Repositories\Hoge;

class HogeRepository implements HogeInterface
{
}

```


## まとめ
- 自身が設計知識に精通しているわけではないので同じディレクトリで良いのだろうかなど色々悩みましたが、まぁーちゃんとした答えがあるとは、思っていないのでひとまずは、同じディレクトリでいいかなっておもい同じディレクトリにしました
    - 「いやいや待て待て」と思う方はぜひご指摘の方よろしくお願いいたします！

- 久々にQiitaに投稿しましたがアウトプットは大切だなと思いました。
    - 自分のコードを見直してて1行しかないメソッドもどうかと思いますが。

- 不備、間違い等ございましたらぜひご指摘いただけたらと思います。