オブジェクト指向プログラミングをSCSSで雑に(小声)紹介してみる

目黒.css #5

@omiend

@omiend

SKILLS:PeopleSoft,Java,Shell,MySQL,SQL,Salesforce(Force.com/ApexCode/VisualCode),GAE(Slim3),ABAP,Scala(ScalaMatsuri Staff),Ruby on Rails,Docker,Angular(1.4…),React/Redux,Riot.js,Vue.js,Nuxt.js

FAV:

Musics,Movies,Joging,Walking,Drink Driven Development

 

プログラマー。

一応フロントエンドからバックエンドまで一通り出来ると思い込んでいる飲んだくれダメェンジニア。

昨年まで音楽雑誌を作るお手伝いをしてました。最近は時々パン屋さんでクロワッサン売ってます。

自己紹介

JVMの世界で生きてきたCSS苦手おじさんが

SCSSでオブジェクト指向プログラミングをしてみた話をします。


OOCSSとはまったく関係ございません。

今日話すこと

オブジェクト指向についてはLTで話しきれるものでもなく、また私個人の見解も多分に含まれております(それもただの経験則)。

 

当内容を利用した際に発生した事故・障害などについて、オミエンドはいかなる責任も負いかねます。

 

当内容に関することについてご利用の際は、現場の上司上長アーキCTOから指示された用法、用量を守って正しくお使いください

免責事項

> プログラムを「オブジェクト」の集合体として構築し、オブジェクトはデータ(状態)を主とし、コード(動作)を従として構成され、無数のオブジェクトが相互に作用し合うようにして任意の処理が実行される。

Wikipedia

オブジェクト指向って?

 

今回Javaのソースコードで説明しようと思ったけど、確実に迷子になりそうなのでボツ・・・😇

Javaのソースコードは下記に・・・。

https://code.sololearn.com/c36xj3tS9AEc/#java

なるほどワカラン

オブジェクト指向って?

ので、登場するワードだけ軽く紹介。

  • クラス
  • 抽象化継承具象化
  • 多様化(ポリモーフィズム)

オブジェクト指向って?

オブジェクト指向って?

まず、動作させる対象となる”オブジェクト”を用意する。

オブジェクト指向って?

次に、これらの”オブジェクト”に共通することを考える。

オブジェクト指向って?

次に、これらの”オブジェクト”に共通することを考える。

・電源を入れる

オブジェクト指向って?

次に、これらの”オブジェクト”に共通することを考える。

・電源を入れる

・ゴミを吸い取る、洗濯する、曲を流す

オブジェクト指向って?

次に、これらの”オブジェクト”に共通することを考える。

・電源を入れる

・ゴミを吸い取る、洗濯する、曲を流す

・電源を切る

オブジェクト指向って?

次に、これらの”オブジェクト”に共通することを考える。

・電源を入れる

・ゴミを吸い取る、洗濯する、曲を流す

・電源を切る

この"オブジェクト"を、クラス(class)という単位でそれぞれ実装する。

オブジェクト指向って?

ここから効率化を図るために、抽象化していく。

オブジェクト指向って?

これらの”オブジェクト”に共通するコトは、機械であるということ。

オブジェクト指向って?

機械を表すオブジェクトを、親オブジェクトとする。

実際の動作対象となるオブジェクトを、子オブジェクトとする。

オブジェクト指向って?

機械って?

・電源を入れる

・ゴミを吸い取る、洗濯する、曲を流す

・電源を切る

オブジェクト指向って?

機械って?

・電源を入れる

・ゴミを吸い取る、洗濯する、曲を流す

・電源を切る

→共通の処理

オブジェクト指向って?

機械って?

・電源を入れる

・ゴミを吸い取る、洗濯する、曲を流す

・電源を切る

→モノによって違う

オブジェクト指向って?

機械って?

・電源を入れる

動作(ゴミを吸い取る、洗濯する、曲を流す)させる

・電源を切る

→抽象化させる

  ※「動作」にまとめる

オブジェクト指向って?

親オブジェクト(abstract class)を用意し、共通処理となる「電源ON/電源OFF」機能を実装する。

オブジェクト指向って?

子オブジェクト(concrete class)用意し、親オブジェクト継承(extend)して具象化する。

オブジェクト指向って?

継承することで子オブジェクトでも共通処理を利用することができる。

電源ON/OFFできるよ!!

電源ON/OFFできるよ!!

電源ON/OFFできるよ!!

オブジェクト指向って?

さらに、親オブジェクトに対して子オブジェクトでも必ず必要となる「動作」という処理の元(概念?)だけ定義しておき・・・

オブジェクト指向って?

子オブジェクトでそれぞれ動作を実装する。

洗濯する。

音楽を流す。

ゴミを吸う。

オブジェクト指向って?

さらに「ゴミパックを取り付ける」「水を入れる」「カセットを挿入する」など必要になるが、いずれの何かを受け取ったとしても、共通の動作するという行為自体は問題なくできる。

オブジェクト指向って?

これを多様化(ポリモーフィズム)という。

処理を多様化させられることで、柔軟な実装が可能となる。

※ちょっと雑すぎる説明かも

水で洗濯する。

カセットの

音楽を流す。

ゴミを吸ってゴミパックにためる。

オブジェクト指向って?

これを多様化(ポリモーフィズム)という。

処理を多様化させられることで、柔軟な実装が可能となる。

※ちょっと雑すぎる説明かも

水で洗濯する。

カセットの

音楽を流す。

ゴミを吸ってゴミパックにためる。

オブジェクト動作を切り分けて

プログラミングするのが

オブジェクト指向プログラミング

SCSSでオブジェクト指向

作るモノ

 

良くオブジェクト指向プログラミングで題材にあがる「車」を作成する。

 

