とあるエンジニア系ライダーの日常

Webエンジニアの話、バイクの話

DDDっておいしいの?設計から実装まで

DDDってなに?

Domain-Driven Design

ドメイン駆動設計です。

Domainって?

google.co.jp

違います!

Domainとは

「知識、影響力、活動の一領域」

よくある参考

飛行機の運航制御のドメイン
「飛行機の運航制御には、出発地と目的地
は航路の始点と終点がある。
航路は出発地と発着地に関連する」

ユビキタス言語

このドメインから、

開発者とドメイン知識をもつ人(ユーザ、専門家等)

との間に共通言語を定義する
「始点(DeparturePoint)」

「終点(ArrivalPoint)」

「航路(Course)」

ユビキタス言語を使って会話してみる

f:id:kensanty:20170825093120p:plain

ユビキタス言語を使うと

ドメインモデルと実装コードがきちんと対応付けられるようになる。

見えないものが見えてくる。

 

設計

f:id:kensanty:20170825093338p:plain

 

ドメインモデルの設計を使うと

色々なところから呼ばれても、

常にドメイン層では同じことが行われるので、

関係なく使いまわせる。

また、フレームワークミドルウェアに依存しない

Springでサンプル

レイヤー分割

f:id:kensanty:20170825093557p:plain

こうやって切り分けることで、別にドメイン部分ではドメインのことだけ考えられる様にする。

サービスによってドメイン内部をブラックボックス

f:id:kensanty:20170825093815p:plain

サービスを介してモデルを使うことで、インターフェース側はモデルのことを

知らなくていい。

リポジトリをつかってデータベースとモデルを切り離す

f:id:kensanty:20170825093928p:plain

DBの値とかどう入っているかはモデルは知らない。

リポジトリさんがんばれ!

ドメインモデルの実装を使うと

それぞれのレイヤーで依存していないので、

があればサーバー上から呼ばなくても値は担保できる。

結論:おいしいポイント

ユビキタス言語を使ったコードの現実化

 専門家にしか見えないものが見えてくる

レイヤー分けされた設計による可用性

 いろんな所から同じ処理を呼び出せる

レイヤー分けされた実装による安全性

 テストが描きやすい

 フレームワークの載せ替えも簡単

 

詳しく勉強される方はこちらで

ReactでStateとPropsをちゃんと使ってみる

前回の記事でReactが使える環境は作ったので、

まずはStateとPropsをちゃんと使ってリストを作ってみる。

ListBaseにStateを持たせて、

ListにPropsとして渡して、

ListRecordを描写してみようかなと。

StateとPropsについて

State
  • そのコンポーネントが持っている状態
  • mutable data (可変のデータ)
  • maintained by component (コンポーネントによって保持)
  • should be considered private (プライベートであるべき)

this.setState({state1: "value1",state2: "value2"});

のようにコンポーネント作成後任意のタイミングで入れられる。

初期値は

this.state = {state1: "value1",state2: "value2"}

こんな感じで入れてもいい。

Props
  • コンポーネントから渡されたプロパティ
  • immutable data (不変のデータ)
  • passed in from parent (親から渡される)
  • can be defaulted & validated (デフォルト値の設定と検証が可能)

<Component props1="value1" props2="value2">

のようにコンポーネント作成時に入れられる。

作ってみた

構成は前回と同じ。

 "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "devDependencies": {
    "babel-core": "^6.24.0",
    "babel-loader": "^6.4.1",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "webpack": "^2.2.1"
  }

 こんな感じ。

最初の呼び出し元としてapp.jsxを作る。

前回はindex.html内でrenderを呼んでいたが、

app.jsx自体にやらせることにした。

app.jsx

import React from 'react';
import ReactDom from 'react-dom';
import ListBase from './listbase.jsx';

ReactDom.render(
  <ListBase/>,
  document.getElementById('listbase'));

なので、webpack.config.jsは、app.jsxをベースとしてapp.jsを作る様に

webpack.config.js

const path = require('path');

