2008年9月20日土曜日

Smalltalk ベストプラクティスパターンを読んでのメモ2

これの続き



Comparing Method


オブジェクト同士を並び替えたいときは比較用メソッドを定義しよう
メソッド名で le だと分かりにくい気もする。lessThanOrEqual のほうが良いか。。。
<=って書きたい。


class Event {

public function le($anEvent) {
return ($this->timestamp <= $anEvent->timestamp);
}

}



Reversing Method


メッセージの流れをスムーズに。
よくわからないけど


class Point {

public function printOn($asStream) {
$this->x->printOn($asStream);
$asStream->nextPutAll('@');
$this->y->printOn($asStream);
}

}


class Stream {
public function _print($anObject) {
$anObject->printOn($this);
}

}
class Point {
public function printOn($asStream) {
$asStream->print($this->x);
$asStream->nextPutAll('@');
$asStream->print($this->y);
}

}



Method Object

たくさんの引数や一時変数であふれているメソッドを単純化する。


class Obiligation{

public function sendTask($aTask, $aJob) {
//一時変数いっぱい
$notProcessed = null;
$processed = null;
$copied = null;
$executed = null;
// たくさんの処理
}
}



class Obiligation{

public function sendTask($aTask, $aJob) {
//一時変数いっぱい
$notProcessed = null;
$processed = null;
$copied = null;
$executed = null;
$this->prepareTask($aTask, $aJob, $notProcessed, $processed, $copied, $executed);
}

public function prepareTask($aTask, $aJob, $notProcessed, $processed, $copied, $executed){
//ComposedMethodで処理を請け負うと引数が多くなりすぎ、コード量の削減にもならない
}
}



class TaskSender{
private $obiligation;
private $task;
private $job;
private $notProcessed;
private $processed;
private $copied;
private $executed;

public function __construct($anObiligation, $aTask, $aJob) {
$this->obiligation = $anObiligation;
$this->task = $aTask;
$this->job = $aJob;
}
public function compute(){
//ここにたくさんの処理。
}
}

class Obiligation{

public function sendTask($aTask, $aJob) {
$taskSender = new TaskSender($this, $aTask, $aJob);
$taskSender->compute();
}
}



Execute Around Method

続けて実行しなければならないアクションのペアを表現

class Cursor {
public function showWhite($aBlock) {
$old = null;
$old = Cursor::currentCursor();
$this->show();
$aBlock->value();
$old->show();
}
}

class File{
public function openDuring($aBlock) {
$this->open();
$aBlock->value();
$this->close();
}

}


class File{
public function openDuring($aBlock) {
$this->open();
try{
$aBlock->value();
}catch(Exception $e){
//更に例外を投げるならその前に$this->close()をする。
}
$this->close();
}
}



Debug Printing Method

デバッグ用のメッセージを出力する。


class Association{
public function printOn($asStream) {
$asStream->print($this->key);
$asStream->nextPutAll('->');
$asStream->print($this->value);
}
}


Method Comment
メソッドのコメントの書き方

メソッドの先頭にコメントを書き、コードから明白に読み取れない重要な
情報を伝える。

2008年9月15日月曜日

Smalltalk ベストプラクティスパターンを読んでのメモ1



PHPで書いてみる。

3 振る舞い
3.1 メソッド

ComposedMethod


1つのことのみするメソッドに分割しよう。


class Controller{
public function controlActivity() {
$this->controlInitialize();
$this->controlLoop();
$this->controlTerminate();
}
public function controlInitialize(){
//初期化
}
public function controlLoop(){
//ループ処理
}
public function controlTerminate(){
//切断
}
}


Constructor Method

インスタンス生成時にいろいろな引数を渡したいときは適切に作ってくれる
メソッドを用意しよう。


class Point{
public function __construct($x, $y){
// .....
}
public function Polar($r, $theta) {
$x = $r * cos(deg2rad($theta));
$y = $r * sin(deg2rad($theta));
new self($x, $y);
}
}

new Point(1, 1);

Point::Polar(sqrt(2), 45);


Constructor Parameter Method

インスタンス変数を一度に設定するメソッドを定義しよう


class Point {
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
}



class Point {
public function __construct($x, $y) {
$this->_setXY($x, $y);
}
private function _setXY($x, $y) {
$this->x = $x;
$this->y = $y;
}
}




Shortcut Constructor Method
ショートカットメソッドを定義しよう

こんな感じ?


class Number {
public function __construct($x) {
$this->x = $x;
}
public function getPoint($y){
return new Point($this->x , $y);
}
}

$number = new Number(1);
$point = $number->getPoint(2);



Conversion

オブジェクトのプロトコルを増やすのではなく、別のオブジェクトに変換しよう

Converter Method

オブジェクトを同一プロトコルのオブジェクトに変換するメソッドを用意しよう
メソッド名はasXXXとする。

