Se ha denunciado esta presentación.

「エクストリームエンジニアへの道(Swift編)」

2

Compartir

Cargando en…3
×
1 de 56
1 de 56

「エクストリームエンジニアへの道(Swift編)」

2

Compartir

Descargar para leer sin conexión

エクストリームエンジニアという、スキルの高い究極のプログラマーになるため必要な技術を説明いたします。
ここでいうエンジニアは、要件を理解して、テスト駆動開発でプログラムを開発でき、設計もして、さらに、DevOpsでソフトウェアをリリースできる技術者を指します。

エクストリームエンジニアという、スキルの高い究極のプログラマーになるため必要な技術を説明いたします。
ここでいうエンジニアは、要件を理解して、テスト駆動開発でプログラムを開発でき、設計もして、さらに、DevOpsでソフトウェアをリリースできる技術者を指します。

Más Contenido Relacionado

Libros relacionados

Gratis con una prueba de 30 días de Scribd

Ver todo

Audiolibros relacionados

Gratis con una prueba de 30 días de Scribd

Ver todo

「エクストリームエンジニアへの道(Swift編)」

  1. 1. エクストリーム・エンジニアへの道 (Swift編) テクノロジックアート ⻑瀬 嘉秀
  2. 2. •  オブジェクト指向 •  テスト駆動開発 •  デザインパターン •  リファクタリング •  関数型プログラミング 内容
  3. 3. •  「プロを目指すSwi% 基本文法と応用」 教科書
  4. 4. オブジェクト指向
  5. 5. •  オブジェクト指向で設計、プログラミング オブジェクト指向
  6. 6. class Money { var amount: Double = 0 var currency: String = "" var rates: Dictionary<String, Double> = ["USDYEN": 120, "USDEUR": 1.2] func setAmount(inputMoney: Double){ amount = inputMoney } func setCurrency(cur: String){ currency = cur } func convert(convertMoney: Money) -> Money { convertMoney.setAmount(amount*rates[currency+convertMoney.currency]!) return convertMoney } func getAmount() -> Double { return amount オブジェクト指向コード
  7. 7. } func displayAmount() -> String { return "" } func getCurrent() -> String { return currency } } class Yen: Money { override func displayAmount() -> String { return String(format: "%.0f", amount) } } class Euro: Money { override func displayAmount() -> String { return String(format: "%.2f", amount) } } オブジェクト指向コード(続き)
  8. 8. テスト駆動開発
  9. 9. テスト駆動開発(TDD)とは Test   ⇒ テストが Driven   ⇒ 駆動する Development ⇒ 開発 開発の手法である (テスト手法ではない)
  10. 10. •  XP のプラクティスの一つである TDDとは: XP のプラクティス アジャイル開発手法 XP プラクティス リファクタリング 最適ペース 継続的結合 テスト駆動開発(TDD) 全員同席 シンプル設計 : その他のXPプラクティスと密接に関係しています
  11. 11. •  定義 –  ソフトウェアの小さな機能ごとに、テスト⇒実装の細かいステップを 繰り返して、プログラムの設計・開発を行う開発手法 •  進め方 –  ToDo リストで実装すべき機能を管理する •  メモに作るべき振る舞いや作業を ToDo として洗い出す –  各 ToDo 毎に以下の手順を繰り返す •  まず、テストコードを書く •  テストを実行する ⇒ 失敗する •  次に、テストをパスするよう機能コードを書く •  テストを実行する ⇒ 成功する •  機能コードを本来あるべき姿にリファクタリングする •  テストを実行する ⇒ 成功していることを確認 (REFACTORING) TDDとは:より具体的に
  12. 12. TDDとは: TDDのサイクル テスト テスト動作確認 リファクタリング 動作 最初にテストを書く コンパイルを通しテストに失敗させる 確実にテストが通るコードを書く きれいなコードにする ⇒ これから追加しようとする機能の振る舞いを明らかにする   テストで仕様を表現する ⇒ 作成したテストが確実に動いていること、   問題のある結果が返ればレッドになることを確認する ⇒ 正しい結果が返ればグリーンになることを確認する   必要最小限の実装を少しずつ安全に積み重ねていく ⇒ リファクタリングでコードの臭いをとる   現在のテストに必要な、最小限の実装にとどめる(YAGNI)
  13. 13. テストフレームワーク
  14. 14. テストコードの作成 func testMoneyCreation() { money = Money() money.setCurrency("USD") money.setAmount(10) XCTAssert(10 == money.getAmount(), "Test Money Amount”) func testYenConversion() { money = Money() money.setCurrency("USD") money.setAmount(10) convertMoney = Yen() convertMoney.setCurrency("YEN") XCTAssert("1200" == money.convert(convertMoney).displayAmount(), "Test Yen Convert") }
  15. 15. デザインパターン
  16. 16. デザインパターンの⽬的 •  洗練された設計を習得・再利用する •  ソフトウェアに安定した構造を導入する •  コードにたいする共通の理解を得やすくする •  コミュニケーションのための語彙とする ソフトウェアの 再利用性、柔軟性、拡張性、保守性 を向上させる
  17. 17. デザインパターンの作成 !  ソフトウェアの再利用性や柔軟性を高めたい !  問題ごとに解法の指針をカタログ化   「パターン名、問題、解法、結果」 !  何度も同じような設計・実装をしてきた !  経験から獲得した解法の工夫を抽出・洗練する
  18. 18. デザインパターンの意義 •  適用範囲が明確に定義されている   → 「課題の解法」を習得・再利用できる •  洗練され、高い再利用性・保守性を持っている   → 構造が安定し、再利用性を確保できる •  コミュニケーションのための語彙になる   → 設計に対し、共通の認識を得ることができる   → 開発時の前提知識の底上げができる •  モデルの知識は変化しにくい   → 設計は実装言語に依存せずに再利用できる
  19. 19. GoFのデザインパターン •  「オブジェクト指向における再利 用のためのデザインパターン 」 •  ガンマ、ブリシデス、ヘルム、ジョ ンソン (著) •  本位田真一、吉田和樹(監訳)、 ソフトバンクパブリッシング
  20. 20. デザインパターンの分類 •  デザインパターンは設計上のパターン –  GoFのデザインパターン(23パターン)  GoF(Gang of Four)と呼ばれる四人がカタログ化    : Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides –  J2EEパターン(15パターン) Sun Java Centerで、J2EEに有用なものをカタログ化 –  分散・並行化設計パターン Pattern Languages of Programsワークショップ選出のものなど デザインパターン GoFの デザインパターン J2EEパターン 分散・並行化 設計パターン
  21. 21. ⽣成に関するパターン •  オブジェクトの生成プロセスに関する(全5パターン) オブジェクトがどのように生成、結合、表現されているの か、ということからシステムを独立にする方法を提供する No. パターン名 目的 1 Abstract Factory オブジェクト群を明確にせず生成するためのインターフェ ースを提供する 2 Builder 複合的に組み合わせたオブジェクトを生成する 3 Factory Method インスタンス化をサブクラスに任せる 4 Prototype コピーして新しいオブジェクトを生成する 5 Singleton インスタンスが1つしか存在しないことを保証する
  22. 22. 構造に関するパターン •  クラス、オブジェクトの構造に関する(全7パターン) クラスやオブジェクトを柔軟に合成する方法を提供する No. パターン名 目的 1 Adapter インターフェースに互換性のないクラス同士を組み合わせる 2 Bridge 機能と実装を別々の階層で拡張する 3 Composite オブジェクトを木構造に組み立てる 4 Decorator 動的にオブジェクトに責任を追加できるようにする 5 Façade 複数のインターフェースに高レベルの統一インターフェースを与える 6 Flyweight インスタンスを共有しコストを節約する 7 Proxy オブジェクトへのアクセスを制御するために処理を代理人に任せる
  23. 23. 振る舞いに関するパターン(1/2) •  クラス、オブジェクトの通信に関する(全11パター ン) アルゴリズムとオブジェクト間での適切な責任分担の方 法を提供する No. パターン名 目的 1 Chain of Responsibility 要求に応じる役割をチェーン状につなぐ 2 Command 命令をカプセル化して再利用する 3 Interpreter 文法規則を表現する 4 Iterator 構造に順にアクセスする方法を提供する 5 Mediator オブジェクト同士の結合度を低める
  24. 24. 振る舞いに関するパターン(2/2) No. パターン名 目的 6 Memento インスタンスの状態を戻せるようにする 7 Observer 状態の変化が自動的に通知され、更新される 8 State 状態にあわせて動作を変える 9 Strategy アルゴリズムをカプセル化して交換可能にする 10 Template Method 特定の処理をサブクラスで行う 11 Visitor 構造と処理を分離する
  25. 25. 特徴 •  互いに関連したり依存し合い、グループを形成するオブジェクト 群を扱う •  グループ同士は共通の概念を持つオブジェクトから成る •  グループ単位でオブジェクト群を生成するインターフェースを提 供する 結果 •  依存関係を乱すことなく、グループ単位でオブジェクトを扱うこと ができる •  グループに含まれるオブジェクトの詳細を意識する必要がない •  生成されるオブジェクトを変更し易い アブストラクトファクトリー(概要)
  26. 26. アブストラクトファクトリー(構造) AbstractFactory +CreateProductA () +CreateProductB () ConcreteFactory1 +CreateProductA () +CreateProductB () ConcreteFactory2 +CreateProductA () +CreateProductB () AbstractProductA ProductA1 ProductA2 AbstractProductB ProductB1 ProductB2 Client +anOperation ()
  27. 27. •  AbstractFactory – AbstractProductのオブジェクトを生成するためのインタ フェースを宣言する •  ConcreteFactory – 生成するオブジェクトの組み合わせを管理する •  AbstractProduct – 生成される部品ごとにインタフェースを宣言する •  ConcreteProduct – ConcreteFactoryによって生成される部品を定義する •  Client – AbstractFactoryのインタフェースにより、 AbstractProductオブジェクトを生成する アブストラクトファクトリー(構成要素)
  28. 28. アブストラクトファクトリー(振る舞い) : Client 1 : createProductA() 3 : createProductB() 5 : Use ProductA 6 : Use ProductB : ConcreteFactory1 2 : new 4 : new : ProductA1 PruductB1
  29. 29. •  マネークラス 適⽤例
  30. 30. let factory = YenFactory() convertMoney = factory.createYenFactory() class YenFactory: Factory { func createYenFactory() -> Money { let yen = Yen() yen.setCurrency("YEN") return yen } } パターン適⽤コード
  31. 31. convertMoney.convert(money) class Yen: Money { override func convert(money: Money) { setAmount(money.getAmount() * 120.00) } override func displayAmount() -> String { return String(format: "%.0f", amount) XCTAssert("1200" == convertMoney.displayAmount(), "Test Yen Convert") パターン適⽤コード(続き)
  32. 32. リファクタリング
  33. 33. リファクタリングとは •  外部から見たときの振る舞いを保ちつつ、 理解や修正が簡単になるように、ソフトウェアの 内部構造を変化させること (出典:リファクタリング) Aを実現する コード Bを実現する コード Cを実現する コード Aを実現する コード Bを実現する コード Cを実現する コード 共通コード リファクタリングのイメージ 振る舞いA 振る舞いB 振る舞いC 振る舞いA 振る舞いB 振る舞いC リファクタリング前 リファクタリング後
  34. 34. •  リファクタリングのきっかけとなる、設計上の問題 コードの臭い(code smell) 臭い 状態 重複したコード 同じ処理が複数個所に存在する 長すぎるメソッド 一つのメソッドに多くの処理が記述されている 巨大なクラス あるクラスが、責務を多く持ちすぎている 多すぎる引数 メソッドに渡す引数の数が多すぎる 変更の発散 1つのクラスがさまざまな変更要求の影響を被る 変更の分散 1つの変更要求によって、複数のクラスが影響を被る 属性、操作の横恋慕 自クラスより他クラスの属性、操作と関連が深い データの群れ 数個のデータがグループとなって各所に現れる 基本データ型への執着 基本データ型を使用し、複雑なロジックが記述されている スイッチ文 スイッチ文により設計が複雑化、硬直化している パラレル継承 あるクラスの継承ツリーと、他のクラスの継承ツリーに関連がある。 表. コードの臭いの例 出典:リファクタリング
  35. 35. リファクタリングの意義 実装済み ツールのサポート 単純ミスの回避 自動化 実装済み コード 臭い リファクタリング コード 修正しやすい 理解しやすい カタログ 臭い 省力化 対象の発見 状態の共有 解決法の共有 デザインパターン 例)Eclipse
  36. 36. リファクタリング リファクタリングの位置づけ 動作しなくなる 危険性 自動テスト バージョン管理システム 常に検証 変更破棄の 場合もある デザインパターン 指針 YAGNI原則 同時に行わない パフォーマンス チューニング 機能の追加 こまめに コミット
  37. 37. •  進化的設計 – 仕様・設計の変更にともない、コードの修正が 多発する • コストとリスクを抑える必要がある – TDD – リファクタリング • これらの手法を学び、適用することで、「コストとリス クを抑えて」 進化的設計(アジャイル開発)を実現する 進化的設計とリファクタリング
  38. 38. オブジェクト指向とカプセル化① •  オブジェクト指向、非オブジェクト指向のソフトウェアの構成の差異 データ 処理 非オブジェクト指向 オブジェクト指向 メッセージ カプセル化 データ 処理
  39. 39. •  オブジェクトのカプセル化とは オブジェクト指向とカプセル化② データや処理をオブジェクト外部から隠蔽すること 定められた「可視性」に よって外部からアクセス できる。 エンジン 色 車名 走る 曲がる 止まる 車オブジェクト 振る舞い (処理) 属性 (データ)
  40. 40. •  インターフェースとは – オブジェクトが実行できる振る舞いを表明した もの オブジェクト指向とカプセル化③ 電源を入れる 電源を入れる チャンネルを変える メッセージ 振る舞い (処理)
  41. 41. オブジェクト指向とカプセル化④ •  クラスは属性と振る舞い(操作)を持っている •  クラスは実体を持たない •  オブジェクトはクラスをインスタンス化することで生成される実体 クラス 鯛焼きの型 鯛焼き 作る インスタンス化 オブジェクト (インスタンス)
  42. 42. オブジェクト指向とカプセル化⑤ •  インターフェースと   実装の分離 処理1  処理2 処理3  処理4 データA クラスA 処理1   処理3   インターフェース1       処理2 インターフェース2 クラスB クラスC 処理1、処理3が
 できるということ
 しか知らない 処理2ができると
 いうことしか
 知らない クライアント
  43. 43. クライアント オブジェクト指向とカプセル化⑥ •  クライアントは、扱うオブジェクトが求める インターフェースにしたがっている限り、 そのオブジェクトの型を知らなくてすむ。 •  クライアントは、これらのオブジェクトを実装 しているクラスを知らなくて済む。クライアン トは インターフェースについてのみ知っていれば よい。 •  当該インターフェースの振る舞いさえ保たれ れば、クライアントは、オブジェクトの内部実 装が変化しても影響は無い。 クラスB クラスC 処理1、処理3が
 できるということしか
 知らない 処理2ができるというこ としか知らない ! リファクタリングのポイント
  44. 44. 実装 実装 •  コンポーネントの形成 オブジェクト指向とカプセル化⑦ クラスA 処理1   処理3   インターフェース1       処理2 インターフェース2 一つのクラスでもよい クラスの集合体でもよい または コンポーネント
  45. 45. カプセル化とリファクタリング •  リファクタリングとは –  外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になる ように、ソフトウェアの内部構造を変化させること (出典:リファクタリ ング) コンポーネント単位で、これを適用する 振る舞い:コンポーネントとして提供するインターフェース 内部構造:クラス構造
  46. 46. 臭 い きれい 臭 い きれい •  リファクタリングとパターンの関係 パターン適⽤の意義① 同じようなクラス構造が よく出てくる… ・分析・抽出 ・一般化 ・カタログ化 リファクタリング コード 臭い コード きれい リファクタリング コード 臭い コード きれい 過去 現在 デザインパターン 指針
  47. 47. •  リファクタリングとパターンの関係 パターン適⽤の意義② リファクタリング規模 小 大 リファクタリング・ カタログ (出典:リファクタリング) デザインパターン (GoF) ・Factory Method ・State など 領 域 ! カタログやデザインパターンは リファクタリング全体の中では一部である
  48. 48. まとめ • オブジェクト指向 • カプセル化 • インターフェースと実装の分離 • コンポーネントの生成 • リファクタリング • コンポーネント内部のリファクタリング • クラス構造のリファクタリング デザインパターン 指針
  49. 49. •  ドルクラスの作成 class DollarFactory: Factory { func createDollarFactory() -> Money { let dollar = Dollar() dollar.setCurrency("USD") return dollar } } class Money { var amount: Double = 0 var currency: String = "" let rateUSDYEN: Double = 120.00 コードのリファクタリング
  50. 50. class Yen: Money { override func convert(money: Money) { setAmount(money.getAmount() * rateUSDYEN) } … class Dollar: Money { override func convert(money: Money) { setAmount(money.getAmount() * rateUSDUSD) } override func displayAmount() -> String { return String(format: "%.2f", amount) } } コードのリファクタリング(続き)
  51. 51. 関数型プログラミング
  52. 52. •  関数 •  高階関数 •  クロージャー •  遅延評価 •  並列処理 •  イミュータブル •  ラムダ式 •  マイクロサービス 関数型プログラミングの特徴
  53. 53. func loopCall (n: Int, f: (Int) -> Int) { for var i = 1; i < n+1; i++ { println(f(i)) } } loopCall(10, f: fiveTimes) func fiveTimes(value: Int) -> Int { return value * 5 } 関数型プログラミング例
  54. 54. 書籍でのコード •  通貨の変換関数 •  円とユーロを自動判定して 必要な関数を返して、使用する
  55. 55. func convert(cur: String) -> (Int -> String) { func convertY(inpch: Int) -> String { return String(format: "%.0f", Double(inpch) * rates["USDYEN"]!) } func convertE(inpch: Int) -> String { return String(format: "%.2f", Double(inpch) * rates["USDEUR"]!) } if cur == "YEN" { return convertY } else { return convertE } } convert()は関数を返す
  56. 56. func doConversion(){ outputCurrency.text = currency let convertOut = convert(currency) outputText.text = convertOut(inputTexts[0]) + " " + convertOut(inputTexts[1]) + " " + convertOut(inputTexts[2]) + " " + convertOut(inputTexts[3]) + " " + convertOut(inputTexts[4]) + " " + convertOut(inputTexts[5]) } 関数型へ変更したコード

×