ロゴ

プログラミング初心者がアプリ開発を目指すブログ

検索機能を書きなおして柔軟な設計に – Javaでデスクトップトップアプリ(予定&ToDo管理)を作る-010

検索機能を書き直す

前回、UMLを書いて設計を見なおしたので
コードを直していきたいと思います。
具体的には、TaskPropetyクラスを書いてmatchメソッドを追加します。
UMLはこんな感じ
UML2
TaskPropetyにmatchメソッドが追加されています。

それでは、TaskPropertyクラスを書いていきます。
[TaskProperty.java]



public class TaskProperty {
  private Date date;
  private String category;
  private String context;
  private boolean whether;
  private boolean finish;
  private Date finishDate;
    TaskProperty(Date date,String category,String context){
      this.date=date;this.category=category;this.context=context;this.whether=true;
      this.finish=false;
      if(date==null){
        this.whether=false;this.finish=false;
      }
    }
    public Date getDate(){return date;}
    public String getCategory(){return category;}
    public String getContext(){return context;}
    public boolean getWhether(){return whether;}
    public boolean getFinish(){return finish;}
    public Date getFinishDate(){return finishDate;}
    public void setDate(Date d){this.date=d;this.whether=true;}
    public void setCategory(String c){this.category=c;}
    public void setContext(String c){this.context=c;}
    public void setWhether(boolean w){this.whether=w;}
    public void setFinish(boolean f,Date fd){this.finish=true;
    this.finishDate=fd;}
    
    public boolean match(TaskProperty otherProperty,Boolean startWeekFlag,
    Boolean endWeekFlag){
      if((otherProperty.category !=null) && 
        (!otherProperty.category.equals(""))&& 
        (!otherProperty.category.equals(this.category)))
        return false;
      if((otherProperty.context !=null) && 
        (!otherProperty.context.equals("")) && 
        (!otherProperty.context.equals(this.context)))
        return false;
      if((whether !=otherProperty.whether))
        return false;
      if((finish !=otherProperty.finish))
        return false;
      if(otherProperty.date != null){
        int y = otherProperty.date.getYear();
        int m = otherProperty.date.getMonth();
        int d = otherProperty.date.getDate();
        if(startWeekFlag){
          if(this.date == null)
            return false;
          if(!this.date.matchWeek(y, m, d))
            return false;
          }else{
            if(this.date == null)
              return false;
            if(!this.date.match(y, m, d))
              return false;
          }
        }
      if(otherProperty.finishDate != null){
        int y = otherProperty.finishDate.getYear();
        int m = otherProperty.finishDate.getMonth();
        int d = otherProperty.finishDate.getDate();
        if(startWeekFlag){
          if(this.finishDate == null)
            return false;
          if(!this.finishDate.matchWeek(y, m, d))
            return false;
          }else{
            if(this.finishDate == null)
              return false;
            if(!this.finishDate.match(y, m, d))
              return false;
          }
        }
      return true;
    }
}

これに合わせて、Boxクラス内のsearchメソッドを変更します。
[Box.java]


  ~今までのコード~
 public List search(TaskProperty searchProperty,Boolean startWeekFlag,Boolean endWeekFlag){
    List matchingTasks = new LinkedList();
    for(Iterator i = this.tasks.iterator(); i.hasNext();){
      Task task = (Task) i.next();
      if(task.getTaskProperty().match(searchProperty,startWeekFlag,endWeekFlag))
        matchingTasks.add(task);
    }
    return matchingTasks;
  }

searchメソッドにTaskPropertyを渡すようにしました。
実際の比較はTaskProperty内のmatchメソッドで行います、これでsearchメソッドはだいぶスッキリしましたね。

設計変更の効果について

「この設計の何がいいのか、ゴチャゴチャしてたのをTaskPropertyに入れただけじゃないか!」
なんて方もいらっしゃるかもしれませんので、この設計変更の効果についてまとめましょう。

一言でいうと、
「コードが柔軟になり変更への対応が容易になった」ということです。

例えば、Taskに繰り返し機能を追加しようと、repeatというフィールドを作ることを考えます。

以前までのコードだと、
Taskクラスを書き換えて、Boxクラス内のsearchメソッドを書き換えなければいけませんでした。つまり、一つの変更に対して、複数クラスの修正を行わなければなりません。
こういった事を放っておくと、修正に修正が重なりわけのわからないグチャグチャなコードになってしまいます。

新しいコードでは、TaskPropertyを書き換えれば修正は終わりです。フィールドを追加するクラスのメソッドだけを書き換えればいいのです。
これなら簡単に機能を拡張できますね。

というわけで、テストします。
[TaskPropertyTest.java]


import java.util.Calendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class TaskPropertyTest{
  public static void main(String[] args){
    Calendar calendar = Calendar.getInstance();
    Date today = new Date(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DATE));
    Date tomorrow = new Date(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DATE)+1);
    Date nextWeek = new Date(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DATE)+7);
    Date nextMonth = new Date(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH)+1,calendar.get(Calendar.DATE));
    
    Box box =new Box();
    box.addTask("取引先にメールを書く","打ち合わせのお礼メール",today,"仕事","オフィス");
    box.addTask("部屋の掃除","机まわりを綺麗に",tomorrow,"家の用事","家");
    box.addTask("コーヒー豆を買いに行く","ブラジルを200g",nextWeek,"趣味","");
    box.addTask("旅行に行く","海外旅行",nextMonth,"趣味","");
    box.addTask("ブログを書く","プログラミング記事",null,"趣味","");
    
    System.out.println("今日のタスクを検索,「取引先にメールを書く」が正解");
    TaskProperty match1= new TaskProperty(today,"","");
    List matchingTasks1 = box.search(match1,false,false);
    if(!matchingTasks1.isEmpty()){
      System.out.println("検索結果は、、、");
      for(Iterator i1 = matchingTasks1.iterator(); i1.hasNext();){
        Task task1 = (Task) i1.next();
        System.out.println(task1.getName());      
      }
    }else{
      System.out.println("検索条件に当てはまるものはありません");
    }
    System.out.println("今週のタスクを検索,「取引先にメールを書く」「部屋の掃除」が正解");
    TaskProperty match2= new TaskProperty(today,"","");
    List matchingTasks2 = box.search(match2,true,false);
    if(!matchingTasks2.isEmpty()){
      System.out.println("検索結果は、、、");
      for(Iterator i2 = matchingTasks2.iterator(); i2.hasNext();){
        Task task2 = (Task) i2.next();
        System.out.println(task2.getName());      
      }
    }else{
      System.out.println("検索条件に当てはまるものはありません");
    }
    System.out.println("趣味カテゴリーのタスクを検索,「コーヒー豆を買いに行く」
    「旅行に行く」「ブログを書く」が正解");
    TaskProperty match3= new TaskProperty(null,"趣味","");
    List matchingTasks3 = box.search(match3,false,false);
    if(!matchingTasks3.isEmpty()){
      System.out.println("検索結果は、、、");
      for(Iterator i3 = matchingTasks3.iterator(); i3.hasNext();){
        Task task3 = (Task) i3.next();
        System.out.println(task3.getName());      
      }
    }else{
      System.out.println("検索条件に当てはまるものはありません");
    }
  }
}

[実行結果]
java実行結果

無事に実行できました。

機能は前回からかわりませんが、中身はよくなっています。
しかし、TaskProperty内がグチャグチャしているのも事実です。
このことについてはまた次回取り上げていきましょう。

アプリ開発記の次の記事はこちら => Java HashMapを簡単に使いこなす! – Javaでデスクトップトップアプリ(予定&ToDo管理)を作る-011

スポンサード リンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA