[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@イデア