module.exports = {
    entry: {
        app: './src/app.jsx'
    },
    output: {
        path: './public',
        filename: '[name].js' // 上記entryのキーに対応したテンプレート
    },
    module: {
        loaders: [
            {
                loader: 'babel-loader',
                exclude: /node_modules/,
                test: /\.js[x]?$/,
                query: {
                    cacheDirectory: true,
                    presets: ['react', 'es2015']
                }
            }
        ]
    }
};

なので、index.htmlはapp.jsを呼び出すだけ。

index.html

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="listbase"></div>
    <script src="public/app.js"></script>
</body>
</html>

 ここからはさくっと。

呼び出されるListBaseコンポーネントはStateデータをコンストラクターで持ち、

<List data={this.state.data}/>

として子コンポーネントに渡すだけ。

listbase.jsx

import React, {Component} from 'react'
import List from './list.jsx';

export default class ListBase extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [
        {
          id: 1,
          name: 'tanaka'
        }, {
          id: 2,
          name: 'yoshida'
        }
      ]
    };
  }
  render() {
    return (<List data={this.state.data}/>);
  }
}

渡されたdataを、

Listコンポーネント内でループしてListRecordコンポーネントをdataの数だけ生成する。

listrecord.js

import React, {Component} from 'react'
import ListRecord from './listrecord.jsx';

export default class List extends Component {
  render() {
    var rows = this.props.data.map(function(row) {
      return (<ListRecord data={row} key={row.id}/>);
    });

    return (
      <ul>
        {rows}
      </ul>
    );
  }
}

で、最終的にListRecordがPropsを描写する。

listrecord.jsx

import React, {Component} from 'react'

export default class ListRecord extends Component {
  render() {
    return (
      <li>
        {this.props.data.id}:{this.props.data.name}
      </li>
    );
  }
}

npm run webpack -pして、

index.htmlを表示してみる!

1:tanaka

2:yoshida

おお!表示された。

PropsはImmutableなので、値を変える時はListBase自体で

setStateし直すということか。

それで、

<ListRecord data={row} key={row.id}/>

keyを比較して変更のあったものを再描写してる感じかな。

(最初keyがなくて怒られた苦笑)

うん、なんとなくだけどわかってきた。

ES6で書くとfunction(){}とかなくてJSっぽくなくていい!

DebugしにくいからReactDevTool入れてちゃんとサーバー上で動かした方がいいな。

あとコンポーネントとして、

こうやってマイクロな感じで作ったコンポーネントを組み合わせて呼び出して、

全部JSじゃなくて必要なところだけコンポーネントを埋め込んでリッチにする方が、

DOM全部管理するより開発しやすいんじゃないかなーと思った。

 

ここまでやって、次はFluxとかでのデータフロー管理なわけかな。

ちょっとずつ進んでる感。

React+Babel+WebpackでHTMLにリストを書いてみた。

作ってみるもの

WebでReactの動的サイトを作るのを目標にとりあえず今回は、

React、Babel、Webpackを使って

普通のリストを作ることにしようかと。

もろもろのバージョンは下記

node:7.6.0

npm :4.4.4

React:15.4.2

Babel:6系

Webpack:2.2.1

Reactとは

Facebookが作っているJSのView部分だけのライブラリ

facebook.github.io

詳しくは本家を。

現在バージョンは15で、初期と大分変わっているので、記事を参考にする際はお気をつけください。

Babelとは

「BabelはブラウザにまだサポートされていないようなJavaScriptの次世代の標準機能を、現在のブラウザでも使えるようにするNode.js製のトランスパイラ。」

要はJSのコンパイラと考えていただければ。

ECMAScriptJavaScript の標準試用)準拠なのがいいところ。

Webpackとは

設定ファイルを書けば、依存関係を解消し、

ビルドしてくれるツール(つまりコンパイラ)です。

さっそく作ってみよう!

とりあえず今回は、

React、Babel、Webpackを使って

特に動かないリストを作ることにしようかと。

とりあえず動くものはFluxとか使ってからで。

