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. 2 この技術講習会(先端技術勉強会)について ゆるくやっていくので、気軽にいきましょう! ⚫ 祝・新メンバー参加、メンバー15人継続。グループを超えて部門の活動となりつつあるので、 今まで通り続けていきます!! ⚫ 頻度は不定、基本1H+α、だいたい夕方にやっています。 ⚫ とりあえず始めてみて様子を見ながら続けます。

    ⚫ 説明中も適宜ブレイク(間)を挟むので、リアクションはその都度音声でもチャットでもOKです! ⚫ テーマはフリー、参加者から聞いたりして決めていきます。 ⚫ 今後のテーマ候補も募集中です! ⚫ 皆さんが講師をしてくれるのも大歓迎です! 第1回 ゴーファーくんと学ぶGo言語の世界 [以下、どれも再開催中] 第2回 AWSの基本情報の歩き方 第3回 ゴーファーくんと学ぶAWSサーバーレスの世界 第4回 ゴーファーくんと辿るプログラミング言語の歴史 第5回 ゴーファーくんたちと学ぶRust言語の世界 第6回 ゴーファーくんと探るMendixの有用性 第7回 ゴーファーくんたちと辿るJavaScriptの潮流 第8回 ゴーファーくんたちと辿るフロントエンドの潮流 第9回 ゴーファーくんたちと再訪するオブジェクト指向の潮流 ★今日はここ★
  2. 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」と略します
  3. 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をよく理解できていない開発者でも開発できる一方、のちのちに保守の観点から設計が問題になることも ←エドガー・ダイクス トラさん アラン・ケイさん→
  4. 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月号で 改めて特集
  5. 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
  6. 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の出典 最近の良本 両方を公平 に解説
  7. 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
  8. 10 4. OOの3要素:③継承/汎化 ◆ 親クラス(スーパークラスとも)の振る舞いを受け継ぐ(=変数、メソッドを受け継ぐ)。再利用できるのでコードの重複を排除できる ◆ 「共通部分を別クラスにまとめる仕組み」でもあるが、単なる差分プログラミングとは考えない方が良い。別の関数に外出しする方法でも 実現できるため ◆ 親に当たる抽象クラス・インターフェース、それを実装した子供の具象クラスを検討。子供クラスに共通する性質や振る舞い(=変数、メ

    ソッド)を見出して親に抜き出していく「汎化」のアプローチで考えていくと、上位概念の「良い抽象」を見つけることができる。抽象クラス と具象クラスを分けて考えることで、より良い設計に繋がる。これも設計を扱う多くの書籍で述べられている interface 飛べる abstract class 生物 abstract class 鳥類 class カラス fly() メソッド定義 メンバ変数age保有 getAge() メソッドを実装 インスタンスは作れない 変数age, getAge()を継承 fly() メソッドを実装強制 鳥類に共通するメソッドを実装 インスタンスはまだ作れない 親のすべてを継承 カラス特有のメソッドを実装 インスタンスが作れる class スズメ 抽象(クラス) 概念を表す 具象(クラス) アプリ内の主役 言語仕様としては…(Javaの例) ~インスタンスが作れない抽象の世界~ ▪インターフェース: メソッド定義のみ。実装(≒継承)したクラスに、 そのメソッド実装を強制 ▪抽象クラス: メンバ変数定義、メソッド定義、メソッドの中身の実装 も可能。 ~インスタンスが作れる具象の世界~ ▪スーパークラス、親クラス:イ ンスタンスが作れる普通のクラス。よ り親があったらそのメンバとメソッドを受け継ぐ。抽象クラスでもこう 呼ぶときもある。 ▪サブクラス、子クラス: 抽象、具象に関わらず親がいるクラス。 設計の文脈でいう具象クラスに対する「抽象クラス」、「インターフェー スに依存せよ! 」の話では、言語仕様におけるインターフェースと抽象 クラスの両方(抽象の世界)を概念的にまとめて指すこともある。 class 子供カラス 優れた特長だが、共通処理の親クラスへの 共通化くらいにしか使われないケースも。 そして時代の変化に伴い近年は…(次項) サブクラス。親のスーパーク ラスがカラス OOP Concepts: Inheritance (Generalization)
  9. 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… 解法は…
  10. 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と関係 ソフトウェアエンジニアリングの歴史・進化の中で、様々な事柄と直接/間接的に関係 デザパタでググると…
  11. 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公式では「モダンアプリケーション」は定義があるが「モダナイゼーション」は基幹シス テムの置き換え系の文脈の範囲。また「モダナイ」と略すのも日系企業のみで独特。 良本! 設計/構築/管理を継続的に見直 し変化を受け入れ続ける戦略、そこか ら逆算して技術を選定すると定義。 良本! デザパタの新 旧分類も載ってます 銀の弾丸はない: すべての問題を解 決する万能の解決策はない。ソフトウェアエン ジニアリング界の有名な格言。
  12. 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
  13. 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法と同名注意
  14. 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ワード以外でも... 朝はご飯 ←→ パン かわいいのは猫 ←→ 犬 お茶は紅茶 ←→ コーヒー うどん ←→ そば きのこの山 ←→ たけのこの里 がいねん 概念 ガイネン 我々は、かなり あいまいな世界に 生きている…!! どちらも かわいい
  15. 17 10. Reactのコンポーネント指向との関係 ◆ コンポーネント指向のベースにある考え方:部品を小さく分けて、修正箇所を小さく、追加しやすく、再利用性を高める ◆ 分割統治法: 大きなことは小さく分割して解決していこう。ソフトウェア設計の基本の考え方。語源は古代ローマ帝国 ◆ 単一責任原則:

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