車は「オブジェクト(ハコ、タイヤ、エンジン)」「特徴(多様化)」の宝庫。

SCSSでオブジェクト指向

SCSSの機能を利用し、オブジェクト指向な設計を実現させる。

 

オブジェクト・クラス → class

ただのCSSのclassを利用する。

 

抽象化・継承・具象化 → class / @extend

@extendは、すでに定義されたclassの内容を継承した新しいclassを定義することができる。

 

多様化(ポリモーフィズム) → @mixin / @include

@mixinは、引数を取る関数のようなものを定義できる。@include利用する。

まず、車を具象化させるための子クラスを用意する。

 

子クラスにはパーツを受け取るdivが定義されている。

<div class="nussan">
  <div class="parts_roof"></div>
  <div class="parts_front_glass"></div>
  <div class="parts_side_glass"></div>
  <div class="parts_bonnet"></div>
  <div class="parts_trunk"></div>
  <div class="parts_front_grill"></div>
  <div class="parts_front_fender"></div>
  <div class="parts_door"></div>
  <div class="parts_rear_fender"></div>
  <div class="parts_front_tire"></div>
  <div class="parts_rear_tire"></div>
  <div class="parts_right_light"></div>
  <div class="parts_left_light"></div>
</div>

SCSSでオブジェクト指向

html

class / @extend

親クラス(abstract class)を用意する。

 

親クラスには、車として具象化するために必要な屋根やタイヤなどのパーツが定義されている。

SCSSでオブジェクト指向

  .abstract-car {
    .parts_common {
      width: 50px;
      border: 1px solid black;
      position: absolute;
    }
    .parts_roof {
      @extend .parts_common;
      height: 50px;
      transform: matrix(1, -0.5, 1, 0.5, 0, 0);
      z-index: 20;
    }
    .parts_front_glass {
      @extend .parts_common;
      height: 30px;
      transform: matrix(1, -0.5, 0, 1, 25, 37);
      background-color: lightblue;
      z-index: 20;
    }
    // ・・・
    .parts_right_light {
      @extend .parts_common;
      height: 20px;
      width: 20px;
      transform: matrix(1, -0.3, 0, 1, 55, 95);
      background-color: yellow;
      border-radius: 50%;
      z-index: 10;
    }
    .parts_left_light {
      @extend .parts_common;
      height: 20px;
      width: 20px;
      transform: matrix(1, -0.3, 0, 1, 85, 80);
      background-color: yellow;
      border-radius: 50%;
      z-index: 10;
    }
  }

scss

次にSCSSの@extendを利用し、子クラス(concrete class)親クラスを継承

nussan車を具象化する。

SCSSでオブジェクト指向

.nussan {
  @extend .abstract-car;
}

scss

scss

scss

  .abstract-car {
    .parts_common {
      width: 50px;
      border: 1px solid black;
      position: absolute;
    }
    .parts_roof {
      @extend .parts_common;
      height: 50px;
      transform: matrix(1, -0.5, 1, 0.5, 0, 0);
      z-index: 20;
    }
    .parts_front_glass {
      @extend .parts_common;
      height: 30px;
      transform: matrix(1, -0.5, 0, 1, 25, 37);
      background-color: lightblue;
      z-index: 20;
    }
    // ・・・
    .parts_right_light {
      @extend .parts_common;
      height: 20px;
      width: 20px;
      transform: matrix(1, -0.3, 0, 1, 55, 95);
      background-color: yellow;
      border-radius: 50%;
      z-index: 10;
    }
    .parts_left_light {
      @extend .parts_common;
      height: 20px;
      width: 20px;
      transform: matrix(1, -0.3, 0, 1, 85, 80);
      background-color: yellow;
      border-radius: 50%;
      z-index: 10;
    }
  }

多様化させるための処理を定義する。

SCSSの@mixinは、@includeすることで共通の処理をclassに定義することができる。

SCSSでオブジェクト指向

// 車の色を変更する
@mixin trait-body-color($_color:white) {
  div {
    background-color: $_color;
  }
}

scss

.nussan {
  $body-color:black;
  $engine-spec: 2s;
  @extend .abstract-car;
  @include trait-body-color($body-color);
}

scss

最大スピードを指定できる(多様化)エンジンも実装すれば走り出す!

SCSSでオブジェクト指向

// 車の色を変更する
@mixin trait-body-color($_color:white) {
  div {
    background-color: $_color;
  }
}

// エンジンを積むことで走るコトができる
// エンジンのスペックを指定できる
// Spec=スピード
@mixin trait-engine($_speed) {
  animation: drive $_speed
                     cubic-bezier(0.56, 0.13, 0.17, 0.58)
                     0s infinite normal forwards running;
}

scss

.nussan {
  $body-color:black;
  $engine-spec: 2s;
  @extend .abstract-car;
  @include trait-body-color($body-color);
  @include trait-engine($engine-spec);
}

scss

SCSSでオブジェクト指向

デモ

まとめ

やってみた感じ

・SCSSではオブジェクト指向プログラミングするための部品はそろっている。

・ある程度オブジェクト指向設計でSCSSできたように思う。

まとめ

しかし

・abstract classの利用シーンが思い浮かばない。
・再利用性ができなければ・・・。
・再利用できたとしてもカオス化するのでは・・・。
・例えば

 

・今回作ったオレオレオブジェクト指向CSSに比べると
OOCSSって結構よくできているのでは?
 

<form class="form-class { @extend abstract-class }">

ご清聴ありがとうございました。

 

オブジェクト指向プログラミングを、SCSSで雑に(小声)紹介してみる

By omiend

オブジェクト指向プログラミングを、SCSSで雑に(小声)紹介してみる

  • 1,512