まずは作業用ディレクトリでnpmで初期化して必要なものをインストール 

※Babel6になりパッケージの分離が行われ、

必要なもののみインストールする必要あります。

npm init
npm install --save react react-dom npm install --save-dev webpack babel-core babel-loader babel-preset-es2015 babel-preset-react

このままじゃ使いづらいので

package.jsにwebpackコマンドを登録

"main": "index.js",
"scripts": {
"webpack": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},

これでnpm run webpackでwebpackが使えるようになります。

とはいえwebpackが何をするかの設定ファイルが必要なので、

下記を用意します。

※これもBabel6の影響でloaderがbabel-loaderになっています。

webpack.config.js

const path = require('path');

module.exports = {
    entry: {
        app: './src/app.js'
    },
    output: {
        path: './public',
        filename: '[name].js' // 上記entryのキーに対応したテンプレート
    },
    module: {
        loaders: [
            {
                loader: 'babel-loader',
                exclude: /node_modules/,
                test: /\.js[x]?$/,
                query: {
                    cacheDirectory: true,
                    presets: ['react', 'es2015']
                }
            }
        ]
    }
};

./publicに、entryでキーに指定した名前の[name].jsが書き出されます。

こうしておけば複数も可能です。

JSは今回はメインの呼び出しとリスト自体の2つ

app.js

import React from 'react';
import ReactDom from 'react-dom';
import List from './list.js';

window.ListApp = {
    render:  () => {
        ReactDom.render(
            <List />,
            document.getElementById('listapp')
        );
    }
};

list.js

こっちは今回は適当。

import React, {Component} from 'react'

export default class List extends Component {
    constructor() {
        super();
    }

    render() {
      var list = [];

      var data = [
        { text: "1" },
        { text: "2" }
      ];

      for(var i in data){
        list.push(<li key={i}>{data[i].text}</li>);
      }

      return(
        <ul>
          {list}
        </ul>
      );
    }
}

で、肝心のHTMLですが。 

index.html

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>List書いてみよ</title>
</head>
<body>
    <div id="listapp"></div>
    <script src="public/app.js"></script>
    <script>ListApp.render();</script>
</body>
</html>

これだけ。

最後に

npm run webpack -p

すると、publicディレクトリにapp.jsが出来ているので、

ブラウザからhtmlを開いてみると普通にリストが表示されます。

(ただのリストなので画像は貼りませんが苦笑)

まとめ

とりあえず入門したかなと。

ここから、FluxかRedux使ってデータ持たせたり、

ちゃんとコンポーネント設計したり、

axiosとか使ってAPI呼んでデータ取ってきたり。

お砂場はできれども道は遠き。

SpringのUTにDBSetupを使ってみたら良かった

はじまり

DBのテスト、できればきれいに書きたい。

ということで

  • insert文とかベタ書き : なんか嫌だ
  • DBUnit : 使ったことはあるけど、ファイル参照嫌だ
  • オレオレUtil : 再利用性がない!

ということで、DBSetupというのを見つけた。

データは「流れるようなインタフェース(Fluent Interface)」で作成する。

この一文に惚れたからだ。

自分の環境

  • spring-boot
  • JPARepository
  • JUnit4

これに合うようにやってみた。

テストされる側

単にデータを全部返すだけのメソッド

@Service
@Transactional
public class MyDataService {

@Autowired
MyDataRepository myDataRepository;

public List<MyData> findAll() {
return myDataRepository.findAll(new Sort(Sort.Direction.ASC, "id"));
}
}

使ってみた

とりあえずversion2.0をimport

pom.xml

<!-- https://mvnrepository.com/artifact/com.ninja-squad/DbSetup -->
<dependency>
<groupId>com.ninja-squad</groupId>
<artifactId>DbSetup</artifactId>
<version>2.0.0</version>
</dependency>

SpringBootはテスト時はtest/resources/application.propertiesがあったらそちらを読み込むので作成。

