40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

042-MVCのControllerの役割を見直す

エントリ情報をローカルにキャッシュすることは出来て、これで完成間近・・・と思ったのですが

「Aというブロガーは何ページ目まで読み込んだのか誰(=どのクラス)が管理するべき?」

という部分で疑問が出てきました。

Entryクラスは、エントリ情報を管理するモデルであるし、そのモデルの情報を受け取って、TitaniumのTableViewの生成をするのは、CreateTableViewクラスであるため、役割的にはこれら2つはふさわしくないように感じました。

そのため、MとVとハンドリングするControllerの役割を考え直す必要が出てきました。折角あと少しで完成という感じになっててき、少し後退する感じですがここで設計を見直すのは大切なように感じたので頑張って手直しすることにしました。

まずはテストコード

ちょっと思いついたのは

  • Entryクラスを経由して、エントリ情報をサーバから取得。その情報をTableViewに渡す
  • 現在何ページ目まで読み込んだのか確認できる
  • 未取得のエントリは当然ローカルにキャッシュしてないためその判定

という感じだったので、こんな感じのテストを考えました

Ti.include('controller/entry.js');

module("Controller");


test("#2 should be handle",
  function(){
    var c = new Controller('hibi');
    c.init();
    var page = c.nextPage();
    equals(page,2);
  }
);

test("#4 page should be handle",
  function(){
    var c = new Controller('hibi');
    c.init();
    c.nextPage();
    c.nextPage();
    c.nextPage();
    var page = c.getCurrentPage();
    equals(page,4);
  }
);

test("handle Entry List",
  function(){
    var c = new Controller('hibi');
    var entry_list = {
      "0":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>\n\u672c\u65e5\u304b\u3089\u57f7\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "1":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>\n\u672c\u65e5\u304b\u3089\u57f7\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "2":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>\n\u672c\u65e5\u304b\u3089\u57f7\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "3":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>\n\u672c\u65e5\u304b\u3089\u57f7\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "4":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>\n\u672c\u65e5\u304b\u3089\u57f7\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      }

    };
    c.init();
    var result = c.receive(entry_list,c.pagenumber);
    equals(result.length,5);
  }
);

test("has Cached??",
  function(){
    var c = new Controller('hibi');
    var entry_list = {
      "0":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"</p>testtest<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "1":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "2":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "3":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"\u30a8\u30f3\u30c8\u30ea\u30fc",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>\n\u672c\u65e5\u304b\u3089\u57f7\u7b46\u3055\u305b\u3066\u9802\u304d\u307e\u3059\uff01</p>\n\n<p>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      },
      "4":{
	"permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
	"title":"IT",
	"html_body":"<p>\u306f\u3058\u3081\u307e\u3057\u3066\u3002<br>",
	"_id":"4d57ba74e93ac1e360000001",
	"blogger":"hibi"
      }

    };
    c.init();
    /*
     ローカルへのキャッシュはEntryクラスのsaveCache()を
     通じて行う
     まだ読み込んでいないページ数(仮に10)を引数にして
     Contoller::receiveを呼び出した場合にはhasCached()
     はfalseになるはず
     */
    var page = 10;
    var result = c.receive(entry_list,10);
    equals(c.hasCached(),false);
  }
);

実際のコードはこんな感じ

Titanium.include(Titanium.App.appURLToPath("app://model/entry.js"));
Titanium.include(Titanium.App.appURLToPath("app://view/styles.js"));
Titanium.include(Titanium.App.appURLToPath("app://view/create_table_view.js"));


Controller = function(blogger){
  this.blogger = blogger;
  this.table_view = new CreateTableView();
  this.entry = new Entry(this.blogger);
  this.page_number = 1; // スタートページとして初期値で1を設定
};

Controller.prototype = {
  init:function(){
    this.entry.getEntry(this.page_number);
    return true;
  },
  getCurrentPage:function(){
    return this.page_number;
  },
  nextPage:function(){
    this.page_number++;
    return this.page_number;
  },
  receive:function(entryList,current_page){
    /*
     エントリ情報の一覧を受取った後、現在何ページ目まで
     読み込んだのか後でハンドリングできるように処理を実施
     */
    this.page_number = current_page;
    var entries = this.table_view.make(entryList);
    return entries;
    //this.table_view.setData(entries);
  },
  tableViewSetData:function(data){
    return this.table_view.setData(data);
  },
  hasCached:function(){
    var flag = null;
    var fileName = this.blogger + this.page_number + ".json";
    var file_path = Titanium.Filesystem.resourcesDirectory
	+ '/cache/'
	+ fileName;
    var file  = Titanium.Filesystem.getFile(file_path);
    if(file.exists()){
      flag = true;
    } else {
      flag = false;
    }
    return flag;
  }
};

色々考えながらやっていて、ちょっと整理付いてない部分があるから明日以降、もう一回熟考しようかと思います