回答編集履歴

2

factory ではなく builder

2023/01/01 17:30

投稿

jimbe
jimbe

スコア13209

test CHANGED
@@ -35,18 +35,18 @@
35
35
 
36
36
  SortTest readFrom(String filename) throws FileNotFoundException, IOException { //throws で例外時の処理は呼び出し側に任せる
37
37
  persons.clear();
38
- Person.Factory factory = new Person.Factory();
38
+ Person.Builder builder = new Person.Builder();
39
39
  try(BufferedReader reader = new BufferedReader(new FileReader(filename))) { //try-with-resource ( close が自動的 )
40
40
  for(String line; (line=reader.readLine()) != null; ) { //'readLine' の結果を受ける変数名は 'line' のほうが合ってる感じ. そして変数の有効範囲(スコープ)は狭く
41
41
  String[] tokens = line.split(",");
42
42
  try {
43
43
  if(tokens.length == 4) {
44
- persons.add(factory
44
+ persons.add(builder
45
45
  .setId(tokens[0])
46
46
  .setName(tokens[1])
47
47
  .setBirthday(tokens[2])
48
48
  .setGender(tokens[3])
49
- .create());
49
+ .build());
50
50
  } else {
51
51
  throw new IllegalStateException("データが4つでは無い. tokens.length="+tokens.length);
52
52
  }
@@ -77,30 +77,30 @@
77
77
  //birthday の解析/表示用
78
78
  private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
79
79
 
80
- static class Factory { //ファクトリパターン (Person の生成はこのクラスが行う)
80
+ static class Builder { //Person の生成はこのクラスが行う
81
81
  private int id;
82
82
  private String name;
83
83
  private LocalDate birthday;
84
84
  private Gender gender;
85
85
 
86
- Factory setId(String id) {
86
+ Builder setId(String id) {
87
87
  this.id = Integer.parseInt(id);
88
88
  return this; //自身を返すことで、呼び出し側が '.' で複数のメソッドを繋げて書けるようになる
89
89
  }
90
- Factory setName(String name) {
90
+ Builder setName(String name) {
91
91
  if(name == null) throw new NullPointerException();
92
92
  this.name = name;
93
93
  return this;
94
94
  }
95
- Factory setBirthday(String birthday) {
95
+ Builder setBirthday(String birthday) {
96
96
  this.birthday = LocalDate.parse(birthday, formatter);
97
97
  return this;
98
98
  }
99
- Factory setGender(String gender) {
99
+ Builder setGender(String gender) {
100
100
  this.gender = Gender.valueOf(gender);
101
101
  return this;
102
102
  }
103
- Person create() {
103
+ Person build() {
104
104
  return new Person(id, name, birthday, gender);
105
105
  }
106
106
  }
@@ -110,7 +110,7 @@
110
110
  final LocalDate birthday;
111
111
  final Gender gender;
112
112
 
113
- private Person(int id, String name, LocalDate birthday, Gender gender) { //Factory が生成する為 private
113
+ private Person(int id, String name, LocalDate birthday, Gender gender) {
114
114
  this.id = id;
115
115
  this.name = name;
116
116
  this.birthday = birthday;

1

コード追加

2022/12/29 17:06

投稿

jimbe
jimbe

スコア13209

test CHANGED
@@ -8,4 +8,149 @@
8
8
  Collections.sort(sortbeanArray, new MemberComparator());
9
9
  for (int i = 0; i < sortbeanArray.size(); i++) {
10
10
  ```
11
+ ---
12
+ 勉強用なら、 TN8001 さんと違った方向のコードにしてみます。
13
+ ```java
14
+ import java.io.*;
15
+ import java.time.LocalDate;
16
+ import java.time.format.DateTimeFormatter;
17
+ import java.util.*;
11
18
 
19
+ public class SortTest {
20
+ public static void main(String[] args) {
21
+ try {
22
+ new SortTest()
23
+ .readFrom("meibo.txt") //ファイル名は埋め込むよりパラメータで渡す
24
+ .show("■ ソートせずに一覧表示")
25
+ .sort((a,b) -> a.id < b.id ? -1 : a.id > b.id ? 1 : 0) //ラムダ式 & 三項演算子
26
+ .show("■ IDでソートし一覧表示");
27
+ } catch(FileNotFoundException e) {
28
+ System.out.println("ファイルが見つかりません."+e.getMessage());
29
+ } catch(IOException e) {
30
+ System.out.println("ファイルの読み込みで問題が発生しました. "+e.getMessage());
31
+ }
32
+ }
33
+
34
+ private List<Person> persons = new ArrayList<>();
35
+
36
+ SortTest readFrom(String filename) throws FileNotFoundException, IOException { //throws で例外時の処理は呼び出し側に任せる
37
+ persons.clear();
38
+ Person.Factory factory = new Person.Factory();
39
+ try(BufferedReader reader = new BufferedReader(new FileReader(filename))) { //try-with-resource ( close が自動的 )
40
+ for(String line; (line=reader.readLine()) != null; ) { //'readLine' の結果を受ける変数名は 'line' のほうが合ってる感じ. そして変数の有効範囲(スコープ)は狭く
41
+ String[] tokens = line.split(",");
42
+ try {
43
+ if(tokens.length == 4) {
44
+ persons.add(factory
45
+ .setId(tokens[0])
46
+ .setName(tokens[1])
47
+ .setBirthday(tokens[2])
48
+ .setGender(tokens[3])
49
+ .create());
50
+ } else {
51
+ throw new IllegalStateException("データが4つでは無い. tokens.length="+tokens.length);
52
+ }
53
+ } catch(Exception e) {
54
+ System.out.println("format error. line="+line);
55
+ e.printStackTrace(); //例外の詳細の表示はコレ
56
+ }
57
+ }
58
+ }
59
+ System.out.println("読み込み完了");
60
+ return this;
61
+ }
62
+
63
+ SortTest sort(Comparator<Person> comparator) {
64
+ Collections.sort(persons, comparator);
65
+ return this;
66
+ }
67
+
68
+ SortTest show(String header) {
69
+ System.out.println(header);
70
+ for(Person person : persons) System.out.println(""+person);
71
+ return this;
72
+ }
73
+
74
+ private static class Person {
75
+ enum Gender { Male, Female } //少ない選択肢なら enum
76
+
77
+ //birthday の解析/表示用
78
+ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
79
+
80
+ static class Factory { //ファクトリパターン (Person の生成はこのクラスが行う)
81
+ private int id;
82
+ private String name;
83
+ private LocalDate birthday;
84
+ private Gender gender;
85
+
86
+ Factory setId(String id) {
87
+ this.id = Integer.parseInt(id);
88
+ return this; //自身を返すことで、呼び出し側が '.' で複数のメソッドを繋げて書けるようになる
89
+ }
90
+ Factory setName(String name) {
91
+ if(name == null) throw new NullPointerException();
92
+ this.name = name;
93
+ return this;
94
+ }
95
+ Factory setBirthday(String birthday) {
96
+ this.birthday = LocalDate.parse(birthday, formatter);
97
+ return this;
98
+ }
99
+ Factory setGender(String gender) {
100
+ this.gender = Gender.valueOf(gender);
101
+ return this;
102
+ }
103
+ Person create() {
104
+ return new Person(id, name, birthday, gender);
105
+ }
106
+ }
107
+
108
+ final int id; //final にすると変更出来なくなる
109
+ final String name;
110
+ final LocalDate birthday;
111
+ final Gender gender;
112
+
113
+ private Person(int id, String name, LocalDate birthday, Gender gender) { //Factory が生成する為 private
114
+ this.id = id;
115
+ this.name = name;
116
+ this.birthday = birthday;
117
+ this.gender = gender;
118
+ }
119
+
120
+ @Override
121
+ public String toString() { //表示用の文字列を自分で生成する
122
+ return String.join(",",""+id,name,birthday.format(formatter),""+gender);
123
+ }
124
+ }
125
+ }
126
+ ```
127
+ meibo.txt
128
+ ```plain
129
+ 57,田中,1999/11/11,Male
130
+ 25,山田,1970/03/12,Female
131
+ 33,伊藤,1989/05/01,Female
132
+ 49,斎藤,2000/01/12,Male
133
+ 50,杉山,2010/05/05,Male
134
+ 63,河井,1996/01/30,Female
135
+ 5,松田,1989/03/21,Male
136
+ ```
137
+ 実行結果
138
+ ```plain
139
+ 読み込み完了
140
+ ■ ソートせずに一覧表示
141
+ 57,田中,1999/11/11,Male
142
+ 25,山田,1970/03/12,Female
143
+ 33,伊藤,1989/05/01,Female
144
+ 49,斎藤,2000/01/12,Male
145
+ 50,杉山,2010/05/05,Male
146
+ 63,河井,1996/01/30,Female
147
+ 5,松田,1989/03/21,Male
148
+ ■ IDでソートし一覧表示
149
+ 5,松田,1989/03/21,Male
150
+ 25,山田,1970/03/12,Female
151
+ 33,伊藤,1989/05/01,Female
152
+ 49,斎藤,2000/01/12,Male
153
+ 50,杉山,2010/05/05,Male
154
+ 57,田中,1999/11/11,Male
155
+ 63,河井,1996/01/30,Female
156
+ ```