月別アーカイブ: 2022年2月

時計

長時間作業を続けることができるたった1つの方法

現在、個人開発(プログラミング)とブログの作業を、平日は仕事が終わった後に4〜5時間、休日は10時間以上は平均して作業を行っています。

どうすればこのように長時間作業に没頭できるようになるのか、その方法について説明したいと思います。

僕と同じようにプログラミングの勉強や個人開発、ブログをしている人以外でも、英語の勉強や受験の勉強などにも使える方法だと思いますので、ぜひ最後まで読んで頂けると嬉しいです。


なぜ長時間作業ができないのか

長時間作業ができない理由を明確にすることがとても重要なので、まずはその理由から紐解いていきます。

結論から言うとそれをすることで得られるメリットが小さいからだと考えています。

例えば英語を勉強したい人は世の中にたくさん居ますよね。

僕もエンジニアの端くれ、英語のドキュメントくらいは読めるようになりたいという思いで英語を勉強をしたことがあります。

その時に勉強した時間は平日せいぜい30分〜1時間、日によっては勉強しないという毎日を繰り返した結果、挫折して終わりました。

「英語のドキュメントを読めるようになりたい」という動機から勉強をはじめて、仮に英語が読めるようになったとします。

得られるメリットは「英語のドキュメントが読めるようになる」というメリットになります。

ですがよく考えると、多くの人にとってはメリットが小さく魅力的でもなんでもないですよね。

「英語を使えるようになれば収入も増えるのでは?」という考え方がありますが、これは増えるかもといった不確実性があまりに高いです。

収入が増えるかも、外国人の友達や恋人ができるかも、海外で仕事ができるようになるかも。

このように、心のどこかで疑っている自分が居ると、必ずどこかで挫折します。

「頑張ったけど結局挫折しました」「今までの苦労はなんだったんだ」

こういうことにならないための危機察知能力のようなものが働いているために、作業に没頭できないのだと思います。


長時間作業を続けられるようにするには

上記でお話した通り、メリットが小さいからこそ作業に没頭できないのであればメリットを大きくすれば良さそうです。

言い換えるとゴールを変えることでそれが可能になります。

「ゴール(動機)を変えることなんてできないのでは?」と思われるかもしれませんが、実際に僕はこの方法で長時間作業に没頭できるようになりました。

実例の方が分かりやすいと思うので、僕がどうやってゴールを変えたのかを説明します。

新卒から今の今までずっとエンジニアとして仕事をしてきましたが、プログラミングの勉強は大嫌いで続いた試しはありませんでした。

勉強が続かないからスキルアップのために家で個人開発をしようとしたこともありますが、これもすぐに挫折しました。

趣味でブログもはじめてみましたが、これも挫折しました。

月日が経ち、生産性の欠片もない毎日を過ごしていたある時、貯金が底をつきそうになりました。

「このままではマズイ」と思い、どうにかお金を稼ぐ手段はないものかと考えた時に、自分のエンジニアスキルでどうにかできないか?と模索し始めました。

その時に、以前は挫折した個人開発とブログが頭をよぎりました。

  • 個人開発(そのためのプログラミングの勉強)のゴールがスキルアップから副収入を得るため
  • ブログのゴールが趣味(承認欲求)から個人開発で開発したサービスの告知や界隈の方とのコミュニケーションの入り口

このようにゴールが変更されました。

これだけだとゴールが弱いので、もう少し強くする必要があります。

また僕の例で恐縮ですが、下記のようにゴールを強く(魅力的に)しました。

  • 個人開発で会社の収入を上回れば会社を辞めることができる
  • プログラミングを勉強することでブログで発信し、これも副収入を得ることができる
  • 自分の好きなゲームを扱った事業を展開すれば、購入するゲームを経費にできる
  • 法人化して家族を社員にすれば経費で最新のスマホとかを買ってあげられる

欲の塊ですね(笑)

ここまで魅力的なゴールを考えることができるとやらない手はないなとなり、平日は4〜5時間、休日は10時間以上作業に没頭できるようになった今に至ります。

以前の記事でも紹介しましたが、ここまで魅力的なゴールを思いつくとこれらをいち早く実現するために自ら他の作業はしなくなります。

大切なのはプロセスを考えるのではなく、他のものがどうでもよくなるほどの魅力的なゴールを鮮明にイメージして設定してあげることです。

これができれば、プロセスもそれに応じての行動になっていくはずです。

英語の勉強や受験の勉強も同じようにゴールを魅力的なものに変えてあげることで、自ずと作業に没頭できるようになるはずです。

  • 英語の勉強→ニューヨークのオシャレなカフェでアメリカ人の彼女とランチをする
  • 受験の勉強→良い大学に入って大企業に入り、女の子を侍らして高級車を乗り回して人生イージーを満喫する
  • プログラミングの勉強→エンジニアスキルを磨いて独立し、大金持ちになって海外を飛び回る

