エレガントなコードの書き方

WEBサイト制作

はじめに

こちらの内容は、下記の書籍を参考に、個人的に整理したものです。
あくまでも個人的な見解も含みますので、その点、ご容赦ください。

参考図書

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice) 出版:オライリー

参考

プログラマの三大美徳

目的

  • 読みやすくする。
  • メンテナンスしやすくする。
  • バグやエラーを出現しにくくする。

ちょっと蘊蓄を

コーディングはシステム開発における単なる下流工程ではありません。
上流工程で決定された各種の仕様やデザインを具現化するクリエィテイブな工程です。

「システムアーキテクト」「ソフトウェアアーキテクト」という言葉がありますが、コーディングを建築で例えるならば、設計図に基づいて家を建てる大工さんです。

そこでは、実際にその家に住む人のことを考えて建てることが求められます。
たとえば、ドアとドア枠の間にすき間がなければそのドアを開閉することはできないでしょう。強引にやれば開閉できるかもしれませんが、それは立てつけの悪い家です。

では、そのドアとドアのすき間は何ミリメートルにすれば良いのでしょうか?おそらく設計図には書かれていないかもしれませんし、たとえ書かれていたとしても、その場所の環境、気象条件、ドアの材質などを考慮しながら実際に建てる過程で微調整しないといけないでしょう。

このように、コーディングでは、仕様に書いていないことを読み取り、様々なケースで正しく快適に動作するシステムを構築することが求められます。

エレガントなコードの実装

ロジック

MVCモデル
Model、View、Controllerに分けて記述します。
厳密に分ける必要はないが、それぞれのプログラムの役割が明確になります。
ロジックの変更なのか、見た目の変更なのかが、わかりやすいです。

ただし、WEBページなどフロントエンドのコードでは、厳密にやりすぎると逆にややこしくなることもありますので、適度に行うが良いでしょう。

【参考】日本OSS推進フォーラム:I-13-10. MVCアーキテクチャの基本と特徴

変数

変数の宣言

Javaでは変数を宣言しないで利用するとエラーになります。宣言する時には、スコープ(pubilc, private)、型(int, float, string)を厳密に定義する必要があります。

Pythonでは宣言していない変数を参照するとエラーになりますが、宣言していなくても代入は行うことができます。

PHPでは宣言していない変数も参照してもエラーになりません。

言語によって動作は異なりますが、基本的には最初に変数名を宣言したうえで利用するのが望ましいです。

スコープ

変数には有効な範囲が存在します。
どの言語でも基本的には、同じ関数やクラス内のみで有効であり、他の関数やクラスでは同じ名前でも別の実体となります。

Javaでは、public/private/protectedなど明確にスコープを宣言しますが、Python,PHPでは宣言を必要としませんので、バグの原因になることもあります。

どの範囲で有効な変数名なのかを常に意識する必要があります。

<?php
$val = 1; # 外側のval
foreach ($array as $val) {
    print($val);  # 内側のval
}
print($val);
?>

配列の引数

値渡しなのか参照渡しなのか、言語によって異なるので要注意です。
標準では、Java,PHPでは値渡し、Pythonでは参照渡し。

PHP

<?php
function sample($var) {
    $var = "こんにちは♪{$var}さん";
}
$var = '太郎';
sample($var);
echo $var;
?>

太郎

Python

def sample(var):
    var = "こんにちは♪{0}さん".format(var)
var = '太郎';
sample($var);
print($var); こんにちは♪太郎さん

グローバル変数

どの場所からも参照できる変数です。便利なのですが、影響が大きいためあまり推奨されていません。
広範囲で参照させたい場合は、クラス内でpublicな変数を定義するのが良いでしょう。

Javaの場合
public class SampleClass {
    public int variable;
}

定数

プログラム中で一度も変更されない値は定数を利用します。

ループ