spring.datasource.url=jdbc:mysql://192.168.33.10/mytestdatabase
spring.datasource.username=testuser
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

これで通常環境は汚染されない。

DataSourceどうやってとってくるかで迷ったけど、普通に@Autowire

DataSouce取ればテスト用のDataSouceが入ってた。

@RunWith(SpringRunner.class)
@SpringBootTest

この辺のDIのおかげかな。

あとは、データの定義、これがカッコイイ!!!

クラス内にデータがどうなっているか収まるのでDBUnitよりも読みやすい!!!

public static final Operation DELETE_ALL =
Operations.deleteAllFrom("mydata");

public static final Operation INSERT =
Operations.insertInto("mydata")
.columns("id", "name")
.values("1","Tanaka")
.values("2","Yoshida")
.values("3","Suzuki")
.build();

で、Beforeでデータをセットしてやると。

@Before
public void before(){
Destination dest = new DataSourceDestination(dataSource);
Operation ops = Operations.sequenceOf(DELETE_ALL, INSERT);
DbSetup dbSetup = new DbSetup(dest, ops);
dbSetup.launch();
}

sequenceOfで生成したOperationを繋げられるので楽!

あとは普通にテストすれば

@Autowired
MyDataService myDataService;

@Test
public void canFindAll() throws Exception {
List<MyData> myData = myDataService.findAll();
assertThat(myData.get(0).getId(),is(1));
assertThat(myData.get(0).getName(),is("Tanaka"));
}

オールグリーン!!!

まぁ、使ってみたかっただけのテストなんで、テスト自体は雑ですが。

なんて素敵なんだろう。この流れるようなインターフェース。

もうDBUnitのことなんて忘れよう!

DBのテストをこれで切り出して、

その部分がテストされていればあとはMockitoとかでMockすればいいし。

うん、なんか結局惚れた!

 

SpringBoot,Thymeleaf,JpaRepositoryで基本構成を作ってみた

あけましておめでとうございます!

SpringBoot、前から気になるなぁと思っていたので、

年末にちょこっと触ってみた。

SpringBootとはとかはハショリます。

今年は週1ぐらいでブログ書きたいなぁと。勉強するために!

 

とりあえずmavenで必要なものを突っ込んでみる

STS(簡単にSpringBootを開発するツール)もあるけど、

おもしろくないのでInteliJでmavenプロジェクトを作成して

必要なものだけ全部突っ込んでみる。

必要な物 

  • spring-boot-starter-parent: SpringBootのベース
  • spring-boot-starter-web
  • spring-boot-starter-thymeleaf: Thymeleafが使いたかった!
  • spring-boot-starter-data-jpa: 結局裏ではhibernate使ってるけど
  • mysql-connector-java: MySQLは適当にVagrantで建てた
  • lombok: あるとJpaRepository使いやすかった
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

 

 

まずは起動用ファイル

SpringBootはサーバーを内包していて、mainから走らせれば起動するので、

これだけ書けばとりあえずサーバーが起動する。

なんとなく名前はBootにしてみた。起動しそうだからb

@SpringBootApplication
public class Boot {
public static void main(String[] args) {
SpringApplication.run(Boot.class, args);
}
}

 

 

Thymeleafを組み合わせてみる

resources/templatesにhtmlファイルを設置

index.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>top page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
test
<p th:text="${msg}" />
</body>
</html>

コントローラーがその名前を返せばいいだけ。

今回はindex.htmlとしたのでこんな感じ。

@Controller
@RequestMapping("/")
public class IndexController {
public String index(Model model) {
model.addAttribute("msg","Hello Spring Boot");
return "index";
}
}

簡単すぎる!

これでBootを走らせるともうlocalhost:8080で見れる!

早すぎる!

 

 

Jpa Repositoryを使ってみる

まずは必要なデータベース!!!

データベース名:mydatabase

テーブル名:mytable

として作って適当にデータを突っ込んでみる。

次に

resources/application.properties

を作ってアクセスできる様に下記を記載する

今回はVM上でmysqlがあるのでこんな感じ。

