[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends] JAVAオブジェクト設計第二章の別案




うーんかなり理解しにくくなったとは思いますが、読書会のお話しにあった別
構成案を投げます.
いろいろ省略してます.
仕様に関しては「JAVAオブジェクト設計」を見ないとわからないとは思います
が、動的にPassenger/Agent/AgentPassengerを切り替えられて、それらをPerson/
PersonRoleとして扱えて、新たな役割の追加時に既存クラスの書き換えがいら
ないものです.
(新しい役割のinterfaceとその実装classを加えれば良い)
読書会ではDecoratorパターンと言ってしまってましたが、Decoratorパターン
とは目的が異なっているのでデザインパターンのDecoratorパターンとは違い
ます.

テストしてないので完全じゃないかもしれませんが、分かりにくいところは一
応説明出来ると思いますので、ご指摘ください.
自分ではPeterさんの設計より良いと思ってます.
Peterさんの設計より悪いところは、Personの機能拡張時にPersonDecoraterも
書き換えないといけないところですが、それ以上にDecoratorサブクラス達を
Personとして扱えることの方が大きいと思っています.


class Address {
	:
}

// 役割の定義部分
interface Person {
	String getName();
	Address getAddress();
}

interface PersonRole extends Person {
	int getNumber();
}

interface Agent extends PersonRole {
	String getPassword();
	boolean isAuthorized();
}

interface Passenger extends PersonRole {
	int REGULAR = 1;
	int GOLD = 2;
	int getType();
}

interface AgentPassenger extends Agent, Passenger {
}

// PersonのDecorator
// (デザインパターンのDecoratorとはちょっと意味的に違うな...)
// # つまり、デザインパターンの方はinterfaceにあるメソッドの拡張
// # だけど、こっちは新しいメソッドの追加だから.
abstract class PersonDecorator implements PersonRole {
// Personを保持したいところだが、Decoratorは属性を持てないので
// PersonRoleを保持する(=ConcretePersonRoleを定義)
	protected PersonRole	personRole_;
	protected PersonDecorator(PersonRole personRole) {
		// Componentを保持
		personRole_ = personRole;
	}
	public String getName() {
		return personRole_.getName();
	}
	public Address getAddress() {
		return personRole_.getAddress();
	}
	public int getNumber() {
		return personRole_.getNumber();
	}
}

class ConcretePerson implements Person {
	// 適当なパラメタを取るコンストラクタをつけてもいい

	private String name_;
	public void setName(String name) {
		name_ = name;
	}
	public String getName() {
		return name_;
	}
	private Address address_;
	public void setAddress(Address address) {
		address_ = address;
	}
	public Address getAddress() {
		return address_;
	}
}

class ConcretePersonRole extends ConcretePerson implements PersonRole {
	private int number_;
	public int getNumber() {
		return number_;
	}
}

class ConcreteAgent extends PersonDecorator implements Agent {
	ConcreteAgent(PersonRole personRole) {
		super(personRole);
	}
	private String password_;
	public String getPassword() {
		return password_;
	}
	private boolean authorized_;
	public boolean isAuthorized() {
		return authorized_;
	}
}

class ConcretePassenger extends PersonDecorator implements Passenger {
	ConcretePassenger(PersonRole personRole) {
		super(personRole);
	}
	private int type_;
	public int getType() {
		return type_;
	}
}

// ConcretePassengerとどっちをextendsするかは実装負担を天秤に決める
class ConcreteAgentPassenger extends ConcreteAgent
						implements AgentPassenger {
	private Passenger passenger_;
	ConcreteAgentPassenger(PersonRole personRole) {
		super(personRole);
		// ConcretePassengerオブジェクトも作っとく
		// PersonDecoratorに属性を持たせないようにするのは
		// こういう使い方の時に属性が重複するから.
		passenger_ = new ConcretePassenger(personRole);
	}
	// この辺がミソですかね
	public int getType() {
		return passenger_.getType();
	}
}

--
Shin@イデア