- テンプレートの機能を持つ
- スーパークラス(親)の方にテンプレートメソッド(抽象メソッド)が定義される
- サブクラス(子)で具体的な内容を実装メソッドとして再定義する
Template Methodパターン
common
InitialSetting.java
LogInfo.java
OriginalHandler.java
message_list.txt
input_info
in_diff_date.txt
in_same_date.txt
output_info
out_diff_date.txt
out_same_date.txt
log
error_log
result_log
template_method
AbstractCalendar.java
DifferentDateCalendar.java
MainTemplate.java
SameDateCalendar.java
Value.java
template.properties
template.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#template.properties #出力言語 language_code=JA #日付フォーマット date_format=yyyy/MM/dd #メッセージファイル msg_list=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\common\\message_list.txt #稼働ログ result_log=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\log\\result_log #エラーログ error_log=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\log\\error_log #同日の日付情報(現) in_same_date=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\input_info\\in_same_date.txt #同月、同週、同曜日の日付情報(現) in_diff_date=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\input_info\\in_diff_date.txt #同日の日付情報(次) out_same_date=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\output_info\\out_same_date.txt #同月、同週、同曜日の日付情報(次) out_diff_date=D:\\D_ProgramFiles\\pleiades\\workspace\\Tomcat8\\src\\output_info\\out_diff_date.txt |
MainTemplateクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package template_method; import java.util.ResourceBundle; import common.InitialSetting; import common.LogInfo; public class MainTemplate { public static void main(String[] args) throws Exception { ResourceBundle prop = ResourceBundle.getBundle("template"); InitialSetting is = new InitialSetting(prop); LogInfo.printLog("IZ0001"); SameDateCalendar s = new SameDateCalendar(is.getSameDateInFile()); s.nextCalendar(s.getInfoYears(), is); DifferentDateCalendar d = new DifferentDateCalendar(is.getDifferentDateInFile()); d.nextCalendar(d.getInfoYears(), is); LogInfo.printLog("IZ0002"); } } |
in_same_date.txt
20190715
20190815
20190812
20190923
in_diff_date.txt
20190214
20190326
20190728
20190803
20190804
20191027
20191126
コンソール出力
1 2 3 4 5 6 7 8 9 10 11 12 13 |
情報: 処理開始 [月 3 30 04:00:40 JST 2020] 2020/07/15(水) 2020/08/15(土) 2020/08/12(水) 2020/09/23(水) 2020/02/13(木) 2020/03/24(火) 2020/07/26(日) 2020/08/01(土) 2020/08/02(日) 2020/10/25(日) 2020/11/24(火) 情報: 正常終了 [月 3 30 04:00:40 JST 2020] |
common
InitialSettingクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
package common; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.ResourceBundle; public class InitialSetting extends LogInfo{ public static final String JAPANESE = "JA"; public static final String ENGLISH = "EN"; public static final String CHINESE = "CN"; public static final String KOREAN = "KR"; public static final String FORMAT_DAY_OF_WEEK = "(E)"; private String sameDateInFile = null; private String sameDateOutFile = null; private String differentDateInFile = null; private String differentDateOutFile = null; SimpleDateFormat sdf = null; public String getSameDateInFile() { return sameDateInFile; } public String getSameDateOutFile() { return sameDateOutFile; } public String getDifferentDateInFile() { return differentDateInFile; } public String getDifferentDateOutFile() { return differentDateOutFile; } public SimpleDateFormat getSdf() { return sdf; } public InitialSetting(ResourceBundle prop) throws Exception { super(prop); String languageCode = prop.getString("language_code"); switch (languageCode) { case JAPANESE: Locale.setDefault(Locale.JAPANESE); break; case ENGLISH: Locale.setDefault(Locale.ENGLISH); break; case CHINESE: Locale.setDefault(Locale.CHINESE); break; case KOREAN: Locale.setDefault(Locale.KOREAN); break; default: printLog("IZ0003"); printLog("SA0002"); throw new Exception(); } String df = prop.getString("date_format"); this.sdf = new SimpleDateFormat(df + FORMAT_DAY_OF_WEEK); this.sameDateInFile = prop.getString("in_same_date"); this.sameDateOutFile = prop.getString("out_same_date"); this.differentDateInFile = prop.getString("in_diff_date"); this.differentDateOutFile = prop.getString("out_diff_date"); } } |
LogInfoクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
package common; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.ResourceBundle; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; public class LogInfo { public final static String MSG_INFO = "I"; public final static String MSG_WARNING = "W"; private ResourceBundle prop = null; private static Logger logger = null; private static Logger errLogger = null; private static HashMap<String, String> msgHash = new HashMap<>(); public ResourceBundle getProp() { return prop; } LogInfo(ResourceBundle prop) throws Exception { this.prop = prop; logger = getLogger(); errLogger = Logger.getLogger(LogInfo.class.getName()); try { //稼働ログ設定 String resultLog = prop.getString("result_log"); FileHandler resultHand = new FileHandler(resultLog, false); //エラーログ設定 String errLog = prop.getString("error_log"); FileHandler errHand = new FileHandler(errLog, false); resultHand.setFormatter(new SimpleFormatter()); errHand.setFormatter(new SimpleFormatter()); logger.addHandler(resultHand); errLogger.addHandler(errHand); //ハンドラーでエラーログレベルの設定を行う errLogger.setLevel(Level.ALL); errHand.setLevel(Level.WARNING); makeMsgTable(prop.getString("msg_list")); } catch (Exception e) { e.printStackTrace(); System.err.println("ログ設定で異常有。ログファイルパスを確認してください。"); System.exit(1); } } private void makeMsgTable(String msgFile) throws Exception { File mf = new File(msgFile); if (!mf.exists()) { System.err.println("メッセージファイル:" + msgFile + "が存在しません。"); throw new Exception(); } FileReader fr = new FileReader(mf); BufferedReader br = new BufferedReader(fr); String line = null; while ((line = br.readLine()) != null) { line.trim(); List<String> list = Arrays.asList(line.split("\t")); msgHash.put(list.get(0), list.get(1) + "\t" + list.get(2)); } br.close(); } public static void printLog(String msgId) throws Exception { if (!msgHash.containsKey(msgId)) { System.err.println("messageID:" + msgId + "が存在しません。"); throw new Exception(); } List<String> list = Arrays.asList(msgHash.get(msgId).split("\t")); if (MSG_INFO.equals(list.get(0)) || MSG_WARNING.equals(list.get(0))) { logger.info(list.get(1)); } else { errLogger.severe(list.get(1)); } } protected static Logger getLogger() { if (logger == null) { logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); // ↓を設定しないとデフォルトのログも一緒に出る logger.setUseParentHandlers(false); // FINEST < FINER < FINE < CONFIG < INFO < WARNING < SEVERE logger.addHandler(new OriginalHandler(System.out, Level.FINEST, Level.INFO)); logger.addHandler(new OriginalHandler(System.err, Level.WARNING, Level.SEVERE)); } return logger; } } |
OriginalHandlerクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package common; import java.io.OutputStream; import java.util.logging.Filter; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.SimpleFormatter; import java.util.logging.StreamHandler; public class OriginalHandler extends StreamHandler { public OriginalHandler(OutputStream out, Level min, Level max) { super(); setOutputStream(out); setFilter(new OriginalFilter(min, max)); setFormatter(new SimpleFormatter()); setLevel(Level.ALL); } @Override public synchronized void publish(LogRecord record) { super.publish(record); flush(); } @Override public void close() { flush(); } } class OriginalFilter implements Filter { /** 出力する最小のレベル */ private final Level min; /** 出力する最大のレベル */ private final Level max; OriginalFilter(Level min, Level max) { this.min = min; this.max = max; } public boolean isLoggable(LogRecord record) { return (min.intValue() <= record.getLevel().intValue()) && record.getLevel().intValue() <= max.intValue(); } } |
message_list.txt
1 2 3 4 5 6 7 8 9 10 11 |
SA0001 S 指定したファイルが存在しません。プロパティファイルを確認してください。 SA0002 S 指定した言語が存在しません。プロパティファイルを確認してください。 SA9999 S 異常終了させるような非常に深刻なイベント EA0001 E ERRORメッセージ EA9999 E 稼働が継続できる程度のエラー WA0001 W WARNINGメッセージ WA9999 W 潜在的に害を及ぼすような状況 IZ0001 I 処理開始 IZ0002 I 正常終了 IZ0003 I 異常終了 IZ9999 I 進捗の概要が分かるメッセージ |
template_method
AbstractCalendarクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
package template_method; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import common.InitialSetting; import common.LogInfo; public abstract class AbstractCalendar { //日付情報 private List<Value> infoYears = null; public List<Value> getInfoYears() { return infoYears; } protected abstract void nextCalendar(List<Value> infoYears, InitialSetting is) throws Exception; AbstractCalendar(String inFile) throws Exception { List<Value> list = new ArrayList<>(); File mf = new File(inFile); if (!mf.exists()) { LogInfo.printLog("IZ0003"); LogInfo.printLog("SA0002"); throw new Exception(); } FileReader fr = new FileReader(mf); BufferedReader br = new BufferedReader(fr); String data = null; while ((data = br.readLine()) != null) { Value val = new Value(); val.setCurrentYear(Integer.parseInt(data.substring(0, 4))); val.setCurrentMonth(Integer.parseInt(data.substring(4, 6))); val.setCurrentDate(Integer.parseInt(data.substring(6, 8))); list.add(val); } br.close(); this.infoYears = list; } protected Calendar nextCalendarInfo(Value val) { Calendar nextCal = Calendar.getInstance(); nextCal.set(Calendar.YEAR, val.getNextYear()); nextCal.set(Calendar.MONTH, val.getNextMonth()); nextCal.set(Calendar.DAY_OF_WEEK, val.getNextDay()); nextCal.set(Calendar.DAY_OF_WEEK_IN_MONTH, val.getNextCntDay()); return nextCal; } } |
SameDateCalendarクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package template_method; import java.io.PrintWriter; import java.util.Calendar; import java.util.List; import common.InitialSetting; import common.LogInfo; public class SameDateCalendar extends AbstractCalendar{ SameDateCalendar(String inFile) throws Exception{ super(inFile); } @Override protected void nextCalendar(List<Value> infoYears, InitialSetting is) throws Exception { try { Calendar nextCal = Calendar.getInstance(); PrintWriter outFile = new PrintWriter(is.getSameDateOutFile()); for (Value val : infoYears) { nextCal.set(val.getCurrentYear() + 1, val.getCurrentMonth() - 1, val.getCurrentDate()); outFile.println(is.getSdf().format(nextCal.getTime())); System.out.println(is.getSdf().format(nextCal.getTime())); } outFile.close(); } catch (Exception e) { LogInfo.printLog("IZ0003"); LogInfo.printLog("SA0002"); e.printStackTrace(); } } } |
DifferentDateCalendarクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package template_method; import java.io.PrintWriter; import java.util.Calendar; import java.util.List; import common.InitialSetting; import common.LogInfo; public class DifferentDateCalendar extends AbstractCalendar { DifferentDateCalendar(String inFile) throws Exception { super(inFile); } @Override protected void nextCalendar(List<Value> infoYears, InitialSetting is) throws Exception { try { Calendar cal = Calendar.getInstance(); PrintWriter outFile = new PrintWriter(is.getDifferentDateOutFile()); for (Value val : infoYears) { Value nextVal = new Value(); cal.set(val.getCurrentYear(), val.getCurrentMonth() - 1, val.getCurrentDate()); nextVal.setNextYear(val.getCurrentYear() + 1); nextVal.setNextMonth(val.getCurrentMonth() - 1); nextVal.setNextDay(cal.get(Calendar.DAY_OF_WEEK)); nextVal.setNextCntDay(cal.get(Calendar.DAY_OF_WEEK_IN_MONTH)); Calendar nextCal = nextCalendarInfo(nextVal); outFile.println(is.getSdf().format(nextCal.getTime())); System.out.println(is.getSdf().format(nextCal.getTime())); } outFile.close(); } catch (Exception e) { LogInfo.printLog("IZ0003"); LogInfo.printLog("SA0002"); e.printStackTrace(); } } } |
Valueクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
package template_method; public class Value { //年(現) private int currentYear = 0; //月(現) private int currentMonth = 0; //日(現) private int currentDate = 0; //曜日(現)1~7:日~土 private int currentDay = 0; //年(次) private int nextYear = 0; //月(次) private int nextMonth = 0; //日(次) private int nextDate = 0; //曜日(次)1~7:日~土 private int nextDay = 0; //曜日が月で何度目か(次) private int nextCntDay = 0; public int getCurrentYear() { return currentYear; } public void setCurrentYear(int currentYear) { this.currentYear = currentYear; } public int getCurrentMonth() { return currentMonth; } public void setCurrentMonth(int currentMonth) { this.currentMonth = currentMonth; } public int getCurrentDate() { return currentDate; } public void setCurrentDate(int currentDate) { this.currentDate = currentDate; } public int getCurrentDay() { return currentDay; } public void setCurrentDay(int currentDay) { this.currentDay = currentDay; } public int getNextYear() { return nextYear; } public void setNextYear(int nextYear) { this.nextYear = nextYear; } public int getNextMonth() { return nextMonth; } public void setNextMonth(int nextMonth) { this.nextMonth = nextMonth; } public int getNextDate() { return nextDate; } public void setNextDate(int nextDate) { this.nextDate = nextDate; } public int getNextDay() { return nextDay; } public void setNextDay(int nextDay) { this.nextDay = nextDay; } public int getNextCntDay() { return nextCntDay; } public void setNextCntDay(int nextCntDay) { this.nextCntDay = nextCntDay; } } |
出力内容を変更するには、
プロパティファイルを編集します。
変更内容を外部ファイルに持つことで
ソースコードを修正せずに済みます。
- 出力言語:JA → EN
- 日付フォーマット:yyyy/MM/dd → G:yyyy/MM/dd
template.properties
1 2 3 4 5 6 7 |
#template.properties #出力言語 language_code=EN #日付フォーマット date_format=G:yyyy/MM/dd |
コンソール出力
1 2 3 4 5 6 7 8 9 10 11 12 13 |
INFO: 処理開始 [Mon Mar 30 05:57:46 JST 2020] AD:2020/07/15(Wed) AD:2020/08/15(Sat) AD:2020/08/12(Wed) AD:2020/09/23(Wed) AD:2020/02/13(Thu) AD:2020/03/24(Tue) AD:2020/07/26(Sun) AD:2020/08/01(Sat) AD:2020/08/02(Sun) AD:2020/10/25(Sun) AD:2020/11/24(Tue) INFO: 正常終了 [Mon Mar 30 05:57:46 JST 2020] |
他にもデザインパターンが存在するので
覚えておくと色々な処理に応用できるので
ここはぜひ、おさえておきたいポイントです。
今の年収に満足していますか?
同じ契約金で業務委託していても
在籍している会社によって給料が違います。
今と同じスキル・業務内容でも
年収が変わるということです。
さらに以下を考慮すると
より年収アップにつながります。
- スキルセットと需要
- 経験と実績
- 業界や地域の市場価値
- 転職時の交渉スキル
転職先の企業の給与体系や
業界の標準的な給与水準を調査し、
給与のみでなく、
福利厚生やキャリア成長の機会、
ワークライフバランスなどの要素も
総合的に考慮することが重要です。
Kindle Unlimitedは、Amazonが提供する
月額定額制の電子書籍サービスを活用します。
また、Kindle Unlimitedには、
体験版が提供されています。
体験版では、一定期間(通常は30日間)に限り、
Kindle Unlimitedのサービスを
無料で利用することができます。
1.豊富な書籍のラインナップ
Kindle Unlimitedには、幅広いジャンルの書籍が
数十万冊以上含まれています。
小説、ビジネス書、自己啓発書、
学術書、漫画など、
様々なテーマや興味に合わせて
多彩な選択肢があります。
2.サービスの内容を体験
体験版では、Kindle Unlimitedの全ての機能を使いながら、
豊富な書籍のラインナップや
読書体験を体験することができます。
自身の読書の好みや
利用頻度に合うかどうかを確認できます。
3.解約が可能
体験版期間中にKindle Unlimitedのサービスに
満足しなかった場合、
期限内に解約することができます。
その場合、追加料金はかかりません。
Kindle Unlimitedでは
さまざまなジャンルの書籍が提供されています。
ITエンジニアとしてスキルを向上させたり
新しい技術を学んだりする際に、
Kindle Unlimitedは
便利な資源となるのでおすすめです。
この記事へのコメントはありません。