こんな感じです。

コツはゴール設定が私利私欲であることが大事だと思います。

「世界中で通じるエンジニアになりたい」とか「大企業で人の役に立つ製品を作りたい」とかだと直接的な自分へのご褒美が無いため、失敗する気がします。


まとめ

「ゴールを設定しても叶うとは限らない、それこそ不確実性が高いのでは?」と言われそうなので、こちらについて補足します。

これに関しての答えはYESです。

当たり前ですが叶うかどうかは自分の努力次第なので、確実とは言い難いです。

しかし、ここまでこの記事を読んで頂いたということは、何かしらを続けることを望まれている方だと思います。

成し遂げたい何かがあるはずです。

それならば、今から頑張らないことにはこの先もずっとできないまま終わってしまいます。

そうならないためにも、鮮明にイメージできる魅力的なゴールを設定してあげることを強くおすすめします。

3日坊主の僕でもできたのですから、きっとできるはずです。

一緒にがんばりましょう。

暑苦しい記事を最後まで読んで頂いてありがとうございました😊

手のひらから水がこぼれ落ちる

個人開発するために捨てたものと得られたもの

会社で働くのが嫌になり、組織に依存せずに生きていきたいと願うようになったのをきっかけに、今年の初旬から個人開発に挑戦しています。

今回は個人開発をする上で、捨てたものや犠牲にしたものなんかをお話したいと思います。

同じように個人開発されている方やこれから挑戦したい方などの参考になれば幸いです。


個人開発をするために捨てたもの

大きく分けて2つあります。

作業時間を捻出するために捨てた習慣と、会社を辞めて個人で稼いで生活費を安定させるために捨てたものです。

簡潔に言うと時間とお金を極限まで節約するために、下記のものを捨てました。


人付き合い

これは言わずもがなという感じですが、人付き合いが多いとその分作業時間が減ります。

幸い今は基本テレワークで会社での人付き合いは無いため、平日は仕事が終わったらすぐに個人開発の作業を進めています。

休日も時間が惜しいため、人との付き合いは全くありません。

今は彼女も居ませんし友達もほぼ居ないので、ある意味恵まれている環境ではあります。

結構な寂しがり屋なので人付き合いを無くすことができるか不安でしたが、個人で稼ぐという覚悟を決めてからというもの、すんなりと人付き合いを無くすことができました。


ゲーム機

ハマると12時間以上も続けてしまうほどのゲーム好きですが、時間が惜しいのでゲーム機をほとんど売りました。

成し遂げたい何かに集中するには、見える範囲の娯楽は全て無くすことが好ましいと考えているため、ゲーム以外の娯楽である動画のサブスクも解約しました。

たまに「ちょっとぐらいゲームしても良いかな」という気持ちが出てくるんですが、なんとか堪えてます。

あとはSNSやyoutubeなんかも覗くのは最低限にしてます。


お酒

お酒大好きで毎週末は朝まで飲み歩いてましたが、今はきっぱりとやめました。

やめてから2ヶ月ほど経ちますが、飲みたいと思うことは滅多にありません。

過去にお酒やめたいのにやめられないという悩みをずっと抱えていましたが、自分でもビックリするほどすんなりとやめられました。

人によるかもしれませんが、お酒を飲んだ翌日は頭がぼーっとしたり常に眠気があったりしたため、個人開発に確実に影響が出ると考えてお酒をやめることを決意しました。

このお酒をやめられたことをきっかけに、他の様々なものが捨てられたと感じています。

おそらく一番の悪習慣を断ったことで、作業時間が生まれてそっちに習慣がシフトしたおかげだと思います。


見栄

これは個人開発をする上で捨てたものというより、個人で稼ぐと決めた上で捨てたものになります。

今住んでいるマンションは小綺麗でオートロックで場所も渋谷なので家賃も高いです。

個人で稼ぐことを考えるとこの出費は大きすぎるので、実家に戻ることにしました。

「アラフォーで実家住まい」という世間体からしたらあまり良い印象ではありませんが、お金のことを考えると実家住まいはコスパ最強なので、変な見栄は捨てることにしました。

他にも、オシャレなお店でランチやディナーを楽しんだり、カフェ等のお金の掛かるところへは行かないようにしています。


メリハリのある生活

平日は仕事終わりに夕飯がてらお酒を飲みに行ったり、週末はどこかへ遊びに出かけたり、そういった生活は一切しなくなりました。

平日は仕事終わったらすぐに作業を開始してシャワー浴びて寝るまで続けています。

休日もほとんど外へは出ずに引きこもってずっと作業をしています。

毎日これの繰り返しです。

以前の僕だったら刺激が少なすぎて気が狂いそうな生活ですが、今は慣れたというより馴染んだ感じです。

今は逆にこの生活リズムが崩れてしまうことに恐れを感じています。