こんな感じ?微妙・・・

class Collection {
private $collection = array();
public function __construct(array $array = array()){
$this->collection = $array;
}
public function asSet() {
return array_unique($this->collection);
}
}

class Number {
public function __construct($x){
$this->x = (int)$x;
}
public function asFloat() {
return (float)$this->x;
}
}



Converter Constructor Method

変換もとのオブジェクトを引数として受け取りインスタンスを生成しよう


Query Method
真偽値を返すメソッドを用意しよう。メソッド名はisXXXとする。


class SwitchClass {
public function makeOn() {
$this->status = 'on';
}
public function makeOff() {
$this->status = 'off';
}
public function status() {
return $this->status;
}
}

class WallPlate{
public function __construct(){
$this->switch = new SwitchClass();
$this->lignt = new Light();
}
public function update() {
if($this->switch->status == 'on'){
$this->lignt->makeOn();
}elseif($this->switch->status == 'off'){
$this->lignt->makeOff();
}
}
}




class SwitchClass {
public function makeOn() {
$this->status = 'on';
}
public function makeOff() {
$this->status = 'off';
}
public function status() {
return $this->status;
}
public function isOn() {
$this->status == 'on'' ? true : false;
}
}

class WallPlate{
public function __construct(){
$this->switch = new SwitchClass();
$this->lignt = new Light();
}
public function update() {
if($this->switch->isOn){
$this->lignt->makeOn();
}else{
$this->lignt->makeOff();
}
}
}


続く

2008年9月7日日曜日

is_readable について

is_readable だと include_path を見てくれないようなので、以下の2つをつくって
どちらが早いか試してみた。isReadable は Zend_Loader での実装。



class readable {

public function test() {
$time1_s = microtime(true);
for($i = 0; $i < 2000; $i++ ){
self::isReadable('spyc/spyc.php5');
}
$time1_e = microtime(true);

$time2_s = microtime(true);
for($i = 0; $i < 2000; $i++ ){
self::isReadable2('spyc/spyc.php5');
}
$time2_e = microtime(true);

Zend_Debug::dump($time1_e - $time1_s);
Zend_Debug::dump($time2_e - $time2_s);
}

public static function isReadable($filename){
if (!$fh = @fopen($filename, 'r', true)) {
return false;
}
@fclose($fh);
return true;
}

public static function isReadable2($filename){
$ret = false;
$paths = explode(':',get_include_path());
foreach($paths as $path){
if(is_readable($path. '/' .$filename)){
$ret = true;
break;
}
}
return $ret;
}
}

※ get_include_path は . 以外に2つのディレクトリを返し、spyc/spyc.php5は最後のディレクトリに存在する。

1回目
float(1.2477900981903)

float(0.3044650554657)

2回目
float(1.3001132011414)

float(0.31661415100098)

3回目
float(1.3001132011414)

float(0.31661415100098)

と isReadable2 が圧勝。clearstatcache()を isReadable2 の中に追記しても+0.2秒程度。

2008年9月6日土曜日

週に一度、日曜日に自問すべき20の質問

やらなきゃいけないこととか、やらなくてもいいこととか、やりたいこととか
やったほうがいいこととか、いろいろあって、いろいろごちゃごちゃで最近すごく大変。

自分のキャパの狭さに唖然となりつつ、少しずつでも成長していかないとと。

で、今日ちょっと巡回してたらこんなエントリが

週に一度、日曜日に自問すべき20の質問



  1. 先週何を学んだか?
  2. 先週一番の達成は何か?
  3. 先週思い出に残った瞬間は?その理由は?
  4. ・・・・・・


とほかにもあり、全部で20個ちょっと。多いけど、ずっとこの内容を気にし続けるわけではなくて週一回のみだから続くかも。

といいつつ、多いと三日(3週?)坊主になりそうだったので、なやんでたけど、昔の記事で
以下のエントリがあったので、まずは7つから来週金曜から毎週にメールするように
Googleカレンダに登録てみました。

あなたの人生を変える、たった7つの魔法の質問



慣れてきたらいろいろ変更したり増やしたりしていこう。

2008年9月4日木曜日

独自ドメインに変更

独自ドメイン使えるのかなぁ?と調べたら意外と簡単に使えたので設定

まずはドメインの参照先を ghs.google.com. へ変更。
※なんか最後の「 . 」がポイント?

そのドメインのページを開いたときに Server Not Found になれば自分の環境ではOK
※ISPなどにより伝播の速度が違うので、場合によっては2,3日見たほうがいい

Blogger の設定 の「公開中」→ 「カスタムドメイン」 → 「アドバンス設定に切り替え」として、ドメインを入れて終了

GoogleAnalytics の設定変更とかできるのかなぁ・・・