自分のポモドーロを作りましょう

##はじめに
この記事は[リンク情報システム](https://www.lis.co.jp/)の[「2019 Tech Connect Summer」](https://qiita.com/dgkz/items/2862d5e6b77203a126b3)のリレー記事です。
engineer.hanzomon のグループメンバによってリレーされます。
リンク情報システムのFacebookは[こちら](https://ja-jp.facebook.com/lis.co.jp/)です。

クマさんチームの九日目を担当しますGo(@Go_in_lis)です。
ポモドーロ・テクニックという作業方法とその作業に必要なタイマーの簡単な作り方(Java)を紹介します。

##ポモドーロ・テクニック
　ポモドーロ・テクニックというのは、1980年代にFrancesco Cirilloが提案した効率的な作業方法です。
　以下の手順に従い、人の集中力とやる気をアップすることにより、個人やチームの生産性を向上することがポモドーロ・テクニックの目的です。
####ポモドーロ・テクニックの手順
1. タスク(目標)を設定する。
2. ポモドーロ(作業)を行う。通常、ポモドーロ一個が25分。
3. 小休憩を取る。通常、小休憩一回は3-5分。
4. 2に戻る。
5. 四つのポモドーロが完成するとき、小休憩ではなく長めの休憩を取る。通常、長めの休憩は15-30分。
6. 1に戻る。

　しかし、集中力は人によって変わるものです。25分でようやく集中できたのに中断されたり、休憩5分では足りなかったりする人は必ずいると思います。
　そこで、本記事では各項目の時間を調整できる「自分のポモドーロタイマー」を作る手法を紹介します。

##実装環境
|種別|名称|
|:---|:---|
|開発言語|Java|
|開発ツール|Eclipse Java 2019-06|
|開発os|win10|
##ポモドーロのフローチャート
　以下のフローチャートはプログラムの手順を示します。なお、ループに掲載している条件は継続条件となります。
![pomodoro_flowchat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/7b6c46a4-4a79-2467-d63e-e25c4dadb4f0.png)



`*フローチャートの作成ツール：https://www.draw.io/`

##ソースコード
####タイマーの設定
　コンソールの入力により各項目の時間が設定できます。
　そして、他のメソッドも設定された時間を利用できるように、フィールドの各メンバーの値を読み取り可能のメソッドも用意しました。

```Java
public class SetTimer
{
	private int pomodoroTime;
	private int shortBreakTime;
	private int pomoNum;
	private int longBreakTime;
	
	//タイマーの設定
	public SetTimer() throws NumberFormatException, IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		System.out.print("ポモドーロの時間(分)を入力してください：");
		pomodoroTime = Integer.parseInt(br.readLine());
		System.out.print("小休憩の時間(分)を入力してください：");
		shortBreakTime = Integer.parseInt(br.readLine());
		System.out.print("長めの休憩までのポモドーロの個数を入力してください：");
		pomoNum = Integer.parseInt(br.readLine());
		System.out.print("長めの休憩の時間(分)を入力してください：");
		longBreakTime = Integer.parseInt(br.readLine());
	}
	
	//各項目のデータの読み取り
	public int getPomodoroTime()
	{
		return pomodoroTime;
	}
	public int getShortBreakTime()
	{
		return shortBreakTime;
	}
	public int getPomoNum()
	{
		return pomoNum;
	}
	public int getLongBreakTime()
	{
		return longBreakTime;
	}	
}
```
####カウントダウン処理(Thread.sleep利用)
　ここで使用するカウントダウンの処理方法として、まずは設定時間を秒単位に変換します。そして、1秒を待てから時間を1秒減らすという操作をループします。ループは時間が0になる時終了します。
　コードは以下となります。

```Java
public class CountDown
{
	//fields
	private static long totalTimeBySec;
	private static long perSec = 1000;
	
	//method
	public static void bySleep(int totalTime) throws InterruptedException		//sleepメソッドを利用するカウントダウン方法
	{
		totalTimeBySec =totalTime * 60;
		for(long i = totalTimeBySec; i >= 0; i--)
		{
			Thread.sleep(perSec);				//一秒を待つ
			ShowTime.remainTime(i);			//残り時間を表示
		}
	}
}
```

####時間表示
　普段の生活中に使用されているデジタル時計は、分・秒にかかわらず2桁で表示するのが一般的です。
　Javaにもc言語の「%2d」と類似する方法がありますが、せっかくのオブジェクト指向のプログラミング言語ですので、DecimalFormatというクラスを使いたいと思います。
　DecimalFormatクラスは、コンストラクタを利用し、十進数のフォーマットを設定できます。そして、format()メソッドを利用し、引数をフォーマット通りに変更できます。
　コードは以下となります。

```Java
public static void remainTime(long timeBySec)
{
		long min = timeBySec/60;
		long sec = timeBySec%60;
		
		DecimalFormat df = new DecimalFormat("00");	//分、秒を二桁で出力
		
		System.out.println(df.format(min) + ":" + df.format(sec));
}
```

####その他のメッセージ表示
　次のタスクに入るかどうかは、使用者に決めてもらいます。その時のio処理メソッドは以下のクラスに書いています。
　そして、ポモドーロ・休憩を開始したり終了したりする時に、ただ表示時間がゼロや初期値になるだけではなく、相応のメッセージを提示する必要もあると思います。これらのメッセージの表示メソッドも以下のクラスにまとめています。

```Java
public class Message
{
	public static boolean isContinue() throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while(true)
		{
			System.out.println("次のタスクをやりたいですか?(Y/N)");
			String reply = br.readLine();
			if(reply.equals("Y"))
			{
				System.out.println("続きます。頑張りましょう。");
				return true;
			}
			else if(reply.equals("N"))
			{
				System.out.println("終了です。お疲れ様です。");
				return false;
			}
			else
			{
				continue;
			}
		}
	}
	
	public static void startPomo()
	{
		System.out.print("ポモドーロ、始めます。");
	}
	
	public static void startShortBreak()
	{
		System.out.print("小休憩、始めます。");
	}
	
	public static void startLongBreak()
	{
		System.out.print("長めの休憩、始めます。");
	}
}

```

####主処理
　すべての処理を、フローチャート通りに組み合わせをすれば、「自分のポモドーロタイマー」が完成です。

```Java
public class Main
{
	public static void main(String[] args) throws InterruptedException, NumberFormatException, IOException
	{
		boolean isContinue = true;
		SetTimer timer = new SetTimer();			//各項目の時間の設定
		do {
			for(int i = 0; i < timer.getPomoNum(); i++)
			{
				Message.startPomo();
				CountDown.bySleep(timer.getPomodoroTime());			//ポモドーロ
				if(i == timer.getPomoNum() - 1)
				{
					Message.startLongBreak();
					CountDown.bySleep(timer.getLongBreakTime());		//長めの休憩
				}
				else
				{
					Message.startShortBreak();
					CountDown.bySleep(timer.getShortBreakTime());	//小休憩
				}
			}
			isContinue = Message.isContinue();
		}while(isContinue);
	}
}
```

##結果
　それでは、実行結果を見てみましょう。
　実行した後、まずはコンソール入力でポモドーロ・小休憩・長めの休憩の時間、長めの休憩までのポモドーロの個数を設定できます。すべての設定が終了したら、タイマーが始まります。
　こちらの画像は効果を示すために、時間を短く設定しています。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/a99599fc-664d-1ed7-3016-06dd8d0eb6f4.png" width = 60% height = 60%>
　ポモドーロが一個終了後、小休憩が始まるというメッセージを提示し、小休憩を始めます。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/7ee8f185-ab78-0fa1-ecff-8741f5819d04.png" width = 50% height = 50%>
　小休憩が終わりましたら、次のポモドーロが始まります。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/f5139195-9d1c-783a-1121-9579ed286348.png" width = 50% height = 50%>
　長めの休憩に入るときもメッセージを提示した後に始まります。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/362e851c-a643-531a-6cff-984d4c6f7d25.png" width = 50% height = 50%>
　長めの休憩が終了後、次のタスクに入るかを決めることができます。「Y」で入力すると、次のタスクに入り、ポモドーロが始まります。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/0adbb61f-2884-a9b5-e363-d26b054c0081.png" width = 50% height = 50%>
　「N」で入力すると、タイマーが終了します。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468972/e16ce4f7-caf0-a86b-baaa-af1fbce74246.png" width = 50% height = 50%>

　こちらのコンソールアプリケーションは残り時間を一行ずつ出力しています。その理由は時間がきちんと一秒ずつカウントダウンしているかを確認するためです。
　毎回前の行を上書き表示するには、`System.out.print("")`のダブルコーテーションに「\b」か「\r」などのエスケープシーケンスを利用することにより実現可能のはずですが、Eclipseのバージョンやシステムなどの環境により実現できない場合もあります。今回の実装環境では実現できないと検証しました。
##参考文献
[1] Pomodoro Technique - Wikipedia. https://en.wikipedia.org/wiki/Pomodoro_Technique
[2] Cirillo, Francesco. "The pomodoro technique (the pomodoro)." Agile Processes in Software Engineering and 54.2 (2006).

##展望
　今回はテーマを何にすればいいとなかなか悩んでいて、決めるのも遅くなる結果、ただのコンソールアプリケーションを作りました。
　ですが、このシステムの展望として、
　　1. データベースに繋ぎ、時間や作業内容の記録
　　2. 作業効率の分析やアドバイス
　　3. GUIのあるアプリケーションやWebアプリケーションにすれば綺麗に見える
　などのことが実現可能となります。

##おわりに
　つまらないものですが、最後までご覧いただきありがとうございます。またご機会があれば、レベルアップのポモドーロを展示したいと思います。
　次はいよいよトリの記事です。引き続きよろしくお願いします！

---
[リンク情報システム株式会社](https://www.lis.co.jp/)では一緒に働く仲間を[随時募集](https://www.lis.co.jp/employ_top)しています。また、お仕事のご依頼、ビジネスパートナー様も募集しております。[お気軽にご連絡](https://www.lis.co.jp/inquiry)ください。