spring.datasource.url=jdbc:mysql://192.168.33.10/mydatabase
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect

がないと、

org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

で悩まされた。。。

 

あとは簡単!

Entityを用意する

@Entity
@Data
@Table(name = "mydata")
public class MyData {

@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
private String name;

}

JpaRepositoryのinterfaceを用意する。

だいたいのメソッドがデフォルトで用意されている。

@Repository
public interface MyDataRepository extends JpaRepository<MyData, Integer> {
}

Repositoryの実装としてServiceを作る。

AutowiredとかはSpring DIの基本なので説明飛ばします!

@Service
@Transactional
public class MyDataService {

@Autowired
MyDataRepository myDataRepository;

public List<MyData> findAll() {
return myDataRepository.findAll(new Sort(Sort.Direction.ASC, "id"));
}
}

最後にThymeleafに送っていたデータをDBからServiceを使って取得。

MyDataにtoStringが実装されてるから取得した値をそのまま出してみる。(雑)

@Controller
@RequestMapping("/")
public class IndexController {

@Autowired
MyDataService myDataService;

@RequestMapping(method = RequestMethod.GET)
public String index(Model model) {
List<MyData> myDataList = myDataService.findAll();
model.addAttribute("msg", myDataList.get(0));
return "index";
}
}

そして走らせる。

 

 

無事成功!

f:id:kensanty:20170101190003p:plain

ほとんど引っかかるところはなく簡単にできたのがすごい!

環境構築もいらないし。

でも、楽だけど、中身をちゃんと知らないといけないなぁと思った。

まぁ、とりあえずベース環境として使って、

勉強しながら気分次第でmavenのimport方法変えていけばいいかなと。

YAGNIということで。

これをベースに何作るかは全然考えてない。。。

デブサミ関西2016に行ってきた

Developers Summit 2016 KANSAI #devsumi

デブサミ関西に行ってきたので感想をまとめ。

なぜか基調講演が1番おもしろかったのでとりあえずそれだけ紹介。

基調講演

鈴木雄介さん

グロースエクスパートナーズ執行役員

日本Javaユーザーグループ会長

クラウドって仮想サーバーのことだけじゃないよね

1.インフラの仮想化 IaaS

仮想インフラによってインフラを所有から利用へ。

2.ミドルウェアの仮想化 PaaS

AWS RDSみたいにミドルウェアもその部分だけを利用できる。
データベースサーバーを借りるのではなくデータベースサービスを借りる。
バックアップとかクラスタかも考えなくていいはず。
その為に積極的にプラットフォームの制約は受け入れる!
フレームワークのように、あと何年かするとそれが当たり前になると。

3.システム構成のコード化

ChefとかAnsibleみたいなの。

 

それら3つが揃って本当にクラウドだよねって話だった。
IaaSだけではクラウドと言えのるか?というのがおもしろかった。
企画→開発→運用 がクラウドの方が早い!


クラウドの進化の紹介

2001年アジャイルソフトウェア開発宣言

「企画→開発」の効率化

2006年クラウド
2009年:DevOps

「開発→運用」の効率化

データセンターの移行にスクラムを導入したところから。

変更と安定稼働は相反する

DevOpsというよりOpsをなくすって考えっていう話がおもしろいw

2010年:多様なリリース方法

ブルーグリーンデプロイメント

本番環境を2つ用意して切り替えるやり方。

カナリアリリース

一部のユーザーだけに特定のバージョンを提供する。

って、やってたけどそんな呼び方するって知らなかった。

2012年:カオスモンキー

NetFlixが使っている。

本番環境をランダムにダウンさせる製品。

インフラの自動化のテストをするため、

自動復旧を観測する。

まじか!データセンターまるごと落とすとかもするらしい。

2014年:マイクロサービスアーキテクチャ

大事だよなぁ。影響範囲を減らすの。

システム全体を単一の構成で作ると技術の切れ目でチームを構成しがち。

コンウェイの法則)

それに対して、システムをサービス同士の連携で実現する。

