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

ゴーファーくんたちと再訪するオブジェクト指向の潮流/tide-of-object-oriented

iwasiman
November 15, 2023

 ゴーファーくんたちと再訪するオブジェクト指向の潮流/tide-of-object-oriented

若手向けに定期開催しているミニ勉強会の資料です。今回はオブジェクト指向をテーマにしました。

iwasiman

November 15, 2023
Tweet

More Decks by iwasiman

Other Decks in Programming

Transcript

  1. 先端技術勉強会 技術講習会
    2023/11
    @iwasiman
    Advanced
    -STUDY GROUP-
    第9回 ゴーファーくんたちと再訪する
    オブジェクト指向の潮流
    Technology
    TECH-SESSION
    OOP:
    Object
    Oriented
    Programming

    View full-size slide

  2. 2
    この技術講習会(先端技術勉強会)について
    ゆるくやっていくので、気軽にいきましょう!
    ⚫ 祝・新メンバー参加、メンバー15人継続。グループを超えて部門の活動となりつつあるので、
    今まで通り続けていきます!!
    ⚫ 頻度は不定、基本1H+α、だいたい夕方にやっています。
    ⚫ とりあえず始めてみて様子を見ながら続けます。
    ⚫ 説明中も適宜ブレイク(間)を挟むので、リアクションはその都度音声でもチャットでもOKです!
    ⚫ テーマはフリー、参加者から聞いたりして決めていきます。
    ⚫ 今後のテーマ候補も募集中です!
    ⚫ 皆さんが講師をしてくれるのも大歓迎です!
    第1回 ゴーファーくんと学ぶGo言語の世界 [以下、どれも再開催中]
    第2回 AWSの基本情報の歩き方
    第3回 ゴーファーくんと学ぶAWSサーバーレスの世界
    第4回 ゴーファーくんと辿るプログラミング言語の歴史
    第5回 ゴーファーくんたちと学ぶRust言語の世界
    第6回 ゴーファーくんと探るMendixの有用性
    第7回 ゴーファーくんたちと辿るJavaScriptの潮流
    第8回 ゴーファーくんたちと辿るフロントエンドの潮流
    第9回 ゴーファーくんたちと再訪するオブジェクト指向の潮流 ★今日はここ★

    View full-size slide

  3. 第9回
    ゴーファーくんたちと再訪する
    オブジェクト指向の潮流
    なんとなく案内役
    ゴーファーくんと
    フェリスさんです
    目的: メンバーからの質問に応えたテーマ。
    ソフトウェアエンジニアリングに大きな役割を果たしてきた
    オブジェクト指向の歴史と現状をいまいちど概観し、
    理解の助けにしてもらう。
    OOP:
    Object
    Oriented
    Programming

    View full-size slide

  4. 1. オブジェクト指向の歴史①②
    2. OOの3要素:①カプセル化 続きで データクラス
    3. OOの3要素:②ポリモーフィズム
    4. OOの3要素:③継承/汎化 続きで 継承の問題点
    5. OOと関係する技術要素
    6. マイナス面とバズワード化
    7. 主要言語のOOとの関係
    8. 関数型言語の概略
    9. IT用語によくある二項対立
    10.Reactのコンポーネント指向との関係
    11.「~指向」には他に何があるのか
    12.本日のまとめ
    ゴーファーくんたちと再訪する
    オブジェクト指向の潮流
    OOP:
    Object
    Oriented
    Programming
    以降、「オブジェクト指向(Object Oriented)」を時々「OO」、
    「オブジェクト指向プログラミング」を「OOP」と略します

    View full-size slide

  5. 5
    1. オブジェクト指向(OO)の歴史①
    ◆ [20世紀] コンピュータが誕生。機械語→アセンブリ言語→人間に親しみやすい高級言語が発明。FORTLAN[1957]、COBOL[1960]
    ◆ [1960年代] 学者エドガー・ダイクストラさんが、正しく動くプログラムには分かりやすい構造が大事だという「構造化プログラミング」を提
    唱。 順次進行/条件分岐/繰り返しの基本三構造で構成。GOTO文は有害であることに人類も気付き、のちの言語からは廃止される
    ◆ [1967] 最初のOO言語 Simula67 誕生。当時のマシン性能限界もあり、研究などで使われるに留まる。 「クラス」という言葉誕生
    ◆ サブルーチン(≒今のサブ関数)の独立性が重要に。サブルーチン内のローカル変数や引数の値渡しの工夫。複数のサブルーチンから
    アクセスできるグローバル変数問題はまだ完全には消せなかった。構造化言語としてPascal[1970]、C言語[1972]などが誕生
    ◆ プログラムの使われる寿命が伸び、大規模化・複雑化。生産性向上/保守性向上/品質向上/再利用性の向上が重要になる。
    根本的には現代と同じである。それぞれの言語で進化が続く
    ◆ 「未来を予測する最善の方法は、それを発明することだ」の言葉で知られるアラン・ケイさんらが「オブジェクト指向(Object-Oriented)」と
    いう考えを発案。この人+他の凄い人々が研究してきたSmalltalk言語が[1980]公開。本格的なOO言語、デザインパターンの元に。
    当時はまだ継承の概念がなかったとされる
    ◆ [1983] 計算機科学者ビャーネ・ストロヴストルップさんがC++言語を公開。OOのパラダイムもサポート、未だに現役
    ◆ [1990年代] C++の後を継いだJavaがオブジェクト指向言語として一気に名を馳せる。Javaが有名になった背景にはインターネットのブーム、
    そしてオブジェクト指向のブームが大きいとされる
    ◆ [2000年代] オブジェクト指向がブームに。デザインパターン、UML、アジャイル、TDD、様々な関連する事柄が誕生し進化する一方で、
    バズワード的にも使われたり誤解のもとにもなる。(後述)
    ◆ [2005 v1] 一方、Ruby言語の有名FW Ruby on Railsが登場。FWが吐き出したクラスにコードを追加するスタイルが多く、設計をFWに任せ
    る形に。生産性が高くOOPをよく理解できていない開発者でも開発できる一方、のちのちに保守の観点から設計が問題になることも
    ←エドガー・ダイクス
    トラさん
    アラン・ケイさん→

    View full-size slide

  6. 6
    1. オブジェクト指向(OO)の歴史②
    ◆ [2010年代前半] スマホ時代、大量データ処理や並列処理が必要に。関数型プログラミングが注目される。
    関数型言語のScalaが注目されるが、OOをベースにした他の言語を置き換えるほどは流行らず…
    ◆ [2010年代] ネットでもオブジェクト指向はオワコン→次は関数型言語だ!的な、誤解の混じった言説も時折見られるように。
    実は対立する概念ではない。(後述)
    ◆ [2015] JavaScriptがES6で「モダンJavaScript」として完全復活。TypeScriptは[2014]にv1。クラスも書けるがそれほどOOP寄りではない。
    またKotlin[2011], Go[2012], Rust[2015]と2010年代生まれの言語は、OO言語と関数型言語の両方の特徴を併せ持つハイブリッドに(後述)
    ◆ [2010年代後半] 拡張し続けるソフトウェアで変化に対応し続けるには、保守性(≒変更容易性)が重要。ソフトウェア設計の重要性を、
    日本の若い企業群も改めて認識。著名な本では『CODE COMPLETE 第2版』[2005]を始め、『Clean Code』『テスト駆動開発』[2017]、
    『Clean Architecture』[2018]、『リファクタリング 第2版』[2019]、『達人プログラマー 第2版』[2020]。
    国内では『現場で役立つシステム設計の原則』[2017]、『ドメイン駆動設計入門』[2020]、『良いコード/悪いコードで学ぶ設計入門』[2022]、
    『ちょうぜつソフトウェア設計入門』[2022]…と設計関係の本も出揃ってくる。考え方の背景にあるOOにも脚光。
    国内のITエンジニア界隈でも設計への注目度が改めて上がり、アーキテクチャや各開発方法論が話題に
    ◆ [2020年代] 普及しきっているので言葉自体は以前ほどは聞かなくなったが、オブジェクト指向は普遍的に存在...
    ソフトウェアエンジニアリングの歴史・進化の上で、全体に
    多大なる貢献!! 実は20世紀の昔からある考え方で、明確
    な定義がない。有名なOOの3要素を次項から解説
    Javaエンジニアがよく
    入門した本 [2014]
    10年ぶりに2021に
    3版! やや古い記述も
    OOを定義できないのが混乱の
    元だと深堀りする、面白い本
    デザパタ本本家
    なんと [1999]
    2021/3月号で
    改めて特集

    View full-size slide

  7. 7
    2. OOの3要素:①カプセル化
    ◆ 変数と関数を1つのクラスの中に「まとめる」:
    ◆ 関数:昔はサブルーチンと呼ばれていたサブ関数がメソッドとしてクラスの中に整理、探しやすく、名前付けもしやすくなる
    ◆ 変数:従来の構造化プログラミングでは完全に消せなかったグローバル変数を撲滅できる。重要なデータ構造を定義できる。
    (ユーザー1人の情報、XYZの座標など。これはOO言語かに関わらず構造体でも可能)
    ◆ クラスの中身を外から「隠す=カプセル化」:
    ◆ 諸悪の根源だったグローバル変数を使わずにプログラミングできる
    ◆ 外から弄ってはいけない変数、弄ってはいけない関数を中に隠せる。保守性の向上、品質維持
    ◆ コード全体の構造から見渡していく場合、クラスの中身の詳細まで調べるステップが飛ばせて理解の時間が軽減。
    複雑さを中に閉じ込められる
    ◆ 設計の重要な要素である分割統治、単一責任原則(SRP: Single Responsibility Principle)、DRY原則(Don’t Repeat Yourself)を実現。
    関心の分離の境界線になり、より良い設計に
    ◆ インスタンスとして「たくさん作る」:
    ◆ 同じクラスでもインスタンスが違えば中身は別で独立。データ構造を実現でき理解しやすい
    ◆ インスタンスメソッドを使って処理すれば再利用化が進み、ロジックがよりシンプルになる
    class User {
    private String firstName; // 名
    private String lastName; // 姓
    // コンストラクタは省略
    public String getFullName() {
    return firstName + lastName;
    }
    }
    Userインスタンス
    アリス
    Userインスタンス
    ボブ
    ・外から姓・名はいじれない
    ・メソッドを通してのみアクセス
    ・ユーザ関係はこのクラスがやってくれる、
    中にデータを持っていると理解しやすい
    根底にあるのは再利用化を進め、
    メンテナンスをしやすい、よりよいソフトウェア設計
    OOP Concepts:
    Encapsulation

    View full-size slide

  8. 8
    2. OOの3要素:①の続き データクラス
    ◆ データクラスとロジッククラスが別々だと、ロジックがあちこちに重複する恐れがある。
    ◆ データ構造とロジックを別にするのはCOBOLやC言語製で汎用機の中で動いていた、手続き型プログラミング時代の古い設計である...
    結局、善悪の定義や明確な使い分け基準はない。
    時代の変化と共にOOの解釈も変わってきた一例
    変数のみでメソッドがないクラスをデータ格納用の「データクラス」などと呼んだりする。
    オブジェクトとしての振る舞いがないからこれはOO的によろしくない、データとロジックが一体化してこそのクラスだとする考え方もある。
    ◆データクラス is bad とする考え方 (伝統的、ドメイン駆動設計の文脈で重視)
    ◆データクラス is not bad 、必要に応じて使ってよいのでは?とする考え方 (最近はこちらが多い)
    ◆ 設計パターンのDTO:Data Transfer Object。異なるレイヤー、サブシステムやコンポーネント間など、異なるかたまり間で
    データのやり取りをするときに使うデータの入れ物クラス。実体はまさにデータクラス
    ◆ Java言語の仕様にあるJava Beans:こちらも特定クラスを継承して作る、データの入れ物クラス
    ◆ Java文化圏では、メンバ変数だけあってデータ構造を表すシンプルなクラスをPOJO: Plain Old Java Object (ポジョ) と称し
    用語で使う。他の言語でもC#(.NET)ではPOCO: Plain Old CLR Object がある。”ポコ”でかわいい。
    ◆ DBに永続化可能なオブジェクトをEntityと呼んだり。これも中身はだいたいデータクラス。
    (設計手法、アーキの文脈で異なる定義で用いられたりする)
    ◆ Javaの後継言語Kotlinでは、必要メソッドも準備されたデータクラスをコンストラクタ宣言のみで書ける文法がある。
    後追いでJava16からRecordクラスが導入。Pythonも3.7からdataclassesが導入と、言語仕様レベルでも対応がある
    ◆ そもそも動的型付け言語では、連想配列やJavaScriptオブジェクトだけでデータ構造が済んでしまうこともある。
    ◆ オブジェクトの生存期間が長ければ非データクラスで、と判断するのが
    よいともされる。バックエンドの長い長いロジックの中など。
    設計が学べる良本 割と
    データクラスis badの文脈
    PofEAA本
    DTOの出典
    最近の良本
    両方を公平
    に解説

    View full-size slide

  9. 9
    Ratクラス...
    3. OOの3要素:②ポリモーフィズム
    ◆ 「多態性」、「多様性」とも訳されるが、結局分かりにくいので「ポリモーフィズム」と呼ばれる
    ◆ 別のクラスからなるオブジェクトがそれぞれ同名のメソッドを実行した際、それぞれ異なる動作をすること
    ◆ という説明でも結局分かりにくいが、鍵は「それらのクラスを呼び出す側の修正がより少なくなる」。ifやswitchの分岐が不要になり、
    変更に強くなる=保守性向上。呼び出し側からみると、すべて同じ呼び出し方を持つプラグインのように扱える
    ◆ 適切に使うと威力は大きく、世の中の様々なライブラリ類の中でも効果的に活用。テストコードでも活用。
    このインターフェイスに依存することの重要性は、設計を扱う多くの書籍でも強調されている
    ここでも根底にあるのは、修正規模が減り
    変更に強い、よりよいソフトウェア設計
    Class Zoo {
    private Animal performer;
    public Zoo() {
    // コンストラクタ内やどこかで、
    // performerをセット。ここで切り替え
    }
    // 特別で楽しいショーを実行します
    public void doSpecialShow() {
    performer.doHappyPerform();
    }
    }
    interface Animal {
    public void doHappyPerform();
    }
    Dogクラス {
    該当メソッド実装 {
    //アクロバットして
    //遠吠えだワン!
    }
    }
    Catクラス {
    該当メソッド実装 {
    //キュートな猫ダンス
    //可愛く決めるニャア
    }
    }
    Animal型で犬でも猫でもすべて表現で
    き、メソッド内では分岐が不要!
    Zooクラス側は切り替えるだけで、いろ
    んなショーを実演できる
    ~より実務に近い例~
    ログ出力を実装: テキスト出力ログ/DB出力ログ/何
    もしないログ...を切り替え
    ファイル読み込み: 対象をtext/CSV/Excel…で
    切り替え
    RDBアクセス: 対象を
    SQLServer/MySQL/Postgre…で切り替え
    キャッシュ機能: 自前のファイルキャッシュ/メモリ
    キャッシュ/各種ライブラリ…で切り替え
    などの様々なケースで活用できる
    Rabbitクラス
    OOP Concepts:
    Polymorphism

    View full-size slide

  10. 10
    4. OOの3要素:③継承/汎化
    ◆ 親クラス(スーパークラスとも)の振る舞いを受け継ぐ(=変数、メソッドを受け継ぐ)。再利用できるのでコードの重複を排除できる
    ◆ 「共通部分を別クラスにまとめる仕組み」でもあるが、単なる差分プログラミングとは考えない方が良い。別の関数に外出しする方法でも
    実現できるため
    ◆ 親に当たる抽象クラス・インターフェース、それを実装した子供の具象クラスを検討。子供クラスに共通する性質や振る舞い(=変数、メ
    ソッド)を見出して親に抜き出していく「汎化」のアプローチで考えていくと、上位概念の「良い抽象」を見つけることができる。抽象クラス
    と具象クラスを分けて考えることで、より良い設計に繋がる。これも設計を扱う多くの書籍で述べられている
    interface 飛べる abstract class 生物
    abstract class 鳥類
    class カラス
    fly() メソッド定義
    メンバ変数age保有
    getAge() メソッドを実装
    インスタンスは作れない
    変数age, getAge()を継承
    fly() メソッドを実装強制
    鳥類に共通するメソッドを実装
    インスタンスはまだ作れない
    親のすべてを継承
    カラス特有のメソッドを実装
    インスタンスが作れる
    class スズメ
    抽象(クラス)
    概念を表す
    具象(クラス)
    アプリ内の主役
    言語仕様としては…(Javaの例)
    ~インスタンスが作れない抽象の世界~
    ■インターフェース: メソッド定義のみ。実装(≒継承)したクラスに、
    そのメソッド実装を強制
    ■抽象クラス: メンバ変数定義、メソッド定義、メソッドの中身の実装
    も可能。
    ~インスタンスが作れる具象の世界~
    ■スーパークラス、親クラス:イ ンスタンスが作れる普通のクラス。よ
    り親があったらそのメンバとメソッドを受け継ぐ。抽象クラスでもこう
    呼ぶときもある。
    ■サブクラス、子クラス: 抽象、具象に関わらず親がいるクラス。
    設計の文脈でいう具象クラスに対する「抽象クラス」、「インターフェー
    スに依存せよ! 」の話では、言語仕様におけるインターフェースと抽象
    クラスの両方(抽象の世界)を概念的にまとめて指すこともある。
    class 子供カラス
    優れた特長だが、共通処理の親クラスへの
    共通化くらいにしか使われないケースも。
    そして時代の変化に伴い近年は…(次項)
    サブクラス。親のスーパーク
    ラスがカラス
    OOP Concepts:
    Inheritance (Generalization)

    View full-size slide

  11. 11
    class 11月専用処理 {
    private BigCalendar calendar;
    // 11月専用処理だけを親に委譲
    void processForNov() {
    this.calendar.baseProcForNov();
    // その後の処理
    }
    }
    4. OOの3要素:③継承/汎化 継承の問題点
    継承ではなく親クラスをインスタンスとして中に
    含め、必要な機能だけを呼び出す。
    親クラスの影響を受けにくくなり、変更に対応
    しやすくなる。
    「コンポジション」 (composition)もしくは
    「継承より移譲(もしくは継承より合成)」
    (Composition over inheritance)
    と呼ばれ、近年よく使われるワード。
    継承is悪ではない(これも大事)。しかし
    こちらも、時代の変化と共にOOの解釈が
    変わってきた一例
    OOが一般化して世の中で多数使われるようになるに従い、近年では継承の問題点も話題に上るようになってきた。
    class BigCalendar
    baseProcForJan()
    baseProcForFeb()
    baseProcForMar()…
    class 11月専用処理
    クラス・継承関係が巨大になってくると、
    メソッドを変更したら子クラス全てに
    影響してしまう。壊れる可能性あり
    子クラスで親クラスのメソッドを書き直
    さなければならず、同じようなコードを
    複製しなければいけない場合も
    class 車
    drive()
    class 飛行機
    fly()
    class 空飛ぶ車
    C++, Pythonは多重継承が可能だ
    が、混乱しがち。(菱形継承問題)
    ほとんどの言語では単一継承のみ。
    右の空飛ぶ車が実現できない。
    →継承でなくインターフェースを使う
    のがうまい解決方法。
    ほか、ライブラリやフレームワーク自作
    レベルだと継承も活用できるが、
    業務アプリなどでは継承を多用する
    ケースがそれほどは出てこなかったり
    する
    class x..
    class x..
    class x..
    流用したいのは baseProcForNov()
    だけなのに、全メソッドを継承! 誤用のも
    とになる。パブリックAPIが増えてしまう。
    Javaの後継Kotlinは、クラスにopenをつけないとデフォ
    ルト継承禁止。
    Go, Rustのように言語仕様で継承を取り入れないモダ
    ン言語も。かわりにトレイト(trait)というもので関数の処
    理だけ定義、構造体に紐づけてクラス的にも使えたり。
    このトレイトは継承に似た機能がある。
    class 乗り物
    class BaseA
    class BaseB
    class BaseC
    class 業務
    class BaseD…
    解法は…

    View full-size slide

  12. 12
    5. OOと関連する技術要素
    ◆ ライブラリ、フレームワーク類: 仕組みの中でOOを有効活用している例も多い。世界中で再利用が促進
    ◆ デザインパターン: OOを活用した設計パターンのノウハウ集。GoF:Gang of Four(ゴフ)のデザインパターン23種[1995-]が有名。2000年代
    のJavaエンジニアはだいたいデザパタも学んでいくのが通例だった。2020年代の現在では、パターンのいくつかはもう古いとされる
    ◆ UML: Unified Modeling Language(統一モデリング言語)の略、ソフトウェアの機能や構造を定義されている図で記述する記法。
    2000年代のOO全盛期に盛んにもてはやされた。現在ではクラス図・シーケンス図など一部が残存
    ◆ モデリング: 業務を分析して情報の構造を概念データモデルで表現、詳細化していく。データベースの設計に繋がる。これもOOと類似
    ◆ アジャイル開発:人間・迅速さ・顧客・適応性に価値を置いたソフトウェア開発手法。OOとイコールではないが、小さな単位で開発する、
    変化に対応していく…などOOと大きく関係。アジャイルソフトウェア開発宣言[2001]を行った著名な17人もOOと関係が深い人が多い
    ◆ TDD: Test Driven Development (テスト駆動開発)。 [2002] ケント・ベックさんが提唱した、テストコードを
    先に書きながらコードを書いていく手法。 テスト用ライブラリでもOOが有効活用されている
    ◆ リファクタリング: Refactoring。マーチン・ファウラーさんの本が有名。[2000-] プログラムの外部仕様を変えずに
    内部構造を安全に改善していく。ここでもOOを活用したテクニック多数
    ◆ SOLID原則: ロバート・C・マーチンさんが明文化したオブジェクト指向原則で5つある [2002]
    ◆ ドメイン駆動設計: DDD: Domain-Driven Design。[2003] 設計手法のひとつ。OOと密接に関係
    ◆ より良いソフトウェア設計の原理・原則全般: 重複の排除、部品の独立性を高める、
    かたまりの凝縮度を上げてかたまり同士の結合度を下げる、依存は一方向に…
    などが、まさにOOと関係
    ソフトウェアエンジニアリングの歴史・進化の中で、様々な事柄と直接/間接的に関係
    デザパタでググると…

    View full-size slide

  13. 13
    6. マイナス面とバズワード化
    ◆ 現実世界の全てはオブジェクトとして表現できる!:主に2000年代に書籍などでもてはやされたが、実際には
    そんなことはない。ソフトウェアの中に限った話。プログラムの整理の話やよりよい設計の話で捉えるとよい
    ◆ UMLに脚光→完璧なクラス図やシーケンス図があればコードは完全自動生成できる!:できない。時間をかけて長大な設計書を書いて
    実装を軽んじる古い考え方とも繋がる。そうした生成ツールもあったが流行らず、UML自体も一部を除き廃れた。
    現代では主なところだけ軽くクラス図を書いたり、設計しながらコードも書いたり
    ◆ デザインパターンやOOの過信:現在でも役に立つ知識だが、いくつかのパターンはもう時代にそぐわないとも言われる。より難解な設計、
    より量の多いコードになっては意味がない。「OO的に正しいか」の観点でコードレビューするのは原理主義的になる危険がある
    ◆ OOがすべてを解決する万能の解決策です!:「アジャイル」と並んで、このように魔法の言葉として使われがちでもあった…
    定義があいまい、小難しく、なんか凄そう、人によって
    解釈が違う「オブジェクト指向」は、まさにバズワード向
    けであり“銀の弾丸”のようにも扱われてきた。定着し
    きった現在は、あまり目にしなくなってきている
    このようにオブジェクト指向の価値は大きく、ソフトウェアエンジニアリングの発展に大いに寄与してきたのだが、一方で誤解されやすい面も…
    バズワードとして使われがちなワードの例:
    ・[ゼロ年代] Web2.0 [いま] Web3.0
    ・ユビキタス
    ・アジャイル、オブジェクト指向
    ・NoSQL
    ・ビッグデータ
    ・クラウド
    ・クラウド関連のワード(サーバーレス、クラウドネ
    イティブなど)
    ・マイクロサービス
    ・DX / 2025年の崖
    ・RPA
    ・モダナイゼーション
    ・ローコード
    ・AI / 生成AI / LLM / ChatGPT (今ココ!)
    バズワード(buzzword): 定義が曖昧でありながら、権威付けする専門用語や人目を引く
    キャッチフレーズとして、特定の時代や分野の人々の間で通用する言葉。
    英語でDX: Developer Experienceで「開発者体験」の意も(最近はDevExとも)。
    翻訳本の技術書では「DX」という言葉は使われていない。
    AWS公式では「モダンアプリケーション」は定義があるが「モダナイゼーション」は基幹シス
    テムの置き換え系の文脈の範囲。また「モダナイ」と略すのも日系企業のみで独特。
    良本! 設計/構築/管理を継続的に見直
    し変化を受け入れ続ける戦略、そこか
    ら逆算して技術を選定すると定義。
    良本! デザパタの新
    旧分類も載ってます
    銀の弾丸はない: すべての問題を解
    決する万能の解決策はない。ソフトウェアエン
    ジニアリング界の有名な格言。

    View full-size slide

  14. 14
    7. 主要言語のOOとの関係
    言語名 解説
    C [1972-] 構造化プログラミングのパラダイム。クラスはなく構造体はある。
    C++ [1983-] OOをサポート。カプセル化、継承、多態性もあり。多重継承ができる。
    C# [2002-] C++の欠点を改良、Javaと並んでOO全盛期の主役。のちのVerでは型推論などJavaより早い進化。不変
    値、高階関数など関数型言語のアプローチも導入中。
    Java [1991-] 90年代後半~のOOブームと重なり普及。多重継承禁止、OOの特長を一通り備えたデファクトに。デザ
    インパターン、よい設計やコードの本にはサンプルがJavaのものが一番多い。Stream APIの導入、型推論など後
    追いで関数型のエッセンスも取り入れようとしている。
    Scala [2003-] 関数型言語の流れを受け継ぐとして2010年代前半に注目されたが、その後あまり振るわず…。
    Kotlin [2011-] Better Java。null安全、継承はデフォルト不可、データクラスの記法、型推論、トップクラスとmainメソッ
    ドがなくても実行可能と、動的型付け言語や関数型言語の考えも当初から導入。
    PHP [1995-] 途中からクラスを導入し型も導入、OOも一通り可能に。関数型の考えも取り入れしぶとく生き残る。
    Ruby [1995-] OO言語として設計、一通り実践可能。第一級関数、パターンマッチングなど関数型の機能も。
    Python [1991-] クラスと継承あり、インターフェースがなく抽象基底クラスで代用。OOもサポートするが他言語ほど
    厳密でないといわれる。短いスクリプトでのデータ処理、機械学習などだとあまりOOが出てこないかも。
    JavaScript/
    TypeScript
    [1995-] プロトタイプベースでJSオブジェクトにはメンバ変数も関数も格納可能、OOではあるが独特。後から
    クラスも書けるようになったがシンタックスシュガーであまり使わない。フロントエンドではFWのReactも
    関数型寄り。バックエンドでもクラス多用は避けた方が良いとされ、全体的にOOとやや距離がある。
    Go [2012-] クラスがなく構造体。関数でのふるまいの追加は可能、インターフェースはあり、継承は取り入れず。型
    推論あり。最初からOOと関数型の両方のエッセンスを取り入れる。
    Rust [2015-] 変数がデフォルト不変なのも関数型寄り。Goと同様、当初からOOと関数型の両方のエッセンス。
    Ruby界隈で著名な
    設計本









    OOP:
    Object
    Oriented
    Programming

    View full-size slide

  15. 15
    8. 関数型言語の概略
    ◆ 関数でプログラムを書く:OO言語も関数を使うが、関数が単なる処理のかたまりでなく、数学的な関数 y=f(x)と同等の定義。
    引数と戻り値を必ず持つ。引数と戻り値に関数を指定できる
    ◆ 式が必ず値を返す:プログラムの命令文を「式」と呼び、関数もデータもみな式で値を返す。関数の戻り値は最後に評価した式の値になり、
    return文が不要なものが多い
    ◆ 関数を値として扱える:関数の引数や戻り値に関数を指定できる。この性質を「第一級関数」(first-class function)と呼び、この性質を使っ
    て引数に関数を取るか、戻り値を関数にしている関数を「高階関数」(higher-order function)と呼ぶ。主要言語の解説にも時々出てくる
    ◆ 受け取った引数と関数を組み合わせられる:部分適用したり、新しい関数を合成したり
    ◆ 「副作用」を起こさない:「引数から戻り値を求めること以外の仕事」をしない。オブジェクトを渡したら求めるもの以外のメンバ変数も
    書き換えられて戻り値で返ったりしない。関数型言語では変数の内容を後から変更できず、「束縛」と呼ぶ。
    何回実行しても引数が同じなら戻り値は必ず同じになるのを「参照透過性」と呼ぶ。クラウドのサーバーレス、FaaS(AWS Labmda, Azure
    Functions)の文脈でもよく出てくる言葉。この副作用を起こさないことは、OO言語でもより良い関数設計の上では重要
    ◆ 場合分け(=パターンマッチ)と再帰処理でループを記述:for文やwhile文がない。簡潔にループを記述できる
    ◆ コンパイラが型推論してくれる:関数そのものも引数と戻り値の型を使って「型」を持つ
    関数型
    言語
    オブジェクト
    指向言語
    オブジェクト
    指向言語
    関数型
    言語
    宿命の
    熱いバトル
    モダンな言語群は
    だいたいこのへん
    実際:境い目は曖昧、大き
    さも形も違う概念で、重な
    り合っている
    一見したイメージ:
    二者択一に見えるが…
    主要言語に影響を与えた純粋
    関数型言語としてよく上がる
    Haskell (ハスケル)
    FP:
    Functional
    Programming
    見積のFP法と同名注意

    View full-size slide

  16. 16
    9. IT用語によくある二項対立
    「オブジェクト指向」はまさに、
    二項対立で使われがちなワードでもあった...
    二項対立:論理学において、二つの概念が
    矛盾または対立の関係にあること。
    ITワードには一見するとこの二項対立に
    見えるが、実際は
    「真ん中がある」「組み合わせられる」
    「3つめ以降の選択肢がある」「状況や文脈
    に応じて選択するもの」「そもそも概念があ
    いまい」「好きでええやん」
    ...などなど、実際には二項対立する概念
    ではないものがけっこうある。
    ■二項対立的に使われがちなワードの例
    (ネタが混じってます):
    手続き型 ←→ オブジェクト指向
    オブジェクト指向言語 ←→ 関数型言語
    静的型付け言語 ←→ 動的型付け言語
    RDB ←→ NoSQL DB
    ウォーターフォール ←→ アジャイル
    オンプレ ←→ クラウド
    モノリス ←→ マイクロサービス
    AWS ←→ Azure
    インデントはタブ派 ←→ スペース派
    React ←→ Vue.js
    jQueryはオワコン ←→ ReactかVue.js
    SIer ←→ Web系
    Windows ←→ Mac (Linuxを入れるのもアリ)
    iPhone ←→ Android
    人間 ←→ AI
    ■ITワード以外でも...
    朝はご飯 ←→ パン
    かわいいのは猫 ←→ 犬
    お茶は紅茶 ←→ コーヒー
    うどん ←→ そば
    きのこの山 ←→ たけのこの里
    がいねん
    概念
    ガイネン
    我々は、かなり
    あいまいな世界に
    生きている…!!
    どちらも
    かわいい

    View full-size slide

  17. 17
    10. Reactのコンポーネント指向との関係
    ◆ コンポーネント指向のベースにある考え方:部品を小さく分けて、修正箇所を小さく、追加しやすく、再利用性を高める
    ◆ 分割統治法: 大きなことは小さく分割して解決していこう。ソフトウェア設計の基本の考え方。語源は古代ローマ帝国
    ◆ 単一責任原則: SOLID原則の同名の原則と同じ。ひとつのコンポーネント(≒OOのクラス)はひとつの仕事だけをする
    「再利用性を高めてよりよいソフトウェア設計を目指す」という
    根本的な目的においては、オブジェクト指向と「だいたい似てる」、
    ぐらいのイメージの理解で大丈夫
    コンポーネント指向: アプリ開発で分割した部品を組み合わせて開発する考え方。フロントエンド/バックエンドとも、
    ロジックの奥よりはユーザーインターフェースに近いところでよく使う。
    Reactコンポーネント OO言語のクラス
    定義 JavaScript/TypeScriptの関数。昔はクラス
    コンポーネントもあったが今は非推奨
    言語仕様に基づいたクラス
    コンス
    トラクタ
    定義時の引数で親コンポーネントから
    受け取ったりするところが該当
    言語仕様のコンストラクタ
    メンバ
    変数
    コンポーネント内のローカル変数が
    たぶん該当
    言語仕様で定義。プロパティ、
    フィールドなど呼び名複数
    メソッド コンポーネント内で関数を定義したり
    呼んだりするところがたぶん該当
    言語仕様で定義
    戻り値 JSX記法で書かれたHTMLの描画内容 クラスに戻り値はない
    インスタ
    ンス
    Reactインスタンスというものはない
    (Vue.jsにはある)
    言語仕様で定義
    ◆この考えを元に、画面表示内容とロジック
    をまとめたものがReactコンポーネント
    ◆オブジェクト指向の特長との関係は…
    ◆ カプセル化:まさに実現
    ◆ ポリモーフィズム:ちょっと違う
    ◆ 継承/汎化:子コンポーネントは親コンポーネントの
    性質を受け継ぐわけではないが、propsを通して
    値を受け取っていくところは似てはいるかも?
    親コンポーネント
    条件部コンポーネント
    ページ全体の描画
    Reactによる1つのWebアプリケーション
    検索結果一覧コンポーネント
    検索条件 ▼
    検索結果1件
    コンポーネント
    Vue.jsのコンポーネント指向も
    根本の考え方はだいたい同じ
    データをここで持ったり

    View full-size slide

  18. 18
    11. 「~指向」には他に何があるのか
    ◆ エージェント指向:OOは「モノ」だったが、それが発展したエージェントが自発的に考えて処理するという考え方。
    OOの後に来ると21世紀初めに言われていたが、結局廃れた。
    ◆ アスペクト指向プログラミング(AOP: Aspect Oriented Programming):アプリ内の「横断的関心事」(各領域の共通処理。ログなど)を外
    出ししてモジュール化しようという考え方。言語レベルの試みもあったが、JavaのSpring FWに機能で存在するぐらいに留まる。
    ◆ サービス指向アーキテクチャ (SOA: Service Oriented Architecture):複数のサービスの集合でネットワーク通信してビジネスアプリを作
    ろうという考え方。2000年代のJava全盛期に提唱されたが実現が難しく流行らず。クラウド時代のマイクロサービスに受け継がれた。
    ◆ データ指向:CPU性能ではなく、データの量や複雑さや変化の速度が課題であるアプリケーションを対象に、よりよい形を
    追求するアプローチ。DB、ストレージ、クラウド、分散システムなど様々な技術要素が関連。
    ◆ 関数型指向:「オブジェクト指向」の対になる言葉としてはこちらよりも、「関数型プログラミング」のほうを比較的よく見る
    ◆ データベースの種類の話:オブジェクト指向DB(流行らなかった)、グラフ指向DB(AWSのNeptune、 AzureはGremlin)、
    通常のRDBは行指向、列指向DBもある(Apache Cassandra)
    ◆ 日本語では「志向」が、「個人の意識や気持ちがある方向、対象に向かっている」。例:キャリア志向、安定志向、健康志向、ブランド志向
    ◆ 日本語では「指向」は「物理的にある方向を向いている」。例:指向性アンテナ、指向性マイク
    ◆ 科学では「指向性」は「音、電波、光などが空間中に出力されるとき、強度が方向によって異なる性質」の定義
    ◆ ITワードとしては「指向」「志向」あまり区別がない
    イメージ。志向を見ないような?
    言葉によって概念の対象や大きさがまったくバラバラなのに注意。
    ソフトウェアエンジニアリング全体に与えた影響の大きさで言えば、
    「オブジェクト指向」ほど大きな概念、動きは(たぶん)他にはない。
    「~指向」 英語では ~ Oriented 。抽象的で便利な言葉なので、ワードだけなら様々ある。大きさはさまざま。
    「ユーザー指向」「お客様指向」などワードであればいくらでも作れる。結局バズワードで廃れたものも…
    オライリーの良本!
    そして分厚い…

    View full-size slide

  19. 19
    12. 本日のまとめ
    ◆オブジェクト指向の源流を辿ると1970年頃から始まり、マシン性能/プログラミング
    言語/エンジニアリングの考え方/関連技術やツール…など諸々の進化と共に発展し、
    ソフトウェア開発全体に大きな役割を果たしています。
    ◆一方、有名な格言の「銀の弾丸はない」はここでも有効で、万能の解決策では
    ありません。統一された明確な定義がないのが混乱の原因でもあります。
    ◆その根底にあるのは、「ソフトウェア設計をより良くする」という普遍的な目標だ、
    というのを踏まえつつ見ていくと良いでしょう。
    Creative Commons Attributions 3.0
    The Gopher character is based on the Go mascot designed by Renée French.
    それではまた次回!
    資料中の様々なロゴやマスコットはその言語や技術の公式・非公式のものです。書影はその書籍・雑誌のものです。
    ぼくらの言語にも受け継がれているんだよね
    次回以降の
    テーマ
    募集中です!!
    (講師も…笑)

    View full-size slide