for, foreach, whileなどのループ文は、どれを利用しても実装可能なことが多いですが、以下のように使い分けると良いでしょう。

  • for,foreach ループする回数が決まっている場合(ex.要素数100の配列から要素を取り出す。)
  • while ループする回数が決まっていない場合(ex.停止ボタンが押されるまで実行し続ける。)

while文では真偽の条件を間違うと永遠にループするおそれがありますので注意が必要です。

関数

同じ処理をする部分を関数にすることで、余計なコードを書くことを防ぎます。
関数化することで、機能がより明確になります。
必要なデータは、引数を利用して渡します。

とはいっても、短いコードなのに最初からすべて関数にしていると、手間暇が増えるため、
ある程度増えてきたら、リファクタリングで関数化するという手もあります。

リファクタリングとは何か?

共通機能(日付の変換、DBアクセス)などは、クラス化してメソッドを呼ぶという方法もあります。

変数名、関数名、クラス名、メソッド名等の命名規則

わかりやすい名前

変数名、関数名などはできるだけわかりやすい名前をつけましょう。

例:
upv → unique_pave_view, uniquePageViewなど
c1, c2 → count_h1tag, count_h2tagなど

変数名が短いほうがソースコードのサイズが短くなるという利点はありますが、しかし、現代のストレージはGBやTBがのオーダですので、よほど効率の悪いプログラムを書かない限り、ソースコードサイズがネックになることはほぼないでしょう。
むしろ、暗号的な変数名を利用することで、読む人が何度も定義部分に戻って変数の意味を確認したり、他の何かと間違えて受け取ってしまうことを防ぐことができます。
また、すでに定義済みの変数と重複する変数名をつけてしまうことを防止できます。

言語毎の変数名の長さの傾向
Java > PHP > Python

近接する部分で一時的にしか利用しない変数であれば、短い変数名でも構いません。

大文字、小文字、アンダースコア

多くの言語で、小文字、大文字は区別されます。
先頭以外は数字、アンダースコア記号(_)も利用できることが多いです。

まずは、その言語の一般的なルールに従うのが良いでしょう。
また、プロジェクト内ではルールを決めて行います。

例            
Java - uniquePageView        
PHP - unique_page_view
Python - unique_page_view

記法

  • PascalCase記法(ex. FileCopy)
    • 先頭を大文字
    • それ以外は小文字
    • 言葉の区切りは大文字
  • camelCase記法(ex. fileCopy)
    • 先頭を小文字
    • 以降も小文字
    • 言葉の区切りは大文字
  • snake case記法(ex. file_copy)
    • 先頭を小文字
    • 以降も小文字
    • 言葉の区切りはアンダースコア記号で小文字

Javaの命名規則
PHPの命名規則
Pythonの命名規則

インデント、スペースなど

インデント、スペースがそろっていないコードは非常に見にくく、ケアレスミスの原因になります。
言語によってインデント、変数名の前後のスペースなどの規則が決まっていますので、基本的にはそれに従いましょう。
また、プロジェクト内ではルールを決めて行います。

コメント

わかりやすいコメントを書くことも、プロのコーダーとして必須です。

プログラミング言語の文法や標準的な関数を知っていることは前提で大丈夫です。
その一文あるいはブロックが何のために何の処理をしているのか、5W1Hの視点で書くと良いでしょう。

言語によっては、コメントにも規則があり、それに従って書くと、自動ドキュメントが作成できます。

【参考】JavaDoc

各言語

HTML

インデントは?

br、imgタグなどの閉じについて、
HTMLでは必要なし

<br>

XHTMLでは必要

<br />

divブロックの中身が長くなるときは、閉じタグにどのID,クラスに対するものかコメントを書くとわかりやすいです。

</div><!-- class:contents -->

JavaScript

インデントはタブ1文字

CSS

インデントは半角スペース2文字か、またはタブ1文字

PHP

インデントはタブ1文字

WordPress

WordPressコーディング規約に準拠する。

$postから取得したURL、タイトル等は表示時には必ずサニタイズすること。

<?php esc_url( $url ); ?>
<?php esc_html( $text ) ?>
タイトルとURLをコピーしました