これは、コードの単純さとパフォーマンスに関係する設計上の問題です。
特定のユーザー ID の一連の値が 2 つのシステム間で同じであることを確認したいとします。ここでの例は、学生 ID がシステム A とシステム B で同じ数のコース登録を持っていることを確認することです。
このために、以下を作成します。
List<String> studentList = new ArrayList<String>();
Set<String> sysAEnrollments = new HashSet<String>();
Set<String> sysBEnrollments = new HashSet<String>();
private Map<String, String> badEnrollList = new HashMap<String, String>();
学生 ID のリスト (studentList) を指定して、適切に入力します。
studentList = getCurrentStudentList();
for (String id : studentList){
sysAEnrollments = getSysAEnrollments(id);
sysBEnrollments = getSysBEnrollments(id);
if (!sysAEnrollments.containsAll(sysBEnrollments)){
badEnrollList.put(id, getBadEnrollmentsById(id, sysAEnrollments, sysBEnrollments));
}
}
質問:メソッド「getBadEnrollmentsById」は何を返す必要がありますか?
単に印刷できるように、十分な意味を持つ連結された文字列のいずれかです。または、新しいオブジェクトを用意します。たとえば、コース ID のリストを持つ別のコレクションを作成します。このコレクションは、さらなる処理には使用できますが、印刷出力には使用するのが難しくなります。
明確さとパフォーマンスのために、予想されるすべてのオブジェクトを徹底的に設計するか、それらの一部を連結された文字列に置き換える価値がありますか?
ノート:
- システム A は信頼できるソースとして優先されます
- getBadEnrollmentsByIdからの出力には、すべてのコースが含まれている必要があり、システム B で不足しているコースにフラグを立てる必要があります。
提案された解決策: (2012-SEP-14)
編集 (2012-SEP-17): Course クラスを更新して、hashCode と equals を含めました
user351721 が提案したように、期待される結果/要件に一致する残りのオブジェクトのモデリングを続けました。わずかな変更が大きな違いをもたらし、この設計上の欠陥を調べて実装を完了することができました。
改訂されたコレクションは次のとおりです。
List<String> studentList = new ArrayList<String>();
Enrollment sysAEnrollments;
Enrollment sysBEnrollments;
Map<String, List<String>> badEnrollList = new HashMap<String, List<String>>();
そして、登録を入力します。
for (String id : studentList){
sysAEnrollments = getSysAEnrollments(id);
sysBEnrollments = getSysBEnrollments(id);
if (!sysAEnrollments.getCourses().containsAll(sysBEnrollments.getCourses())){
List<String> missingCourses = getProblemEnrollmentListById(id, sysAEnrollments, sysBEnrollments);
badEnrollList.put(id, missingCourses);
}
}
したがって、今のところ出力は、各 ArrayList を取得してコース名を出力することにより、badEnrollList から出力できます。* の付いたコース名は、sysB にないことを意味します。
登録クラスは次のようになります。
public class Enrollment {
private Set<Course> courses = new HashSet<Course>();
public void setCourses(Set<Course> courses){
this.courses = courses;
}
public Set<Course> getCourses(){
return this.courses;
}
}
Course クラスは次のようになりました。
public class Course {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
// Must override hashCode() and equals()
@Override
public boolean equals(Object o){
if (o == this)
return true;
if (!(o instanceof Course))
return false;
Course c = (Course) o;
return c.id.equals(this.id) && c.name.equals(this.name);
}
@Override
public int hashCode(){
// Magic numbers as shown on Joshua Bloch's book "Effective Java" 2nd Edition, p.48
int result = 17;
result = 31 * this.id.hashCode();
result = 31 * this.name.hashCode();
return result;
}
}
変更は微妙に見えるかもしれませんが、重要な手掛かりは、登録は文字列のコレクションではなく、登録はコースのコレクションであり、各コースには名前と可用性プロパティがあることです。それらは多くのことをしていないように見えますが、それらを使用することで、使用しているオブジェクトを定義し、これらのクラスを将来どのように再利用できるかを文書化しています。