捨てたことで得られたもの

これらを捨てたことで、作業時間はもちろんですが他にも得られたものはたくさんあります。

しかも得られたものの価値は個人的には相当高いので、それらについてまとめてみました。


自信

仕事終わるとぼーっとyoutube見たり外へ出かけたりする平日と、朝までお酒を飲んでは翌日二日酔いで一日中布団の中で過ごす休日を過ごしてきましたが、それらをすべて断ち切ることができた自分がとても誇らしく思えるようになりました。

捨てることが出来ていなかった日々は「自分はなんてダメなやつだ」とか「周りは結婚したりしているのに俺ときたら…」と辛いことばかり考えていて、自己肯定感がとても低かったのですが、上記のものを捨てられた自分に対して「やればできるじゃん」という自信が付きました。


健康

お酒をやめたことによる効果と、ゲームをやめたことによる睡眠不足が解消されたためか、毎日規則正しい生活を過ごせています。

ここ1ヶ月以上はほとんど毎日引きこもって作業をしていますが、以前と比べると身体の調子がとても良いです。

身体だけではなく、頭もクリアで冴え渡っているように感じます。

日課の筋トレや自炊で積極的に野菜を摂取しているのもありますが、寝る時間と起きる時間がほとんど毎日同じになっているのが良いのかなと思います。


心の安定

主に人付き合いを捨てたことに起因しますが、余計なことを考えなくて良くなった結果、心がとても穏やかになりました。

心理学者のアドラーは人の悩みの原因はすべて自分以外の人が存在しているからだと提唱していました。

好きになるのも嫌いになるのも怒るのも悲しむのも疲れますからね。

こんなこと言うと「なんて寂しい人間なんだ」と思われそうですが、今は身軽でとても心地よいと感じてます。


まとめ

当然といえば当然ですが、捨てたもの犠牲にしたものは時間やお金が掛かることが共通点ですね。

今は仕事と睡眠とご飯食べている時以外はほぼ作業をしているような毎日を1ヶ月以上続けています。

我ながらゾーンに入っていると感じます。

過去の自分なら、どうすればそれだけの時間を使って作業できるようになるのか疑問に感じたことと思います。

実際に、どうすれば10時間以上作業が続けられるようになるのかをググったりyoutubeで検索したりして、何度も調べていました。

3日坊主でなにかを継続できた試しがありませんでしたが、おそらくこれがきっかけかな?と思うところがあるため、それはまた別で記事にしたいと思います。

最後まで読んで頂きありがとうございました。

これから何かを始めたい方の参考になれば嬉しいです😊

プログラミング画面

悪いソースコードとはどういうソースコードか?

10年以上開発の現場でコードを書いたり読んだりしていると、悪いソースコードに出くわす機会も少なからずあります。

今回はPHPのサンプルコードを例に、悪いソースコードとその対策についてまとめました。

プログラミング初心者の方の参考になれば幸いです。


悪いソースコードとは?

そもそも悪いソースコードとはどういうソースコードなのか?

いくつも原因が考えられますが、下記のもので改善が可能なものを指すことが多いです。

  • 処理に時間が掛かり負荷が高い書き方
  • バグにつながる書き方
  • コピペが多くコンポーネント化(関数化)されていない書き方
  • 純粋に見づらい(分かりづらい)書き方

順番にサンプルソースコードを例に解説します。


処理に時間が掛かり負荷が高い書き方

一番分かりやすい例が、if elseの文です。

性別を判定する処理を例にします。(0: 不明 / 1: 男 / 2: 女 / 9: 適用不明)

<?php
// 悪いソースコードの例
if ($sex === 0) {
    echo "不明";
}
if ($sex === 1) {
    echo "男";
}
if ($sex === 2) {
    echo "女";
}
if ($sex === 9) {
    echo "適用不能";
}

プログラミング初心者の方が陥りやすい書き方です。

このソースコードの問題点は何度もifの判定を繰り返している点です。

$sexが1の場合、内部では下記のように処理されます。

$sexが0か判定 → $sexが1か判定("男"と表示) → $sexが2か判定 → $sexが9か判定

目的である性別の表示が終わっても、以降の判定を行っているため無駄な処理が存在して負荷が高くなっています。

<?php
// 良いソースコードの例
if ($sex === 0) {
    echo "不明";
} else if ($sex === 1) {
    echo "男";
} else if ($sex === 2) {
    echo "女";
} else if ($sex === 9) {
    echo "適用不能";
}

else ifを使ってあげることで、性別の表示以降の判定が行われないため、負荷を減らせます。

$sexが0か判定 → $sexが1か判定("男"と表示)

状態を判定する場合、基本的にはelseifを使うと覚えておけば問題ないと思います。

※どうでも良いですけど、変数名やカラム名にsexって付けるとレビュー時にちょっと恥ずかしいですよね…。


