Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

イケてる技術で品質を担保しつつスピード感のある開発を実現する冴えたやり方

1,047 views

Published on

https://alterbooth.connpass.com/event/103125/

Published in: Technology
  • Be the first to comment

イケてる技術で品質を担保しつつスピード感のある開発を実現する冴えたやり方

  1. 1. イケてる技術で品質を担保しつつ スピード感のある開発を実現する冴えたやり方 2018/10/23 AADojo #0 株式会社オルターブース 松村 優大
  2. 2. 松村 優大 (MLBお兄さん) 株式会社オルターブース 業務執行役員/CTA C#/PHP/Azure/AWS 31歳/島根出身/娘1人
  3. 3. 開発において大事にしていること • テストできる状態(Testable)を保つ・網羅する • 今日書いたコードは今日テストを書く • 開発初期段階からCIを回す(Continuous Integration)
  4. 4. なぜテストが必要か(再確認) • エラーを見つける • 想定内のエラー:想定通りのエラー処理であることを確認 • 想定外のエラー:リリース前にエラーに気付くため • 変更に伴う“デグレ”を生まない・残さない
  5. 5. Testableなコードとは • 処理(関数)の目的が明確かつ粒度が小さい • 途中処理の差し替えが容易である(モック) • 外部リソースの挙動の差し替えが容易である(モック) データベース SaaS (API) ストレージ
  6. 6. .NET Coreのバージョンとサポート計画 バージョン レベル リリース日 サポート終了日 1.0 LTS 2016/06/27 2019/06/27 1.1 LTS 2016/11/16 2019/06/27 2.0 Current 2017/08/14 2018/10/01 2.1 LTS 2018/05/30 At least three years from LTS declaration (August 21, 2018) 2.2-preview3 Preview 2018/09/12 - ※2018/10/23現在
  7. 7. Data Store Repository Controller View Model Service/Domain Repository Model Repository Model Data Store Model Controller View Model Model
  8. 8. ユースケースに従って ServiceやDomainを 構成する CRUDの操作のみ データ保存の振る舞い
  9. 9. public interface IRepository<T> where T : class { IEnumerable<T> GetAll(); //一覧 T Find(int id); //取得 T Create(T entity); //作成 void Update(T entity); //更新 void Delete(T entity); //削除 } public interface IUserRepository : IRepository<User> { }
  10. 10. public class UserRepository : IUserRepository { private readonly DbContext db; public UserRepository(DbContext db) => this.db = db; public IEnumerable<User> GetAll() => ...; public User Find(int id) => ...; public User Create(User entity) => ...; db.SaveChanges(); public void Update(User entity) => ...; db.SaveChanges(); public void Delete(User entity) => ...; db.SaveChanges(); DbContext = データベース = 外部リソース 外部リソースを直接操作する ため、モックを作れない (=テストしづらい)
  11. 11. public class UsersController : Controller { private readonly IUserRepository userRepository; public UsersController(IUserRepository userRepository) => this.userRepository = userRepository; public IActionResult Create(User user) { userRepository.Create(user); return Ok(); } テスト時はモックのリポジトリを差し込む 処理のなかで外部リソースが現れるため 単体テストを行うことができない (擬似的な保存の振舞いができない)
  12. 12. ユースケースに従って ServiceやDomainを 構成する CRUDの操作のみ データ保存の振る舞い データストアを隠蔽 単体テストが可能
  13. 13. public interface IUnitOfWork { int SaveChanges(); //DbContext.SaveChanges(既存の保存処理) bool SaveEntities(); //実際に呼び出される保存処理の定義 } public class MyContext : DbContext, IUnitOfWork { public DbSet<User> Users { get; set; } public bool SaveEntities() => 0 < this.SaveChanges(); //public bool SaveEntities() => true; //モックの書き方 } DbContextに新しい保存処理を実装 (テストではモック化し保存の振舞いだけ)
  14. 14. public class UserRepository : IUserRepository { private readonly DbContext db; public IUnitOfWork UnitOfWork => db; public UserRepository(DbContext db) => this.db = db; --- public IActionResult Create(User user) { userRepository.Create(user); userRepository.UnitOfWork.SaveEntities(); return Ok(); } リポジトリから保存処理を切り離す 処理のなかで外部リソースが隠蔽されたため 単体テストを行うことが可能
  15. 15. アプリケーションアーキテクチャを どう学ぶか
  16. 16. アーキテクチャを学ぶうえで良い資料
  17. 17. 実行環境をどうするか PaaS? コンテナー? サーバーレス? アプリケーション構成に応じて適した環境を選ぶべき →言語(ランタイム)、規模、スケール、実行頻度、etc →Kubernetesを使うかどうかは規模によりけり
  18. 18. Appendix • https://www.microsoft.com/net/learn/dotnet/architecture-guides • https://docs.microsoft.com/ja-jp/dotnet/standard/modern-web-apps-azure-architecture/ • https://github.com/dotnet-architecture/eShopOnWeb • https://github.com/dotnet-architecture/eShopOnContainers • https://12factor.net/ja/
  19. 19. ご清聴ありがとうございました。

×