- テンプレートの機能を持つ
- スーパークラス(親)の方にテンプレートメソッド(抽象メソッド)が定義される
- サブクラス(子)で具体的な内容を実装メソッドとして再定義する
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] |
この記事へのコメントはありません。