バグにつながる書き方

パターンとしては色々ありますが、最も多いのは型を意識していないためにバグにつながるケースです。

<?php
$str = 'hogehoge';
$find   = 'hoge';

$pos = strpos($str, $find);

if ($pos != false) {
    echo "OK";
} else {
    echo "NG";
}

// 結果
NG

strpos関数は、文字列が含まれていた場合にその位置を返す関数です。

この関数を利用して、$strに’hoge’という文字列が含まれているかどうかを判定し、含まれていたらOKと表示します。

一見良さそうですが、結果はNGとなりました。

今回は一番先頭にその文字列が含まれていたため、先頭を指し示す0がstrpos関数によって返されますがfalseも数値としては0なので、意図した挙動にはならなかったのです。

<?php
if (0 == false) {
    echo "一致";
}
// 結果
一致

数値としては一致しますが、型は当然違います。

<?php
echo gettype(0), "\n";
echo gettype(false);

// 結果
integer
boolean

これを回避するためには、型も判定に含める!==演算子を使う必要があります。

<?php
$str = 'hogehoge';
$find   = 'hoge';

$pos = strpos($str, $find);

if ($pos !== false) {
    echo "OK";
} else {
    echo "NG";
}

// 結果
OK

strposはよく利用されるため知っている方も多いと思いますが、他の関数になると戻り値を意識していないソースコードをよく見かけます。

※戻り値がnullに対してisset関数を使用したり、変数の存在を判定するためにempty関数を使用したり等。

型を意識するだけでも相当数のバグを減らすことができるので、関数の戻り値の型をチェックすることをおすすめします。


コピペが多くコンポーネント化されていない書き方

例えばユーザー情報を取得する下記のようなSELECT文の関数があった場合です。
※Laravelの書き方を例にしています。
※Laravel自体まだ触り始めたばかりなので、間違っていたらご指摘頂けると助かります。

<?php
public function get_users(): User {
    $users = User::get();
    return $users;
}

後から機能が追加され、nameでソートする必要が出てきたとします。

その場合に下記のような関数を別途追加してしまうパターンです。

// $sortには'desc'か'asc'を指定
public function get_users_sort_by_name($sort): User {
    $users = User::orderBy('name', $sort)->get();
    return $users;
}

一見すると良さそうですが、SELECTする際の条件を追加する必要があった場合はどうでしょう?

その場合、get_users関数もget_users_sort_by_name関数も両方修正する必要がでてきます。

関数が2つだけならまだ大丈夫ですが、3つ4つと同じような関数が増えてきた場合、全部に修正が必要になってきます。

これの恐ろしいのが修正が漏れてしまうケースが発生することです。

この修正漏れがバグを引き起こす原因になってしまいます。

そうならないためにも、条件(where文)が同じであれば下記のようにget_users関数に引数を追加してあげることでこの問題を回避できます。

// get_users()で呼び出せばソート無し
// get_users($sort)で呼び出せばソート有り
public function get_users(string $sort = NULL): User {
    if (is_null($sort)) {
        $users = User::get();
    } else {
        $users = User::orderBy('name', $sort)->get();
    }
    return $users;
}

こうすればwhereが複雑になったとしてもget_users関数内だけ修正すればOKなので、手間もバグも減らせます。

この例以外にも「あれ…なんか似てるような処理書いているな」と思ったら大抵の場合コンポーネント化できますので、面倒くさがらず処理をひとまとめにできないか模索してみてください。


純粋に見づらい(分かりづらい)書き方

見づらくなってしまう原因については、下記があげられます。

  • インデントがずれている
  • 1つの関数の処理が長い(行数が多い)
  • 文字数が多く改行がされていない
  • ifのネストが多い

このあたりについては分かりやすいので説明は割愛しますが、プログラミング歴が長い人でも陥りやすい書き方を紹介します。

明示的でない

この変数にはどういうデータが入っているのか?またはこの関数はどういう処理をするのか?というのが明示的でないのも悪い書き方になります。

実際に僕がやっていた悪いソースコードの例になります。

<?php

public function get_data(): array
{
	$data = array();
  $data['meats'] = array('cow', 'pig');
	$data['fruits'] = array('apple', 'cherry');
	$vegetables = 'potato';
	
	/*
	省略
	*/

  return $data;
}

この関数が例えば1000行以上になったと仮定します(1つの関数あたりの行数が長いのも問題ではありますが、ここでは説明のため…)

冒頭で$dataに’meats’と’fruits’というキーでデータを格納していますが、$vegetablesは格納していません。

この関数の処理を第三者の人がreturnまで読んだ際に「あれ、$vegetablesってこの$dataに含まれていたっけ?」となってしまい、処理をまた追いかける羽目になります。

そうならないためにも、returnで返す値を直前で格納するようにした方が読みやすくなります。

<?php

