なぜそのようなお客様の責任の列挙子どもたちは、お客様のパターン?
-
22-08-2019 - |
質問
に基づくコードがその場で発音を確認することが、このお客様に必要な知の構造を訪れたオブジェコの子どもたち。このように見えるビット無骨ころがあった場合には、お客様思い続けていきたいという方のために作業の場合でも訪れ授業を修正しました。
しないといけないのではないか本物の質問は はそのパターンが列挙されるように訪れたコードではなく、お客様コードについて教えてください。
解決
お客様にオブジェクト は いかな構造のものです。大丈夫だよ。い っ 書専門の見直しを支援します。各タイプのものをお客様先番号は予約確認通知す。これによりお客様でも大人気でしたい、という。
います。一お客様がいpre-orderうためには以下のようなものがないのin-orderで、他のお客様が法だけでは葉ノード。お客様に授業をすることができこれらのものを必要とせずに変更、ツリークラスです。
知識の構造にもなう運用のお客様を行っています。場合、お客様に コマンド.の様子オブジェクトコマンドオブジェクトの訪問者がコマンドを起動し、各ものです。
したい場合についての簡単な操作を収集す各項目に関する法律するために使うことができるのコレクションを提供 反復子 います。お電話の機能は各物の反復子を与えます。
したい場合に対して繰り返し処理を実行するツリーのノードに様々な注文を、そのツリーが必要であると複数の反復子.処理を行いたい場合のノードにするために読み込んでしまうなどの既に支援する必要がありますの変更、ツリークラスです。
他のヒント
はい。訪問したオブジェクトは、(必要な子どもたちに、すなわちコール)列挙を行うことができます。これはまだ(実際には、のデザインパターンのビジターの初のサンプルがこのようん)「ビジター」パターンと呼ばれています。私の作っアップ例のスニペットます:
public void accept(Visitor visitor) {
for (Node n : children) {
n.accept(visitor);
}
}
注:子供たちを訪問し、我々はvisitor.visit(n);
を言うことはできません。これは、Javaが動的に(その引数の実行時のクラスに基づく)方法を選択していないためであるが、(その引数のコンパイル時の型によって)静的メソッドを選択します。
短い言葉で、私はVisitorパターンを列挙が行われている方法に直交することを考えます。それはまったくのいずれかの方法、または全く列挙を行うことができます。
私は、訪問者がで構成されて何の要素訪問した構造を知ることが必要であると思います。車はホイールやエンジンで構成されていることを知っていただきたいです。彼らはどのように組み合わせるかを正確に知るためには必要ではないですが、私は思います。次の例を考えてみましょう。インサイダーは、訪問したオブジェクト構造を知っているし、列挙自体が実行されます。アウトサイダーは、訪れたオブジェクトに及び代表者の列挙を知りません。
interface Visitable {
void accept(Visitor visitor);
}
class WorkingRoom implements Visitable {
public int number;
WorkingRoom(int number) {
this.number = number;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class BossRoom implements Visitable {
public String bossName;
BossRoom(String bossName) {
this.bossName = bossName;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
interface Visitor{
void visit(WorkingRoom workingRoom);
void visit(BossRoom bossRoom);
void visit(Office office);
}
class Office implements Visitable{
public Visitable[] firstFloor;
public Visitable[] secondFloor;
public Visitable ceoRoom;
public Office(){
firstFloor = new Visitable[]{ new WorkingRoom(101),
new WorkingRoom(102),
new BossRoom("Jeff Atwood"),
new WorkingRoom(103)};
secondFloor = new Visitable[]{ new WorkingRoom(201),
new WorkingRoom(202),
new BossRoom("Joel Spolsky")};
ceoRoom = new BossRoom("Bill Gates");
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void showMeTheOffice(Visitor visitor, boolean sayPlease) {
// Office manager decides the order in which rooms are visited
for(int i=secondFloor.length-1; i >= 0; i--){
secondFloor[i].accept(visitor);
}
if (sayPlease){
ceoRoom.accept(visitor);
}
for (int i = 0; i < firstFloor.length; i++) {
firstFloor[i].accept(visitor);
}
}
}
class Insider implements Visitor{
public void visit(WorkingRoom workingRoom) {
System.out.println("I> This is working room #"+workingRoom.number);
}
public void visit(BossRoom bossRoom) {
System.out.println("I> Hi, "+bossRoom.bossName);
}
public void visit(Office office) {
// I know about office structure, so I'll just go to the 1st floor
for(int i=0;i<office.firstFloor.length;i++){
office.firstFloor[i].accept(this);
}
}
}
class Outsider implements Visitor{
public void visit(Office office) {
// I do not know about office structure, but I know they have a
// nice office manager
// I'll just ask to show me the office
office.showMeTheOffice(this, true);
}
public void visit(WorkingRoom workingRoom) {
System.out.println("O> Wow, room #"+workingRoom.number);
}
public void visit(BossRoom bossRoom) {
System.out.println("O> Oh, look, this is "+bossRoom.bossName);
}
}
public class Main{
public static void main(String[] args) {
Office office = new Office(); // visited structure
// visitor who knows about office structure
Insider employee = new Insider();
office.accept(employee);
System.out.println();
// visitor who does not know about exact office structure
// but knows something else
Outsider candidate = new Outsider();
office.accept(candidate);
// no enumeration at all, but still a visitor pattern
Visitable v = new BossRoom("Linus Torvalds");
v.accept(candidate);
}
}
私はまったく列挙することなく、ビジターパターンの幅広い用途でプロジェクトを持っていました。我々は非常に多くの場合、我々は例えばDB、XMLへのエクスポートなどから、別の方法で負荷を、それをレンダリングし、フィールドの種類に基づいて異なることを行う必要があったなどStringField、NumberField、のように、それを実装する基本インタフェースフィールドと多くのクラスを持っていました。私たちは、フィールドインタフェースのメソッドを定義することができますが、それはそれはプロジェクトの一つ一つの機能と結合するだろう - 貧しいフィールドには、エクスポート、インポート、HTMLやRTFにレンダリングについて知っている必要があり、などを我々はまた、instanceofを使用しますが、可能で設定することができますフィールドのインターフェイスを実装するクラスは、時間の経過とともに変更され、新しいフィールドタイプを追加し、追加することを忘れすることが可能であった。
else if (field instanceof NewlyAddedFieldType) {...}
どこか。だから我々は、訪問者のパターンを使用することを決定し、それはのようだった。
Visitor v = new XMLExportVisitor(outputStream);
field.accept(v);
の任意のフィールドの実装は方法が要求されるように
void accept(FieldVisitor visitor)
私はフィールドインタフェースの新しい実装を追加する場合は、そして、私は何とかそれを実装する必要があります。通常、それは
visitor.visit(this);
ここで、これは、新たに追加されたクラスです。これは、追加するために私を強制的に
void visit(NewlyAddedClass visited);
私は、我々がすでに持っているすべてのFieldVisitorの実装でそれを実装可能FieldVisitorインターフェイスへ。だから私は、これの何かをするのを忘れた場合 - 私はコンパイルエラーを取得します。 この場合の列挙は、もしあれば、訪問した構造とビジターの外で行われました。しかし、私はまだVisitorパターンの有効なケースとしてそれについて考えます。 少しの実装が困難になってますが、使いやすくかつ安全であると起こっています。
階層Visitorパターンレベル。関連する議論ページは、訪問者やコンテナ内にある反復の引数を提示します。それはあなたが定期的にツリーを持っているとは異なる反復処理する必要がある場合は私には理にかなって外部イテレータを使用しての示唆を含んでます。
バックそれはレベルのシリーズを持っていたの私の oofRep訪問者のために探して訪問する異なるクラスのと同様の方法内の繰り返しを持っていた。
void
oofRepVisitor::VisitViewHeaders(oofRepBandList& inBands)
{
VisitBandList(inBands);
}
void
oofRepVisitor::VisitBandList(oofRepBandList& inBands)
{
EnterLevel();
const unsigned long numBands = inBands.count();
for (unsigned long i=0; i<numBands; i++) {
oofRepBand* theBand = inBands.value(i);
assert(theBand);
VisitTypedBand(theBand);
}
LeaveLevel();
}
オーバーライドと
void
OOF_repXMLlayoutVisitor::VisitViewHeaders(oofRepBandList& inBands)
{
oofRepStreamEnv::out() << mIdentities.getIndentString();
if (inBands.keepTogether())
oofRepStreamEnv::out() << "<header>\n";
else // default is ON, and simplifies XML
oofRepStreamEnv::out() << "<header keepTogether='false'>\n";
VisitBandList(inBands);
oofRepStreamEnv::out()
<< mIdentities.getIndentString()
<< "</header>\n";
}
この記事の中に説明を見てください。
ウィキでから:
オブジェクト指向プログラミングではと ソフトウェア工学、訪問者 デザインパターンは、分離の方法です オブジェクト構造からアルゴリズム それが動作する時に。実用的 この分離の結果は に新しい操作を追加する機能 既存のオブジェクト構造なし これらの構造を変更します。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example、 ビジターパターンを使用して役立ちます 開/閉に準拠 原則ます。