職場で3月から単身アプリ制作を開始し、紆余曲折を経て機能がほぼ完成しました。そのため今週から、内部ソースコードのリファクタリングを本格的に行うことになりました。
・・・が、案の定どこをどのように変えていけば良いかが分からず苦戦を強いられました。ひとつめがこちら↓
<リファクタリング前>
〜〜〜〜〜 HTML 〜〜〜〜〜
<div class="compatibility_icon">
<div class="compatibility_icon1"></div>
<div class="compatibility_icon2"></div>
<div class="compatibility_icon3"></div>
<div class="compatibility_icon4"></div>
<div class="compatibility_icon5"></div>
<div class="compatibility_icon6"></div>
<div class="compatibility_icon7"></div>
</div>
〜〜〜〜〜 CSS 〜〜〜〜〜
.compatibility_icon {
content: "";
margin-top: 0.6rem;
display: block;
clear: both;
overflow: hidden;
.compatibility_icon1 {
margin-left: 1%;
margin-right: 0%;
margin-top: 4%;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-right: 0.5rem solid #000000;
float: left;
height: 0.5rem;
width: 1.5%;
}
.compatibility_icon2 {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_1_on.png");
background-repeat: no-repeat;
background-size: 6rem 4.5rem;
float: left;
overflow: hidden;
height: 4rem;
width: 19%;
}
.compatibility_icon3 {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_2_on.png");
background-repeat: no-repeat;
background-size: 6rem 4.5rem;
float: left;
overflow: hidden;
height: 4rem;
width: 19%;
}
.compatibility_icon4 {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_3_on.png");
background-repeat: no-repeat;
background-size: 6rem 4.5rem;
float: left;
overflow: hidden;
height: 4rem;
width: 19%;
}
.compatibility_icon5 {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_4_on.png");
background-repeat: no-repeat;
background-size: 6rem 4.5rem;
float: left;
overflow: hidden;
height: 4rem;
width: 19%;
}
.compatibility_icon6 {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_5_on.png");
background-repeat: no-repeat;
background-size: 6rem 4.5rem;
float: left;
overflow: hidden;
height: 4rem;
width: 19%;
}
.compatibility_icon7 {
margin-left: 0%;
margin-top: -6%;
margin-right: 0%;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-left: 0.5rem solid #000000;
float: right;
height: 0.5rem;
width: 0.5%;
}
}
<リファクタリング後>
〜〜〜〜〜 HTML 〜〜〜〜〜
<div class="compatibility_icon">
<div class="compatibility_icon arrow1"></div>
<div class="compatibility_icon_type openness"></div>
<div class="compatibility_icon_type integrity"></div>
<div class="compatibility_icon_type extroversion"></div>
<div class="compatibility_icon_type cooperativeness"></div>
<div class="compatibility_icon_type emotional"></div>
<div class="compatibility_icon arrow2"></div>
</div>
〜〜〜〜〜 CSS 〜〜〜〜〜
.compatibility_icon {
content: "";
margin-top: 0.6rem;
display: block;
clear: both;
overflow: hidden;
.compatibility_icon.arrow1 {
margin-left: 1%;
margin-right: 0%;
margin-top: 4%;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-right: 0.5rem solid #000000;
float: left;
height: 0.5rem;
width: 1.5%;
}
.compatibility_icon_type {
background-repeat: no-repeat;
background-size: 6rem 4.5rem;
float: left;
overflow: hidden;
height: 4rem;
width: 19%;
}
.openness {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_1_on.png");
}
.integrity {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_2_on.png");
}
.extroversion {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_3_on.png");
}
.cooperativeness {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_4_on.png");
}
.emotional {
background-image:
url("../assets/imgs/diagnosis_result_parts/pm_status_icon_5_on.png");
}
.compatibility_icon.arrow2 {
margin-left: 0%;
margin-top: -6%;
margin-right: 0%;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-left: 0.5rem solid #000000;
float: right;
height: 0.5rem;
width: 0.5%;
}
}
今回は、HTMLとCSSのみで、割と手軽にできる箇所でリファクタリングを行いました。
上記のコードで気をつけた箇所が朱色のところです。
① <div>
タグのクラスがある箇所では基本的にタグひとつにつき、クラスはひとつしか書かないものだと思っていましたが、ふたつ以上書くことができるという発見がありました。
② ひとつのクラス内に複数クラスを書く際はCSS上では上記のように並列で書くようにするそうです。
③ HTMLとCSSのタブ(へこみ具合)は互いに対応したものにするそうです。
*アイコンの部分が該当箇所になります。
ふたつめの本日のメインとなった箇所がこちら↓
〜〜〜 リファクタリング前のHTML〜〜〜
<div class="trend_all">
<div class="trend_detail trend_detail-1-color">
<div class="characteristic {{OpennessRank == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{OpennessRank == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{OpennessRank == 2 ? 'on' : 'off'}}">開放性</div>
<div class="characteristic {{OpennessRank == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{OpennessRank == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content_openness">
<div class="trend_content_openness_detail1"></div>
<div class="trend_content_openness_detail2">げんじつてき</div>
<div class="trend_content_openness_detail3">ロマンチスト</div>
<div class="trend_content_openness_detail4"></div>
</div>
<div class="trend_detail trend_detail-2-color">
<div class="characteristic {{ConscientiousnessRank == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{ConscientiousnessRank == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{ConscientiousnessRank == 2 ? 'on' : 'off'}}">誠実性</div>
<div class="characteristic {{ConscientiousnessRank == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{ConscientiousnessRank == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content_integrity">
<div class="trend_content_integrity_detail1"></div>
<div class="trend_content_integrity_detail2">だいたん</div>
<div class="trend_content_integrity_detail3">コツコツ</div>
<div class="trend_content_integrity_detail4"></div>
</div>
<div class="trend_detail trend_detail-3-color">
<div class="characteristic {{ExtroversionRank == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{ExtroversionRank == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{ExtroversionRank == 2 ? 'on' : 'off'}}">外向性</div>
<div class="characteristic {{ExtroversionRank == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{ExtroversionRank == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content_extroversion">
<div class="trend_content_extroversion_detail1"></div>
<div class="trend_content_extroversion_detail2">インドア</div>
<div class="trend_content_extroversion_detail3">アウトドア</div>
<div class="trend_content_extroversion_detail4"></div>
</div>
<div class="trend_detail trend_detail-4-color">
<div class="characteristic {{AgreeablenessRank == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{AgreeablenessRank == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{AgreeablenessRank == 2 ? 'on' : 'off'}}">協調性</div>
<div class="characteristic {{AgreeablenessRank == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{AgreeablenessRank == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content_cooperativeness">
<div class="trend_content_cooperativeness_detail1"></div>
<div class="trend_content_cooperativeness_detail2">じぶんだいじに</div>
<div class="trend_content_cooperativeness_detail3">きくばりじょうず</div>
<div class="trend_content_cooperativeness_detail4"></div>
</div>
<div class="trend_detail trend_detail-5-color">
<div class="characteristic {{NeuroticismRank == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{NeuroticismRank == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{NeuroticismRank == 2 ? 'on' : 'off'}}">情緒性</div>
<div class="characteristic {{NeuroticismRank == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{NeuroticismRank == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content_emotional">
<div class="trend_content_emotional_detail1"></div>
<div class="trend_content_emotional_detail2">おだやか</div>
<div class="trend_content_emotional_detail3">こまやか</div>
<div class="trend_content_emotional_detail4"></div>
</div>
</div>
〜〜〜〜〜〜 リファクタリング後のHTML〜〜〜〜〜〜〜〜
<div class="trend_all">
<ng-container *ngFor="let trend of trends; let i = index">
<div class="characteristic_all">
<div class="trend_detail trend_detail-{{i+1}}-color">
<div class="characteristic {{TrendRank(trend.type)}} == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{TrendRank(trend.type)}}== 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{TrendRank(trend.type)}} == 2 ? 'on' : 'off'}}">
{{trend.name}}</div>
<div class="characteristic {{TrendRank(trend.type)}} == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{TrendRank(trend.type)}} == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content">
<div class="trend_content_detail_lower">{{trend.lower}}</div>
<div class="trend_content_detail_upper">{{trend.upper}}</div>
</div>
</div>
</ng-container>
</div>
〜〜〜 Typescriptの追記箇所〜〜〜
① trends: any; の追記 →変数 trendsの定義
② this.trends = this.styleDiagnosis.Ocean; の追記 → jsonfileの呼び出し
③ TrendRank(type) {
return this.result ? this.result.big5Score[type].rank : 0;
}
の追記
今回は、HTML、CSS、TypeScriptの三つの項目でリファクタリングを進める必要があり、特に工夫を要したHTMLとTypeScriptのふたつでのリファクタリングの様子をみていこうと思います。
今回のポイントはHTMLの機能を必要最小限の単位で小刻みに切り分けていくことです。
*具体的な進め方
①
<div class="characteristic_all">
<div class="trend_detail trend_detail-{{i+1}}-color">
<div class="characteristic {{TrendRank(trend.type) == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{TrendRank(trend.type) == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{TrendRank(trend.type) == 2 ? 'on' : 'off'}}">
{{trend.name}}</div>
<div class="characteristic {{TrendRank(trend.type) == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{TrendRank(trend.type) == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content">
<div class="trend_content_detail_lower">{{trend.lower}}</div>
<div class="trend_content_detail_upper">{{trend.upper}}</div>
</div>
</div>
をコメントアウト
② trends(変数) の定義・・・TypeScript上でngForを使用するための変数を定義します。
③```
④ {{trend.lower}} {{trend.upper}} の定義・・・TypeScript上に処理を記述します。
⑤```
⑥```
⑦ {{trend.name}} の部分を定義・・・中心のバーにBig5の文字が入るようにします。
⑧{{TrendRank(trend.type) の部分を定義・・・これを記述することで0〜4の箇所(5つのバー)全てでon・off表示がされるようになります。
*この記述をしないと5箇所あるうちのいずれかの縦一直線でしかonになりません。
以上でリファクタリング終了です。TypeScriptによる変数の定義とそれに伴う出力があるためかなり複雑になりますが、console.log(変数)によるログの出力や細分化して機能を試すことなどを繰り返し行うことで全部で80行近くあったコードを20行以下まで短縮・整理することができます。
*慣れてきたら・・・
それぞれ1ブロック分のコードを書く
(例)
<div class="trend_detail trend_detail-1-color">
<div class="characteristic {{OpennessRank == 0 ? 'on' : 'off'}}"></div>
<div class="characteristic {{OpennessRank == 1 ? 'on' : 'off'}}"></div>
<div class="characteristic {{OpennessRank == 2 ? 'on' : 'off'}}">開放性</div>
<div class="characteristic {{OpennessRank == 3 ? 'on' : 'off'}}"></div>
<div class="characteristic {{OpennessRank == 4 ? 'on' : 'off'}}"></div>
</div>
<div class="trend_content_openness">
<div class="trend_content_openness_detail1"></div>
<div class="trend_content_openness_detail2">げんじつてき</div>
<div class="trend_content_openness_detail3">ロマンチスト</div>
<div class="trend_content_openness_detail4"></div>
</div>
だけ、書き出す。
共通化できる箇所を探し、変数の定義を行いながらコードを書きます。
*ステータスバーのところが該当箇所になります。
リファクタリングはコード全般で保守性・可読性向上のために必ず行われるため、初めは上手くできなくとも徐々にできるようにしていきたいです。