omiend
Hey dude. I'm omiend.
目黒.css #5
@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から指示された用法、用量を守って正しくお使いください!
> プログラムを「オブジェクト」の集合体として構築し、オブジェクトはデータ(状態)を主とし、コード(動作)を従として構成され、無数のオブジェクトが相互に作用し合うようにして任意の処理が実行される。
今回Javaのソースコードで説明しようと思ったけど、確実に迷子になりそうなのでボツ・・・😇
Javaのソースコードは下記に・・・。
なるほどワカラン
ので、登場するワードだけ軽く紹介。
まず、動作させる対象となる”オブジェクト”を用意する。
次に、これらの”オブジェクト”に共通することを考える。
次に、これらの”オブジェクト”に共通することを考える。
・電源を入れる
次に、これらの”オブジェクト”に共通することを考える。
・電源を入れる
・ゴミを吸い取る、洗濯する、曲を流す
次に、これらの”オブジェクト”に共通することを考える。
・電源を入れる
・ゴミを吸い取る、洗濯する、曲を流す
・電源を切る
次に、これらの”オブジェクト”に共通することを考える。
・電源を入れる
・ゴミを吸い取る、洗濯する、曲を流す
・電源を切る
この"オブジェクト"を、クラス(class)という単位でそれぞれ実装する。
ここから効率化を図るために、抽象化していく。
これらの”オブジェクト”に共通するコトは、機械であるということ。
機械を表すオブジェクトを、親オブジェクトとする。
実際の動作対象となるオブジェクトを、子オブジェクトとする。
機械って?
・電源を入れる
・ゴミを吸い取る、洗濯する、曲を流す
・電源を切る
機械って?
・電源を入れる
・ゴミを吸い取る、洗濯する、曲を流す
・電源を切る
→共通の処理
機械って?
・電源を入れる
・ゴミを吸い取る、洗濯する、曲を流す
・電源を切る
→モノによって違う
機械って?
・電源を入れる
・動作(ゴミを吸い取る、洗濯する、曲を流す)させる
・電源を切る
→抽象化させる
※「動作」にまとめる
親オブジェクト(abstract class)を用意し、共通処理となる「電源ON/電源OFF」機能を実装する。
子オブジェクト(concrete class)用意し、親オブジェクトを継承(extend)して具象化する。
継承することで子オブジェクトでも共通処理を利用することができる。
電源ON/OFFできるよ!!
電源ON/OFFできるよ!!
電源ON/OFFできるよ!!
さらに、親オブジェクトに対して子オブジェクトでも必ず必要となる「動作」という処理の元(概念?)だけ定義しておき・・・
子オブジェクトでそれぞれ動作を実装する。
洗濯する。
音楽を流す。
ゴミを吸う。
さらに「ゴミパックを取り付ける」「水を入れる」「カセットを挿入する」など必要になるが、いずれの何かを受け取ったとしても、共通の動作するという行為自体は問題なく処理できる。
これを多様化(ポリモーフィズム)という。
処理を多様化させられることで、柔軟な実装が可能となる。
※ちょっと雑すぎる説明かも
水で洗濯する。
カセットの
音楽を流す。
ゴミを吸ってゴミパックにためる。
これを多様化(ポリモーフィズム)という。
処理を多様化させられることで、柔軟な実装が可能となる。
※ちょっと雑すぎる説明かも
水で洗濯する。
カセットの
音楽を流す。
ゴミを吸ってゴミパックにためる。
オブジェクトと動作を切り分けて
プログラミングするのが
「オブジェクト指向プログラミング」
作るモノ
良くオブジェクト指向プログラミングで題材にあがる「車」を作成する。
車は「オブジェクト(ハコ、タイヤ、エンジン)」「特徴(多様化)」の宝庫。
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>
html
class / @extend
親クラス(abstract class)を用意する。
親クラスには、車として具象化するために必要な屋根やタイヤなどのパーツが定義されている。
.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車を具象化する。
.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に定義することができる。
// 車の色を変更する
@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
最大スピードを指定できる(多様化)エンジンも実装すれば走り出す!
// 車の色を変更する
@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できたように思う。
しかし
・abstract classの利用シーンが思い浮かばない。
・再利用性ができなければ・・・。
・再利用できたとしてもカオス化するのでは・・・。
・例えば
・今回作ったオレオレオブジェクト指向CSSに比べると
OOCSSって結構よくできているのでは?
<form class="form-class { @extend abstract-class }">
ご清聴ありがとうございました。
By omiend