public function get_data(): array
{
  $meats = array('cow', 'pig');
	$fruits = array('apple', 'cherry');
	$vegetables = 'potato';
	
	/*
	省略
	*/
	
	// $vegetablesが入ってないことが明確
  $data = array();
	$data['meats'] = $meats;
	$data['fruits'] = $fruits;

  return $data;
}

関数の戻り値や三項演算子の多用

これは悪いソースコードとは言い難いので迷いましたが「読みづらい」という点では悪いソースコードといえなくもないので、載せておきます。

少し無理やりですが、下記みたいな書き方です。

※ちなみに僕もよくやりがちなので、戒めの意味も込めて載せています。

<?php

return $cnt > 0 ? (get_mode() === 1 ? get_status() : "error") : NULL;

カッコを付けていても分かりづらいですが、三項演算子のネストです。

熟練エンジニアの方や参考書にもこういった書き方で載っていますし、1行でまとまっているので美しいようにも見えます。

ですが分かりやすいかと言われれば間違いなく分かりづらい書き方です。

組織での開発は複数人で行うため、誰が見ても分かりやすい書き方がベターです。

<?php

$mode = get_mode();
$status = $mode === 1 ? get_status() : "error";
return $cnt > 0 ? $status : NULL;

エレガントな書き方より見やすい書き方の方が読みやすいので、バグも生まれにくくなります。


良いソースコードを書くには

書いたコードを1行ずつ理解して読み直すことを強くおすすめします。

  • 関数の戻り値の型に合った判定をしているか?
  • 負荷を掛ける処理になっていないか?
  • 似たような処理をいくつも書いていないか?
  • 変数名や関数名は適切か?
  • 1行ずつ人に説明できるか?

上記のポイントを抑えながら読み直してリファクタリングをするのがおすすめです。

長くなりましたが、最後に良いソースコードを書く上でおすすめの書籍を紹介します。

おすすめの書籍① リーダブルコード

タイトルにもある通り、良いソースコードの書き方について解説している書籍です。

この手の本(というか技術書全般)は内容が難しくなりがちですが、シンプルでとても読みやすい上に、ページ数もそこまで多くないのでさらっと読めると思います。

変数名や関数名の付け方から、ネストを深くしない仕組みやコメントの書き方などが載っているため、綺麗で読みやすい良いソースコードが書けるようになります。

実際に僕も「エレガントなソースコードが良いとは限らない」というのをこの書籍に教えられてから、誰にでも読みやすいコードを書けるようになりました。

おすすめの書籍② 達人プログラマー

こちらは良いコードの書き方というより、エンジニアとして開発する上で基盤となる開発手法が書かれています。

エンジニアはどういう心構えが必要か、開発手法やエンジニア思考について多くを学べる書籍です。

同じ処理を2つ以上書かない設計手法であるDRY原則(Don’t Repeat Yourself)や、アヒルのおもちゃにソースコードを1行ずつ説明することで理解を深めるラバーダック・デバッグ法のやり方といった具体的な手法が載っており、これらを実践することで間違いなく開発スキルがグンと上がります。

周りのエンジニアも絶賛しており、僕にとってもこの書籍はエンジニアとしてのバイブルになっています。
※アヒルのおもちゃも買いました。


最後に

悪いソースコードの例は挙げればキリがありませんが、よく見るパターンをまとめてみました。

まだ思いつく悪いソースコードのパターンはあるので、今度また余裕があった時にまとめてみます。

参考になりましたら幸いです。

最後まで読んで頂きありがとうございます。

ゴミ箱

個人開発でボツにしたアイデア

今年の1月初旬から、Laravelを勉強しながら個人開発(webサービス)に挑戦しております。

開発を始めるにあたりサービスのアイデアをいくつか考えましたが、ボツにしたアイデアとどこがダメだったのか、個人開発で成功するために何を作れば良いかをまとめたので参考にして頂けたら嬉しいです。


ボツにしたアイデア1 婚活向けToDoリスト管理サービス

一番最初に思い付いたアイデアで、婚活を本気で頑張りたい人向けのサービスを考えました。

文字通りToDoを管理するサービスで、初回ログイン時にいくつかの設問に答えることで自動的に婚活向けのタスクが追加されるというものです。

例えば『気になる異性は居ますか?』というのに対し、YESなら『実際に声を掛けてみる』というタスクが追加され、NOなら『街コンへ参加』というタスクが追加されるといった感じで、ある程度の強制力により自身を鼓舞し、婚活を頑張ってもらうサービスです。

画像はfigmaというワイヤーフレーム作成webサービスで作成したプロトタイプの画面レイアウトです。

開発中の婚活ToDoサービスの画面
実際に作成したレイアウト

ToDoリスト機能とは別に、同性同士でのみやり取りができる掲示板機能を設け、婚活を本気で頑張っている人たちのコミュニティを作り上げる構想でした。

