Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java初心者が知っておくべきプログラミングのこと - JJUG CCC 2022 Spring

Java初心者が知っておくべきプログラミングのこと - JJUG CCC 2022 Spring

2022年6月19日に開催されたJJUG CCC 2022 Springでの登壇資料です

Naoki Kishida

June 10, 2022
Tweet

More Decks by Naoki Kishida

Other Decks in Programming

Transcript

  1. JJUG CCC 2022 Spring Java初心者が知っておくべき プログラミングのこと 2022/6/19 JJUG CCC 2022

    Spring きしだ なおき
  2. JJUG CCC 2022 Spring 自己紹介 • きしだ なおき (@kis) •

    LINE Fukuoka • 「プロになるJava」デテマス • 今日の話の具体的なコードのせてます
  3. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    プログラムを作るための技術
  4. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    計算論 • アルゴリズム • プログラムを作るための技術 • Javaの文法 • 標準ライブラリ • オブジェクト指向 • テスト
  5. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    計算論 • アルゴリズム • プログラムを作るための技術 • Javaの文法 • 標準ライブラリ • オブジェクト指向 • テスト 知らないと動かせない 知らないと書けない
  6. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    計算論 • アルゴリズム • プログラムを作るための技術 • Javaの文法 • 標準ライブラリ • オブジェクト指向 • テスト 入門書がない 入門書がある
  7. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    計算論 • アルゴリズム • プログラムを作るための技術 • Javaの文法 • 標準ライブラリ • オブジェクト指向 • テスト 入門書がない 入門書がある 入門書を読んでも 動くプログラムが書けない
  8. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    計算論 • アルゴリズム • プログラムを作るための技術 • Javaの文法 • 標準ライブラリ • オブジェクト指向 • テスト 入門書がない 入門書がある プログラムを動かせないと意味がないのに 入門書にある プログラムを動かすのに必要っぽく 書いてあったりする 入門書を読んでも 動くプログラムが書けない
  9. JJUG CCC 2022 Spring プログラミング技術 • プログラミング技術は大きくわけて2つ • プログラムを動かすための技術 •

    計算論 • アルゴリズム • プログラムを作るための技術 • Javaの文法 • 標準ライブラリ • オブジェクト指向 • テスト おおまかに載ってます
  10. JJUG CCC 2022 Spring 話すこと • プログラムを動かすための技術 • プログラムの処理がなぜ難しいか •

    処理の難しさの分類 • プログラムを作るための技術 • オブジェクト指向がなぜ難しいか • オブジェクト指向をうまく使うには
  11. JJUG CCC 2022 Spring 話すこと • プログラムを動かすための技術 • プログラムの処理がなぜ難しいか •

    処理の難しさの分類 • プログラムを作るための技術 • オブジェクト指向がなぜ難しいか • オブジェクト指向をうまく使うには
  12. JJUG CCC 2022 Spring プログラムの処理がなぜ難しいか • 状態遷移の理解 • 計算の複雑さ

  13. JJUG CCC 2022 Spring 状態遷移の理解 • プログラムの処理では状態が変わっていく • 通常の文章は状態一定 •

    推理小説でも「犯人はヤス」という状態を徐々に記述している • 途中を飛ばしたり、読む順番を入れ替えても、表現される状態は変わらない • プログラムは途中を飛ばしたり実行する順番を入れ替えると保持する 状態が変わる • 状態が変わっていくこと=状態遷移を理解する必要がある
  14. 代表的な状態 • 逐次実行 • 変数 • ループ

  15. 代表的な状態 • 逐次実行 • どの行を実行するかという状態が変わっていく(プログラムカウンタ)

  16. 代表的な状態 • 変数 • 再代入可能な変数は状態を保持している • 状態を保持する変数は再代入が必要 • 再代入不可な変数は状態を管理しないので理解しやすい? •

    変数の難しさは、逐次実行で値が設定されることと状態をあらわして いることとにあるんではないだろうか
  17. 代表的な状態 • ループ • ループの処理では状態が変わっていく • ループのない処理からはプログラムカウンタ以外の状態を排除できる • ループの難しさは状態遷移ではないだろうか •

    あとで詳しく説明
  18. 逐次実行や状態遷移を把握するには • JShellで一行ずつ実行する • デバッガで実行の過程や変数の変化を確認する

  19. JJUG CCC 2022 Spring 計算の複雑さ • 計算自体に複雑さがある • 複雑さには階層がある •

    組み合わせ論理 • 有限オートマトン • プッシュダウンオートマトン • チューリングマシン
  20. JJUG CCC 2022 Spring 計算の複雑さ • 計算自体に複雑さがある • 複雑さには階層がある •

    組み合わせ論理(状態がない) • 有限オートマトン(状態がある) • プッシュダウンオートマトン(スタックが必要) • チューリングマシン (スタックが二つ必要=なにかデータ構造が必要)
  21. JJUG CCC 2022 Spring 計算の複雑さ • 計算自体に複雑さがある • 複雑さには階層がある •

    組み合わせ論理(論理素子の結線で実装可) • 有限オートマトン(クロックとレジスタが必要) • プッシュダウンオートマトン(FIFOが必要) • チューリングマシン (自由にアクセスできるメモリが必要)
  22. JJUG CCC 2022 Spring 話すこと • プログラムを動かすための技術 • プログラムの処理がなぜ難しいか •

    処理の難しさの分類 • プログラムを作るための技術 • オブジェクト指向がなぜ難しいか • オブジェクト指向をうまく使うには
  23. JJUG CCC 2022 Spring 処理の難しさ • 計算複雑さは理論的で実感とは異なる • 逐次処理はどこを実行しているかの状態をもつ •

    有限オートマトン以上の複雑さになる • 多くの処理ではスタックは不要 • プッシュダウンオートマトンよりは単純
  24. JJUG CCC 2022 Spring 処理の難しさ • 有限オートマトンを細分化する • それぞれの特徴をつかんで、それぞれをトレーニングすることで 難しい処理がかけるようになっていくのでは?

  25. JJUG CCC 2022 Spring 処理の難しさの分類 • ループがない • ループの各処理が独立 •

    集計が必要 • 他のデータを利用 • 隠れた状態を扱う • 状態を明示的に管理する • スタックが必要
  26. JJUG CCC 2022 Spring ループがない • 状態を考えなくていい • 変数の再代入は不要

  27. JJUG CCC 2022 Spring ループの各処理が独立 • 変数の再代入は不要 • 例: 配列のデータを表示する

  28. JJUG CCC 2022 Spring 集計が必要 • 変数の再代入が必要 • 例: 配列のデータを合計する

  29. JJUG CCC 2022 Spring 集計が必要 • Streamが使える • ループを考えなくていい •

    変数の再代入が不要
  30. JJUG CCC 2022 Spring 他のデータを参照 • 拡張forやStreamでは書けない • 例:重複排除、移動平均 https://nowokay.hatenablog.com/entry/2022/04/25/130057

  31. JJUG CCC 2022 Spring 隠れた状態を扱う • 隠れた状態をみつける必要がある • 変数で管理する必要がある •

    例:ランレングス圧縮 カッコが対応しているか検査 https://nowokay.hatenablog.com/entry/2022/04/26/183544
  32. JJUG CCC 2022 Spring 状態を明示的に管理する • 状態の遷移が複雑で管理が必要 • 状態遷移図を書く •

    各状態の処理は単純なので難しさに 気づかずたくさんのフラグを導入してしまう ことがある • 例:文字列が実数として妥当か判定 受注・入金・発注などの管理
  33. JJUG CCC 2022 Spring スタックを使う • 入れ子のある処理 • 再帰を使って書ける •

    例:深さ優先探索 カッコ付数式処理 種類のあるカッコの対応を判定
  34. JJUG CCC 2022 Spring プログラムを動かすための技術のまとめ • 作るための技術だけじゃなく動かすための技術も必要 • 処理の難しさに段階があるので、把握して練習しておくと 難しい処理にも対応できるようになる

  35. JJUG CCC 2022 Spring 話すこと • プログラムを動かすための技術 • プログラムの処理がなぜ難しいか •

    処理の難しさの分類 • プログラムを作るための技術 • オブジェクト指向がなぜ難しいか • オブジェクト指向をうまく使うには
  36. JJUG CCC 2022 Spring オブジェクト指向がなぜ難しいか • 必要ないところで使おうとしているからです

  37. JJUG CCC 2022 Spring オブジェクト指向がなぜ難しいか • 必要なところで使うと難しくないし便利

  38. JJUG CCC 2022 Spring オブジェクト指向がハマるところは? • GUIフレームワークを作るとき • 作る機会はめったにない •

    つまりオブジェクト指向がハマる機会はめったにない • オブジェクト指向が流行ったタイミングでGUIプログラミングが流行り 始めたので、いろいろなプログラミングにオブジェクト指向がハマる と勘違いしたのではと思っている
  39. JJUG CCC 2022 Spring オブジェクト指向がなぜ難しいか • オブジェクト指向とはなにか • 「パラダイム」にだまされているのでは?

  40. JJUG CCC 2022 Spring オブジェクト指向とはなにか • 「データ構造と振る舞いが一体となったオブジェクトの集まりと してソフトウェアを組織化すること」 ~「オブジェクト指向方法論OMT」ジェームズ・ランボー~ •

    OMTは「オブジェクト指向」の重要な源流のひとつ • ジェームズ・ランボー • 1980年代のオブジェクト指向ブームの中心人物のひとり • ブーチ、ヤコブソンと共に「スリーアミーゴズ」と呼ばれた • OMT、ブーチ法、OOSEを統合するときの統一記法がUML
  41. JJUG CCC 2022 Spring オブジェクト指向とはなにか • オブジェクト指向の基準 (「オブジェクト指向入門」~バートランド・メイヤー) • 「支援する方法論も含めて、オブジェクト指向言語および環境は、ラ

    イフサイクル全体に適用され、作業段階の間の隔たりを最小限にする ものでなければならない」 • 「クラスが唯一のモジュールでなければならない」 • 「すべての型はクラスに基づいていなければならない」 • モジュールと型が一致する
  42. JJUG CCC 2022 Spring オブジェクト指向の特徴 • カプセル化 • データの一部を外部からみえなくする •

    データとデータに対する操作をまとめることで実現する • 多態(ポリモーフィズム) • 同じメソッド呼び出しが、操作対象によって振る舞いを変えること • 継承 • クラスの機能を再利用して拡張する • 型理論の部分型(サブタイピング)を実現する
  43. JJUG CCC 2022 Spring オブジェクト指向の特徴の実際 • カプセル化 • 抽象データ型としてオブジェクト指向以前から存在した •

    カプセル化をクラスとして実現するのがオブジェクト指向、といえる • 多態(ポリモーフィズム) • 関数を値としてもつことでオブジェクト指向以外でも実現化 • Javaの場合はラムダ式 • 継承 • 機能を再利用するというコンセプトはオブジェクト指向に固有といえ そうだけど、あまり機能の再利用としては使われなくなっている • 型理論の部分型として考えるほうが整理されている
  44. JJUG CCC 2022 Spring オブジェクト指向の特徴の実際 • カプセル化 • 抽象型としてオブジェクト指向以前から存在した •

    カプセル化をクラスとして実現するのがオブジェクト指向、といえる • 多態(ポリモーフィズム) • 関数を値としてもつことでオブジェクト指向以外でも実現化 • Javaの場合はラムダ式 • 継承 • 機能を再利用するというコンセプトはオブジェクト指向に固有といえ そうだけど、あまり機能の再利用としては使われなくなっている • 型理論の部分型として考えるほうが整理されている オブジェクト指向に こだわらなくていいのでは
  45. JJUG CCC 2022 Spring 「パラダイム」にだまされているのでは • パラダイム – 考え方の枠組み •

    パラダイムの例 • オブジェクト指向 • 関数型 • 構造化
  46. JJUG CCC 2022 Spring 「パラダイム」にだまされているのでは • パラダイムは暗黙にプログラミング全体を方向づけるように 語られる • 実際はパラダイムでプログラム全体を方向づけれない

  47. JJUG CCC 2022 Spring 「パラダイム」にだまされているのでは • イメージ:パラダイムはアプリケーション実装方針の枠組み • 実現するためにそのパラダイムの言語を使う •

    実際:パラダイムは言語機能の枠組み • 言語はいろいろなパラダイムの言語機能を独自の方針で組み込む • アプリケーション実装方針は言語次第 要求 アプリケーション オブジェクト指向 Java オブジェクト指向言語なら 同じ実装方針のまま代替可 イメージ 要求 アプリケーション Java オブジェクト指向 関数型 構造化 実際 言語が変わると 実装方針も変わる
  48. JJUG CCC 2022 Spring 「パラダイム」にだまされているのでは • 言語非依存な「オブジェクト指向プログラミング」なんてない • パラダイムに沿ったオブジェクト機能がある •

    言語によって「オブジェクト機能」の実現方法が違う • 言語によって「オブジェクト機能」以外の機能との関係も違う • 結局、言語ごとに言語機能を活かしてプログラミングする オブジェクト指向に こだわらなくていいのでは
  49. JJUG CCC 2022 Spring 話すこと • プログラムを動かすための技術 • プログラムの処理がなぜ難しいか •

    処理の難しさの分類 • プログラムを作るための技術 • オブジェクト指向がなぜ難しいか • オブジェクト指向をうまく使うには
  50. JJUG CCC 2022 Spring 話すこと • プログラムを動かすための技術 • プログラムの処理がなぜ難しいか •

    処理の難しさの分類 • プログラムを作るための技術 • オブジェクト指向がなぜ難しいか • オブジェクト指向機能をうまく使うには
  51. JJUG CCC 2022 Spring オブジェクト機能をうまく使うには • アプリケーションのアーキテクチャ • 差分プログラミング •

    データの定義と分類
  52. JJUG CCC 2022 Spring アプリケーションのアーキテクチャ • アプリケーションの構造はレイヤー構造が主流 • レイヤーは関数的 •

    クラスは単なる関数置き場 • プログラム的には自由に統合分割できる • データはオブジェクト • 操作はデータの正規化、別表現の生成 • 他のデータと直接やりとりしない
  53. JJUG CCC 2022 Spring レイヤー構造はオブジェクト指向か • 「データ構造と振る舞いが一体」になってない • 「オブジェクトの集まりとしてソフトウェアを組織化」 されてない

    • 「ライフサイクル全体に適用され」てない
  54. JJUG CCC 2022 Spring レイヤー構造はオブジェクト指向か • 「データ構造と振る舞いが一体」になってない • 「オブジェクトの集まりとしてソフトウェアを組織化」 されてない

    • 「ライフサイクル全体に適用され」てない オブジェクト指向とは言い難い
  55. JJUG CCC 2022 Spring レイヤーを流れるデータはオブジェクト指向か • 「データ構造と振る舞いが一体」になっている • 「オブジェクトの集まりとしてソフトウェアを組織化」 してるほどではない

    • 「ライフサイクル全体に適用され」てるとは言えない • レイヤーが変わるときに詰め替えることがある
  56. JJUG CCC 2022 Spring レイヤーを流れるデータはオブジェクト指向か • 「データ構造と振る舞いが一体」になっている • 「オブジェクトの集まりとしてソフトウェアを組織化」 してるほどではない

    • 「ライフサイクル全体に適用され」てるとは言えない • レイヤーが変わるときに詰め替えることがある オブジェクト指向と 言ってもいいかもしれないが 余分な話がついてくるので 抽象データ型と考えるのが いいんでは
  57. JJUG CCC 2022 Spring レイヤー構造でのオブジェクト機能の使い方 • レイヤー • 似たような処理の異なる部分を抜き出す差分プログラミング •

    データ • 抽象データ型 • 継承を使ってデータを分類する
  58. JJUG CCC 2022 Spring 差分プログラミング • 似たような処理のうち異なる部分を抜き出す • メソッドは似たような処理のうち共通部分を抜き出す

  59. JJUG CCC 2022 Spring 継承による差分プログラミング • 共通部分をもつクラスを定義 • 差分は抽象メソッドとして定義 •

    継承して実装 • テンプレートパターン
  60. JJUG CCC 2022 Spring ラムダ式による差分プログラミング • 差分プログラミングはラムダ式を使うほうが簡潔

  61. JJUG CCC 2022 Spring データの定義と分類 • 「オブジェクト指向」はアプリケーション全体の設計まで含み データの定義方法を考えるには範囲が広すぎるので抽象データ型 として考える •

    メソッドはデータの整合性の保障や別表現の生成を行う • 継承を使ってデータの分類を行う
  62. JJUG CCC 2022 Spring プログラムを作る技術のまとめ • プログラムを動かすための技術ではない • まずは動かせるようになろう •

    オブジェクト指向が適用できるところは限定的 • 現代のアプリケーション構造にあわせて利用方法を絞る • オブジェクト機能としてJava言語の機能に集中する
  63. JJUG CCC 2022 Spring まとめ • プログラミングは作り方だけじゃなく動かし方も勉強する 必要がある • JShellやデバッガで逐次実行を確認しよう

    • ループを分類して、難しいループも書けるようにしよう • 入門書を読んでるとオブジェクト指向に惑わされることがある けど、プログラムが動かせるようになってから考えよう • Javaの機能を使いこなすことを考える