Your SlideShare is downloading. ×

Rpscala2011 0601

979

Published on

scala勉強会 渋谷 …

scala勉強会 渋谷

Scaalでプログラム作ってみたのでScalaの作法を教えてください

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
979
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1.
    • Scala でプログラム作ってみたので
    • Scala の 作法を教えてください
  • 2. 自己紹介
    • ( 株 ) オープンストリーム 所属
    • twitter yangiYa
    • COBOL -> Java (-> Scala になれたら。。 )
    • 会社ではあまりプログラム作る 機会がなくなってきた。欲求不満
    • Scala は去年の秋ぐらいからはじめた
    • Scala の書籍で読んだもの
      • Scala プログラミング入門
        • デイビッド・ポラック ( 日経 BP 社 )
      • プログラミング Scala
        • Dean Wamloer/Alex Payne ( オライリー )
  • 3.
    • 作ってみたもの
    • 説明
  • 4.
    • 行列モデルを Scala で実装
  • 5. 利用用途
    • 行列で表現できる概念に汎用的に利用
    • 「物体」 ( ゲームのキャラクタなど ) の座標
    • 「物体」の速度
    • 「物体」の大きさ
    • 将棋、囲碁、チェス、オセロ、などの駒の位置
  • 6. 要求仕様(モデルの値)
    • 座標は、x,y,z
    • x,y,z のデフォルトは Double
    • 平面上のオブジェクト表現の場合は、 x,y だけで管理したい
    • x,y,z を整数で管理したい場合もある。 ( 整数同士の計算結果が少数点以下の数字にならないようにしたい)
  • 7. 要求仕様(モデルのサービス)
    • 行列の加算
      • ( 2,1 ) + (3,1) = (5,1)
  • 8. 要求仕様(モデルのサービス)
    • 行列の k 倍
      • ( 2,1 ) × 3 = (6, 3 )
  • 9. インタフェース設計
    • trait Matrix {
    • /**[[scala.Int]] 型の x 座標 */
    • def xByInt: Int
    • /**[[scala.Int]] 型の y 座標 */
    • def yByInt: Int
    • /**[[scala.Int]] 型の z 座標 */
    • def zByInt: Int
    • /**x 座標 */
    • def x: Double
    • /**y 座標 */
    • def y: Double
    • /**z 座標 */
    • def z: Double
    • }
  • 10. インタフェース設計
    • /** この行列と引数の行列の和を返却する */
    • def add(matrix: Matrix): Matrix
    • def +(matrix: Matrix): Matrix = add(matrix)
  • 11. インタフェース設計
    • /** この行列の実数倍 ( 引数 ) を返却する */
    • def product(scalarValue: Long): Matrix
    • /** この行列の実数倍 ( 引数 ) を返却する */
    • def product(scalarValue: Int): Matrix
    • /** この行列の実数倍 ( 引数 ) を返却する */
    • def product(scalarValue: Double): Matrix
  • 12. インタフェース設計
    • /** この行列に実数倍 ( 引数 ) した行列と、この行列との和を返却する */
    • def productValueAndAdd(scalarValue: Long): Matrix
    • /** この行列に実数倍 ( 引数 ) した行列と、この行列との和を返却する */
    • def productValueAndAdd(scalarValue: Int): Matrix
    • /** この行列に実数倍 ( 引数 ) した行列と、この行列との和を返却する */
    • def productValueAndAdd(scalarValue: Double): Matrix
  • 13. 要求仕様(非機能)
    • 低いオブジェクト生成コスト 頻繁に利用されるバリューオブジェクトを想定
    • スレッドセーフ 複数のスレッドから利用されることを想定
    • 利用者インタフェースのみに縛られる
      • 利用者は具象クラスや内部実装に縛られたくない
      • インタフェースを守る範囲で内部実装は自由に変えたい
  • 14. 非機能要求からの方針
    • オブジェクト生成コストは小さいほうがいい
      • オブジェクトが使うメモリは小さく
      • オブジェクト生成時の処理ロジックは少なく
    • イミュ ー タブル
      • 複数スレッドからも安全に使用できる
    • インターフェースを維持し、かつ、利用局面に応じた具象クラスを使えるようにする
      • オブジェクト生成は、 java の static ファクトリーメソッドのようなイメージで
        • (Java の例 ) java.util.Calendar#getInstance() ==>Scala では、 object の         apply メソッドがよさそう
  • 15. モデル設計 ( 一部抜粋 ) MatrixWithDouble x:Double y:Double z:Double MatrixWithInt xByInt:Int yByInt:Int zByInt:Int MatrixWithInt2D xByInt:Int yByInt:Int zByInt:Int = 0 MatrixWithDouble2D x:Double y:Double z:Double = 0.0 Matrix x:Double y:Double z:Double xByInt:Int yByInt:Int zByInt:Int << インタフェース >>
  • 16. オブジェクト生成
    • object Matrix { // ・・・コンパニオンオブジェクトと呼ばれる?
    • def apply(x: Int, y: Int, z: Int): MatrixWithInt =
    • MatrixWithInt(x, y, z)
    • def apply(x: Int, y: Int): MatrixWithInt2D =
    • MatrixWithInt2D(x, y)
    • def apply(x:Double,y:Double,z:Double): MatrixWithDouble =
    •                          MatrixWithDouble(x, y, z)
    • def apply(x: Double, y: Double): MatrixWithDouble2D =
    •                          MatrixWithDouble2D(x, y)
    • }
  • 17. 機能仕様(=テスト仕様)抜粋
    • assert(Matrix(1, 2, 3) === MatrixWithInt(1, 2, 3))
    • val mtx10_20_30Double = MatrixWithDouble(1.0, 2.0, 3.0)
    • assert(Matrix(1.0, 2.0, 3.0) === mtx10_20_30Double)
    • assert(Matrix(1.0, 2, 3) === mtx10_20_30Double)
    • assert(Matrix(1, 2) === MatrixWithInt2D(1, 2))
    • assert(Matrix(1.1, 2.2) === MatrixWithDouble2D(1.1, 2.2))
  • 18. 機能仕様(=テスト仕様)抜粋
    • val mtx21_32_0 = MatrixWithInt2D(21, 32)
    • assert((Matrix(1, 2) + Matrix(20, 30)) === mtx21_32_0)
    • assert(Matrix(20, 30) + (Matrix(1, 2)) === mtx21_32_0)
    • val mtx111_222_333 = MatrixWithDouble(11.1, 22.2, 33.3)
    • assert(Matrix(10, 20) + Matrix(1.1, 2.2, 33.3) ===
    •                         mtx111_222_333)
    • assert(Matrix(1.1, 2.2, 33.3).add(Matrix(10.0, 20.0)) ===
    •                            mtx111_222_333)
  • 19. 機能仕様(=テスト仕様)抜粋
    • var m1: Matrix = Matrix(1, 2)
    • var m2: Matrix = Matrix(10, 20)
    • assert(m1 + m2 === MatrixWithInt2D(11, 22))
  • 20. 実装:オーバーロードとオーバーライド
    • sealed trait Matrix {
    • /** この行列と引数の行列の和を返却する */
    • def add(matrix: Matrix): Matrix = Matrix(x + matrix.x, y + matrix.y, z + matrix.z)
    • }
    • private[core] abstract trait MatrixWithIntBase extends Matrix {
    • def add(point: MatrixWithInt): MatrixWithInt = MatrixWithInt(xByInt + point.xByInt, yByInt + point.yByInt, zByInt + point.zByInt)
    • def add(point: MatrixWithIntBase): MatrixWithIntBase = MatrixWithInt(xByInt + point.xByInt, yByInt + point.yByInt, zByInt + point.zByInt)
    • }
  • 21. 実装:オーバーロードとオーバーライド
    • final case class MatrixWithInt2D private[core](xByInt: Int, yByInt: Int) extends MatrixWithIntBase with Matrix2D {
    • def add(matrix: MatrixWithInt2D): MatrixWithInt2D = MatrixWithInt2D(xByInt + matrix.xByInt, yByInt + matrix.yByInt)
    • def +(matrix: MatrixWithInt2D): MatrixWithInt2D = add(matrix)
    • override def add(matrix: MatrixWithIntBase): MatrixWithIntBase = matrix match {
    • case pointWithInt2D: MatrixWithInt2D => add(pointWithInt2D)
    • case pointWithInt: MatrixWithInt => add(pointWithInt)
    • case other => super.add(other)
    • }
    • }
  • 22. 機能と実装の 説明おわり
  • 23. もっとやるとしたら (今回やってません)
    • 機能要求
      • 行列の回転
    • 非機能要求
      • Flyweight パターン
      • オブジェクトキャッシュ
  • 24. 感想 と 知りたいこと
  • 25. 感想 - Scaladoc class と object が横並び コンストラクタを private に したら表示されない リンクはもっと柔軟にかけたらいいのに
  • 26. Scaladoc リンクはもっと柔軟にかけたらいいのに
    • [[ クラス名フル修飾 ]] でリンクになる
      • パッケージ名を書くの面倒。 import されているのは、シンプルなクラス名だったらいいのに
    • メソッドへのリンクつくれないの? なんか方法ないですか。おしえてください
    • Scaladoc 文法を書いてあったページが なくなっているような。。。 (Scaladoc 2 Documentation for Authors)
  • 27. Scaladoc コンストラクタを private にしたら表示 されない
    • private コンストラクタが表示されないことは うれしい
    • 利用者に、どうやってインスタンス化するかは、ドキュメントに書くしかないか?
      • 誰もが迷うことなくインスタンス化する方法を 把握できればいいのに。 いい方法ないでしょうか。
  • 28. Scaladoc class と object が横並び
      • コンパイルした結果の
        • &quot;class Hoge&quot; と &quot;object Hoge&quot; は 型の関係はなにもないはず
        • コンパイル後のクラスファイル名ってホントはちがう
          • Hoge 、 Hoge$ のようなかんじ。。。
      • 設計上、暗黙の守るべきルールがあるのかではなかろうか? 教えてください
  • 29. object と apply メソッド
    • 今回作ったものの中では。。。
    •                              コード再掲
    • sealed trait Matrix
    • object Matrix {
    • def apply(x: Int, y: Int, z: Int): MatrixWithInt = MatrixWithInt(x, y, z)
    • def apply(x: Int, y: Int): MatrixWithInt2D = MatrixWithInt2D(x, y)
    • def apply(x: Double, y: Double, z: Double): MatrixWithDouble = MatrixWithDouble(x, y, z)
    • def apply(x: Double, y: Double): MatrixWithDouble2D = MatrixWithDouble2D(x, y)
    • }
    • ファクトリ役として使った
  • 30. object と apply メソッド
    • コンストラクタより、 apply メソッドのほうが、 柔軟にインスタンス生成できる
      • 生成する型を柔軟に切り替えられる
      • シングルトンを返却したり、こっそりインスタンスをキャッシュすることもできる
      • 利用者のコードを変更せず、内部実装を切り替えられる
        • こっそり、非パブリックなインスタンスを返却する用変更なんてことも可能
      • 使用者が意図的に生成するインスタンスの型を決めたいなら、 apply メソッドで作らず、 &quot;createHoge&quot; みたいなメソッドのほうがいい
      • コンストラクタより劣ること
        • めんどくさい
  • 31. object と apply メソッド
    • コンパニオンオブジェクト
      • 使命はなに? おしえてください
        • class と同名の object をこうよぶのか?
      • case class Foo() 、 object Foo val foo :Foo = Foo 後ろの Foo はオブジェクトなのかクラスなのかややこしい
        • class と object が関係あるよとの意思表示として object Foo extends Foo とかしたほうがいいとかあるのかな。。
  • 32. おわり ありがとう ございました

×