競合調査として、5chやガールズちゃんねるといった掲示板を覗いた際に、婚活に関する書き込みはあるものの圧倒的に少なく、レスも茶化したようなものが多かったため本気で婚活する人たちが集まるコミュニティを作ることができれば、このサービスは成長するのではないかと考えました。


マネタイズ

下記の課金要素を検討していました。

・トライアルプラン
最初の30日間は全ての機能が使えるが、広告が表示される。

・フリープラン
ToDo機能は使えるが、掲示板機能が使えず広告が表示される。

・ベーシックプラン
全ての機能が使え、広告も非表示。
月額980円

『お金掛けてるし頑張らないと』という意識を持ってもらうため、金額については敢えて高めに設定しました。

  • 安いサービス = 悪いサービス(期待しない)
  • 高いサービス = 良いサービス(その分期待する)

高額なサービスなものほど品質に見合った成果が出るという認識を人は持っているため、そこをうまく刺激できるくらいの金額設定にしました。

本気で痩せたい人向けのサービスであるライザップとかが良い例ですね。


ボツにした理由

同じように個人開発されている方のブログを拝見していると「ユーザーが集まらないと価値が提供できないサービスは失敗する(難しい)」という内容をよく目にしました。

それを理解した上で、当初はある程度広告にもお金を掛けて集客しようと考えていました。

しかし、いざ開発を進めていると「ユーザーに使ってもらえるんだろうか?」「結構な開発ボリュームだけどコストに見合う利益は得られるのだろうか?」「時間もお金も掛けて失敗したら相当辛いだろうな…」など、ネガティブな思考がどんどん湧いてくるのです。

特に「時間もお金も掛けて失敗する」事態だけは絶対に避けたかったので、このアイデアはボツになりました。

この失敗から、個人開発する上での指針みたいなものが決まりました。

  • お金も掛かるし開発期間も長い → NG
  • お金は掛からないが開発期間が長い → NG
  • お金は掛かるが開発期間が短い → 場合によってはOK
  • お金も掛からないし開発期間も短い → OK

ボツにしたアイデア2 方眼紙マッピングWEBアプリ

普段ゲームをされない方は馴染みがないかもしれませんが、ウィザードリィというレトロゲームがあります。

古いゲームなので今みたいに地図(マップ)が表示される機能が存在せず、探索しながら紙の方眼紙に自分で地図を書いて進めるというのが一般的な手法です。

この面倒臭さも良さであり、今でもウィザードリィをプレイされる方はこの方法でゲームをプレイしています。

これをWEBアプリ化すれば便利なのではないか?と思いさっそく競合となるアプリを調べたところ、Windowsで動作するアプリケーションはあるのですがWEBで管理できるものはありませんでした。

一定数以上は需要があることも分かりました。

方眼紙マッピングの需要
「方眼紙マッピング」で検索した際の関連キーワード

これらの関連キーワードからiPhoneなりAndroidなり、ブラウザ上で動作するマッピングツールの需要があることが伺えます。

需要があり、まだWEBで使えるアプリは無かったのでこれはイケると確信し、さらに深く構想を練りましたが結局ボツにしました。


ボツにした理由

このアイデアに欠点はないか?を注意深く精査したところ「長期間使われるものではない」という欠点がありました。

マップ表示機能が存在しないものは、ウィザードリィのシリーズでも1、2本程度であり、使用するユーザーもウィザードリィをクリアしてしまえば、その後に使う機会はほぼ無いものです。

ウィザードリィ以外の3DダンジョンRPGもあることにはありますが、当然のごとくマップ表示機能は存在します。

見込みユーザー数が少ない上に想定される使用期間も短かったため、このアイデアをボツにしました。


個人開発で成功するには何を作れば良いか

以上のボツにしたアイデアを参考に、自分の中での個人開発で成功するための指針についてまとめました。


規模が小さいものを作る

個人開発はほとんど一人で作らねばならないので、当然大規模なものを開発することは相当難しいはずです。

世に出回っているサービスは何十人何百人の人間が関わっていて作られているものばかりです。

これらの規模が大きいサービスと戦っても勝てるはずは無いので、必然的に規模が小さいもので勝負することになるでしょう。

僕の考えですが、企業がサービス化しても利益を生みづらいもの、すなわち小遣い稼ぎ程度の利益が出そうなもので勝負することが成功への近道だと考えています。


自分が使いたいと思うものを作る

個人開発に関して調べていると「自分が使いたいと思うものを作ると良い」この言葉もよく耳にしました。

これを聞いた当初は「まぁ…そうかもね」程度にしか思ってませんでした。

そもそも使いたいと思ってるものなんて無かったし、アイデアの幅を狭めるのではないかと感じたからです。

でもこの言葉、今思えばかなり重要なことだったんだなと強く思います。

なぜなら自分が使いたいと思っている時点で需要があるからです。

