Core Tech Blog

株式会社Coreのエンジニアチームが日々習得した技術やTipsを公開するブログです

プログラミング未経験だった私が、エンジニアとして働いた1年間を振り返る

開発部の瀧です。 私事ではありますが、弊社株式会社Coreに入社してから1年が経ちました。 私は、前職では広告の制作会社で主にTV-CMの企画・制作業務をしており、Coreにはエンジニア実務未経験での入社になります。つまり職業エンジニアとしても、1年の年月を数える訳であります。

そこで今回のテックブログでは、少し趣向を変えて、この1年の業務を通じて得た私の「気づき」をシェアさせていただければと思います。

簡単な自己紹介

渋谷の某「結果にコミットする」プログラミングススクールを経て、株式会社Coreの1人目のエンジニアとして入社しました。 以降、マーケティングツールの新規開発を任され、プログラミングのみならず上流の設計やインフラの構築を担当、現在に至ります。

「動くものを作る」がゴールではない

Coreに入社し、晴れて職業エンジニアとしてキャリアをスタートさせました。当然今まで開発してきた個人的用途のアプリケーションではなく、商用のアプリケーションを作成することになります。 動けばいいとどこかの個人ブログや、StackOverFlowからコピペしてきたようなコードをそのまま使うようなことはできません。現在開発に当たるのは私一人ですが、これからはメンバーも増え、運用・保守していくのは、他の誰かかもしれません。そうした場合も考慮して、メンテナンス性の容易性と可読性の高さを常に意識してコーディングするマインドセットが必要です。

コーディングの原理原則に従う

チームでの開発が基本のソフトウェア開発には作法とも言える原理原則があります。

DRY原則

Don't Repeat Yourself(繰り返すな)は、ソフトウェア開発に携わる人にはあまりにも有名なフレーズかと思います。アプリケーションの中のコードの重複を排除しなければならないという基本的な考え方です。 重複は、不必要にファイルを肥大化し、ロジックの理解を難しくさせ、引いてはバグが生じる危険性を高めます。 例えば下記のようなコードの場合、

<?php

class Validation
{
    public function validateUser(array $user)
    {
        if (!isset($user['name'])) {
            throw new \Exception('名前は必須入力です');
        }

        if (!isset($user['email'])) {
            throw new \Exception('emailは必須入力です');
        }

        if (!isset($user['password'])) {
            throw new \Exception('パスワードは必須入力です');
        }
    }
}

配列$userに各keyが存在するかが異なるだけで、処理は共通しています。 DRY原則に則り書き直すと、下記のようなコードになります。

<?php

class Validation
{
    private $userKeys = [
        'name',
        'email',
        'password'
    ];

    public function validateUser(array $user)
    {
        foreach ($this->userKeys as $key) {
            if (!isset($product[$key])) {
                throw new \Exception(sprintf('%sは必須入力です', $key));
            }
        }
    }
}

どうでしょう。if文の羅列が無くなり見た目もスッキリした印象ではないでしょうか。また、急な仕様の変更で$useraddressも追加したいといった時にも、

private $userKeys = [
    'name',
    'email',
    'password',
    'address'
];

上記のように、コードに大きな変更もなく対応できます。

明瞭な命名

コードを書いていると必ず直面する問題に、関数や変数の名前の付け方があります。

ケース

命名規則には、まずどういう記法で表現するかを表すケースから策定しなければなりません。 ただこのケースに関しては、ネット上では度々論争が繰り広げられるトピックでもあるので、言語ごとのスタイルガイドに合わせて表記するのが一番だとは思います。

名称 表記例 備考
ローワーキャメルケース、キャメルケース camelCase 複合語の先頭を小文字にする
アッパーキャメルケース、パスカルケース PascalCase 複合語の先頭を大文字にする
スネークケース snake_case 複合語の語頭をアンダースコアで区切る

命名

何を格納する変数なのか、何の処理をする関数なのか、一目で理解のできる名付けをする必要があります。 先ほどのコードですが、下記のように表記されていた場合どうでしょうか。

<?php

class Dosomething
{
  private $array = [
      'variable1',
      'variable2',
      'variable3',
      'variable4'
  ];

    public function doSomethingToUser(array $variable)
    {
        foreach ($this->array as $key) {
            if (!isset($variable[$key])) {
                throw new \Exception(sprintf('%sは必須入力です', $key));
            }
        }
    }
}

何をしている処理かさっぱりわかりません。極端な例で、幸い私自身目にしたことはないですが、こうした命名でも「動くコード」という視点から見れば先ほどのコードと何ら変わりはありません。 ただ、メンテナンスが容易かと聞かれればそうではないはずです。何をしている処理か、何のためのコードかを、チームのために、将来の自分のためにリーダブルな命名規則を心がける必要があります。

セキュリティ対策

Webアプリケーションを扱うエンジニアとして、お客様の大切なデータを扱う以上、セキュリティに関しての知見も最低限の知識として必要です。

SQLインジェクション

代表的な攻撃手段として、SQLインジェクションを取り上げます。SQLインジェクションとは、開発者が意図していない処理をSQLとして実行させてしまう攻撃のことです。 例えばEmailとPasswordで認証するloginページにおいて、下記のようにユーザーが入力した文字列からSQL文を発行しているアプリケーションの場合、

SELECT * FROM login email = '$_POST['email']' AND password = '$_POST['password']'

悪意あるユーザーがpassword=' OR A=Aと入力すると、下記のようなSQL文が発行され、

SELECT * FROM login email = 'hogehoge@hoge.com' AND password = '' OR A=A'

結果は常にtrueとなり、悪意あるユーザーはログインに成功してしまいます。

対策

SQLインジェクションの根本的な対策は明快で、SQL生成の際にプレースホルダを利用するようにすることです。 プレースホルダとは、SQL文の中で可変な項目を後から変更可能なパラメーターとして置き換え、処理する方法です。

SELECT * FROM login email = ? AND password = ?

プレースホルダでは、この?の部分を単純な文字列として扱うので、先ほどのような不正なパラメーターの入力があっても問題なく処理することができます。 プレースホルダには、アプリケーション側のライブラリで実行する「動的プレースホルダ」と、データベース側でプレースホルダを実現する「静的プレースホルダ」があります。 静的プレースホルダは、SQLを準備する段階で SQL文の構文が確定し、後からSQL構文が変化することがないため、セキュリティの観点から言えばより安全です。

まとめ

節目の1年が終わりました。まだまだ技術的に未熟で、先輩エンジニアに泣きつくこともありますが、成長という意味では確実な手応えがあります。 それは上記に記したような、エンジニアとしての基本的な知識の習得を経て感じるものであり、今1年前の私のコードを見て感じることでもあります。 また1年後、今の私のコードを見て、同じように感じられるよう日々精進して、技術を磨いていきます。