サービスレベルでチームを構成する。

 

APIさえ変わらなければいい。

だからアジャイルがやりやすい。

 

あと、MSAに再構築は愚か!今から始められる。

少しずつ取り入れるのを始めるべきってのには共感した。

確かにちょっとずつ切り出していくのが1番良さそう。

 

そして、ここでドメインモデルが出てくる。

業務領域で分ける。正解はない。。。難しいよねDDD。

 

全てはアジャイルからはじまった。

「この年表のどの時点にみなさんはいますか?」

って言うのがカッコ良かった。

クラウド時代のデベロッパ

アプリとインフラは不可分に。両方コード化している。

何をコーディングして何をコーディングしないのか。

システム開発からサービス運営へ

企画→開発→運用の全てでエンジニア!!!

スペシャリスト:特定領域の専門家

ジェネラリスト:専門家を繋いで価値に繋げる

どちらを目指すか、戦略を考えて先へ進んで行かないといけない。

ビジネスの中心にエンジニアがある。

エンジニアにもコミュニケーション、プレゼン、チームビルディング能力が必要。

特にジェネラリストに必要。

個人でシステムをつくり上げるのは不可能に近い。

 

スキルを縦か横に拡げるという話だった。

この話にはすごい悩まされた。

自分のスキルはどっちかというといつも横に広がっていっているな。

どっちかというとジェネラリスト向きなんだろうなと思った。

しゃべるのも好きだし。その方向だとそういう方向にどう拡げるか

考えないとなー。

 

この講演の内容はクラウドファーストアーキテクチャ設計ガイドで読めるらしいです!笑

phpとslim3で汎用掲示板を作ってみた

ふとしたきっかけからphpslim3を使って汎用掲示板を作ってみました。

ライセンス表記とか全然してないけどオープンソースなので、

プルリクもらえると嬉しいですw

github.com

Slim3について

phpのマイクロフレームワーク

Slim Framework - Slim Framework

ORマッパーとか機能は全然ついてなく、

後からComposerでvendorに追加していく感じ。

CakePHPみたいに規則も厳しくなく、設定ファイルも簡単なので、

いろいろ組み合わせて作っていくと案外いいかなと。

ただ、リクエストをさばくのがroutes.phpだけなので、

機能が増えるとこれがかさばって可読性下がりそう。

routes.phpから完全にそれぞれのページのパラメーター関係のロジックを

抜き出して、そこに全部渡せばすっきりするかな?

今回の構成について

こんな感じで、バリデーションとCSRFはComposerでありものを突っ込んだ。

やっぱり車輪の再開発はしたくない。

で、routes.phpではそういったパラメーターの処理だけさせて、

あとはapp/src/usecaseの中のロジックでDBとかの処理をしている感じ。

これだけでローカル試せます

実はscotch-box(LAMPvagrant box)を入れているので、

vagrantとvirtual boxがインストールしてあれば、

cloneしてvagrant up、

MySQLddl.sqlのユーザー作成とテーブル作成をして、

Document Rootを/public(index.php)があるにすれば動くはず。

PHPで開発するならローカルのエディター使いながら随時確認できる

scotch-boxおすすめ!

Scotch Box ♥ A Vagrant LAMP Stack That Just Works

TODO:やりたい、やりたかったこと

- ほんとはDDDで作りたかったので、

時間があったらusecaseからmodelとrepositoryを切り出して、

もっと柔軟性を持たせたいかな。

- DIとnamespaceを適当にやってしまった所をちゃんと定義

したいかなと。

- エラーハンドリングとかトランザクションが適当なので、

もっとしっかりしたいなと。usecase内でトランザクションがはれる様なイメージ。

まとめ

Slim3自体は簡単かつすっきりとした小規模システムをつくりたい、

リクエストのハンドリングとテンプレートエンジンとかだけ使えれば十分。

あと、そういった作りにしておいてロジックを分離することで、

今後フレームワーク間の載せ替えや

バージョンアップも簡単になるんじゃないかなと。