ボツにした方眼紙マッピングWEBアプリもそうですが、関連キーワードに出るということは自分以外の需要も存在するということです。

僕はこの考えを念頭に置いてアイデアを出すようにしています。


面白いものではなく課題を解決するものを作る

仕事で自社サービスの開発をしているのですが、現場で「これ面白そうじゃない?作ろうよ」みたいな話がよく出ますが、これはほぼ間違いなく失敗する考え方だと思っています。

この面白そうという考え方は今まで無かったアイデアが浮かんだ際に芽生えることが多いですが、この時点でユーザー視点ではないので、失敗する可能性が大きいと考えています。

「面白い」が売りのクリエイティブ領域やエンタメ系でも同じことが言えるのか?というと、確かに新しい体験を望むユーザーは居ると思いますが、大前提として楽しめるコンテンツありきで、創意工夫の部分は二の次になるというのが現実ですよね。

上記の場合「面白そうと製作者が思うまったく新しいコンテンツ」ではなく「楽しめるコンテンツを探している」というユーザーの課題に答えるのが成功に導くのではないかなと思います。


長期間使用されるものを作る

方眼紙マッピングWEBアプリをボツにした理由がこれですが、ユーザーの使用想定期間が短いものは利益になり辛いと思います。

例えば、年賀状をWEB上で作成できるサービスは年末年始のみにしか使われないため、それを想定した上で利益が出るかどうかを熟慮する必要があります。

個人で開発する場合、継続した収益の安定化は必須だと思うので、使用想定期間が長いものを作った方が安心ですよね。


競合を避ける

これも当然といえば当然ですが、既に完成形に近いサービスがあるのに後発で個人開発して勝ち目があるのかというとほとんど無いので、これも重要な要素ですね。


まとめ

あくまで僕の主観ですが、個人開発で成功するための指針となります。

  • お金も時間も極力掛けずに開発する
  • 人が集まらないと楽しめないサービスは控える
  • 自分が使いたい or 過去に使いたかったものを作る
  • ユーザーの課題を解決するものを作る
  • 使用想定期間が長いものを作る
  • 競合を避ける

前述した通り、まだ1つもリリースしてないくせに大層な記事になってしまいましたが…。

それでも毎日頭がねじ切れるほど考えてまとめた開発指針です。
※こう見ると当たり前のことばかりですが、いろんな方の記事や成功しているサービスやアプリを見ると、この当たり前がとても重要なんだなと実感します。

同じように個人開発されている方、もしくはこれから始めようとしている方、エンジニアの方は仲良くして頂けると嬉しいです。

プログラミング画面

Laravel9/8 パスワードリセット機能の実装

Laravel Breezeを導入することで、ログインやアカウントの登録、パスワードのリセットができる状態になりますが、今回はLaravel Breeze導入後のパスワードリセット機能をカスタマイズする方法について解説していきます。

Laravel9で検証していますが、8のドキュメントを見ながら実装したので、どちらでも大丈夫だと思います。

※Laravel Breeze導入済みであることを前提としています。
※mailhogを使用して検証を行っています。


まずは下記のURLで表示されるビューの英語を日本語化していきます。
http://localhost:8000/forgot-password

./resources/views/auth/forgot-password.blade.phpに定義されている下記英語のメッセージ表示を日本語へ変更します。

<div class="mb-4 text-sm text-gray-600">
    {{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
</div>
<div class="flex items-center justify-end mt-4">
    <x-button>
        {{ __('Email Password Reset Link') }}
    </x-button>
</div>

./config/app.phpのロケールがjaになっていることを確認します。

'locale' => 'ja',

./langディレクトリにja.jsonという名前でファイルを追加します。

localeをjaに変更したことで、__ヘルパ関数を使用した際にja.jsonから翻訳文字列を取得できるようになります。

詳しくは日本語に翻訳されたドキュメントに書かれているので、こちらを参考にしてください。
https://readouble.com/laravel/8.x/ja/localization.html
※「翻訳文字列の取得」の箇所です。

ファイルを追加したら、下記のように定義して、英語メッセージを日本語に置き換えます。

{
    "Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.": "登録時のメールアドレスを入力してください",
    "Email Password Reset Link": "パスワードリセットメールを送信"
}

次に、ユーザーアクション後に表示されるメッセージも英語から日本語に変更します。

./langにjaディレクトリを作成し、その中に./lang/en/passwords.phpファイルをコピーしたものを格納してください。

下記のように配置できていればOKです。

lang
├── en
│   ├── auth.php
│   ├── pagination.php
│   ├── passwords.php
│   └── validation.php
├── en.json
├── ja
│   └── passwords.php
└── ja.json

./lang/ja/passwords.phpを下記のように編集します。

    'reset' => 'パスワードのリセットが完了しました',
    'sent' => 'パスワードリセット用リンクのメールを送信しました',
    'throttled' => 'しばらく経ってからお試しください',
    'token' => 'トークンが無効のため、あらためてパスワードリセットを実行してください',
    'user' => "登録されていないメールアドレスです",

ここまできたら、登録されていないメールアドレスを入力して反映されているか確認してみましょう。
今まで設定してきた日本語が適用されていればOKです。

日本語化されたメッセージ

次に、通知クラスを追加します。

Laravel Breezeで実装されているソースコードを追うと分かりますが、この通知クラスを利用してパスワードリセットメールを送信しているため、同じように下記コマンドで通知クラスを追加します。
※ResetPasswordNotificationの部分は任意のクラス名を指定してください。

php artisan make:notification ResetPasswordNotification

./app/Notificationsの中に指定したクラスファイルが追加されているはずです。

次に、./app/Models/User.phpに下記内容を追記します。

use App\Notifications\ResetPasswordNotification;

    public function sendPasswordResetNotification($token)
    {
        $url = url("reset-password/${token}");
        $this->notify(new ResetPasswordNotification($url));
    }

次に、先ほど追加した通知クラス内(ここでは./app/Notifications/ResetPasswordNotification)のtoMailメソッドを下記のように修正します。

    // コンストラクタでurlを格納します
    public function __construct($url)
    {
        $this->url = $url;
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->subject(config('app.name'). ' パスワードリセットURLの送付')
                    ->greeting('いつもご利用頂きありがとうございます')
                    ->action('パスワードリセット', $this->url)
                    ->line('こちらからパスワードリセットを行ってください');
    }

パスワードリセット画面でメールアドレスを入力し、実際にメールが送られてくることを確認します。

http://localhost:8025にアクセスして、受信したメールを確認します。

設定した内容が適用されていればOKです。

メール受信成功画面

メールテンプレートをデフォルトから変更したい場合、下記のようにviewメソッドをコールすることで実現できます。
下記の場合./resources/views/emails/list_password.blade.phpファイルを追加することになります。

    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->subject(config('app.name'). ' パスワードリセットURLの送付')
                    ->greeting('いつもご利用頂きありがとうございます')
                    ->action('パスワードリセット', $this->url)
                    ->line('こちらからパスワードリセットを行ってください')
                    ->view('emails.liset_password');
    }

メールテンプレートの設定について詳しく知りたい方は、こちらも日本語に翻訳されたドキュメントに書かれているので参考にしてください。
https://readouble.com/laravel/8.x/ja/notifications.html
※「その他のメール通知フォーマットオプション」の箇所です。

エラーが出てメールが受信できない場合は.envと./config/mail.phpの設定を見直してみてください。
下記のようになっていれば問題ないと思います。

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=hoge@example.com
MAIL_FROM_NAME="${APP_NAME}"
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
            'port' => env('MAIL_PORT', 587),
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
            'username' => env('MAIL_USERNAME'),
            'password' => env('MAIL_PASSWORD'),
            'timeout' => null,
        ],

受信したメールのリンクからパスワードリセット画面へアクセスします。

ボタンがRESET PASSWORDになっているので、ここも日本語に変更します。

パスワードリセット画面のビューは./resources/views/auth/reset-password.blade.phpなので、ボタンの定義を確認します。

            <div class="flex items-center justify-end mt-4">
                <x-button>
                    {{ __('Reset Password') }}
                </x-button>
            </div>

‘Reset Password’の翻訳文字列を./lang/ja.jsonに定義します。

"Reset Password": "パスワードリセット"

※ちなみに’Reset Password’と表記されているのに画面表示上ではなぜ全て大文字になっているのか?気になって調べたところ、buttonコンポーネント内でTailwind CSS のclassであるuppercaseが定義されていたからでした。

バリデーションエラーメッセージを確認するためPasswordに”aaa”Confirm Passwordに”bbb”等適当な短い文字列を入力して、エラー表示させてみます。

下記のような英語メッセージが出るので、ここも日本語に変更していきます。

  • The password confirmation does not match.
  • The password must be at least 8 characters.

./lang/en/validation.phpを./lang/ja/にコピーします。

コピーしたら、34行目あたりの’confirmed’と96行目あたりの’min’ => [‘string’]を下記のように書き換えます。

    'confirmed' => ':attribute が一致しません',

    'min' => [
        'numeric' => 'The :attribute must be at least :min.',
        'file' => 'The :attribute must be at least :min kilobytes.',
        'string' => ':attribute は :min 文字以上必要です',
        'array' => 'The :attribute must have at least :min items.',
    ],

再度Passwordに”aaa”Confirm Passwordに”bbb”等適当な短い文字列を入力して、エラーメッセージが日本語になっていることを確認します。

エラーメッセージが日本語になっている

最後に、正常にパスワードリセットができることを確認できれば完了です。

パスワードリセット成功

参考になりましたら、記事を拡散して頂くと嬉しいです😊