-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Visitor | ||
アルゴリズムを操作対象のオブジェクトから分離できる動作設計パターン | ||
|
||
複雑なオブジェクト構造のすべての要素(オブジェクトツリーなど)に対して操作を実行する必要がある場合 | ||
|
||
### メリット | ||
- オープン/クローズド原則。クラスを変更せずに、異なるクラスのオブジェクトを操作できる新しい動作を導入できます。 | ||
- 単一責任の原則。同じ動作の複数のバージョンを同じクラスに移動できます。 | ||
- さまざまなオブジェクトを操作しているときに、いくつかの有用な情報を蓄積できます。オブジェクトツリーなどの複雑なオブジェクト構造をトラバースし、この構造の各オブジェクトにビジターを適用する場合に便利。 | ||
|
||
### デメリット | ||
- クラスが要素階層に追加または要素階層から削除されるたびに、すべてのVisitorを更新する必要があります。 | ||
- 作業することになっている要素のプライベートフィールドとメソッドへの必要なアクセスを欠いている可能性があります。 | ||
|
||
### 他パターンとの関係性 | ||
- Commandより強力 | ||
- Compositeツリー全体に操作を実行できる | ||
- Iteratorと一緒に使用して、複雑なデータ構造をトラバースし、その要素に対して何らかの操作を実行できる | ||
|
||
### 例題 | ||
- 実際に構造体を変更せずに、構造体に動作を追加できる | ||
- 次のlibをメンテナンスする場合 | ||
- 四角 | ||
- サークル | ||
- 三角形 | ||
- 共通の形状インターフェースを実装している | ||
|
||
- チームがgetAreaをshape構造体に追加するように要求 | ||
- これを解決するには3つ | ||
|
||
1. getAreaメソッドをshapeインターフェイスに直接追加してから、各shape構造体に実装する | ||
- コストが高い | ||
- 誰かが別の動作を要求するたびに貴重なコードを壊す可能性が高い | ||
2. 機能を要求するチームが自分で動作を実装できる | ||
- プライベートコードに依存する可能性があるため、これが常に可能であるとは限らない | ||
3. Visitorパターン | ||
- visitorインターフェイスの具体的な実装を定義し、その具体的な実装に面積計算ロジックを記述するだけ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package visitor | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
type areaCalculator struct { | ||
area int | ||
} | ||
|
||
func (a *areaCalculator) visitForSquare(s *square) { | ||
// Calculate area for square. | ||
// Then assign in to the area instance variable. | ||
fmt.Println("Calculating area for square") | ||
} | ||
|
||
func (a *areaCalculator) visitForCircle(s *circle) { | ||
fmt.Println("Calculating area for circle") | ||
} | ||
func (a *areaCalculator) visitForRectangle(s *rectangle) { | ||
fmt.Println("Calculating area for rectangle") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package visitor | ||
|
||
type circle struct { | ||
radius int | ||
} | ||
|
||
func (c *circle) accept(v visitor) { | ||
v.visitForCircle(c) | ||
} | ||
|
||
func (c *circle) getType() string { | ||
return "Circle" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package visitor | ||
|
||
import "fmt" | ||
|
||
type middleCoordinates struct { | ||
x int | ||
y int | ||
} | ||
|
||
func (a *middleCoordinates) visitForSquare(s *square) { | ||
// Calculate middle point coordinates for square. | ||
// Then assign in to the x and y instance variable. | ||
fmt.Println("Calculating middle point coordinates for square") | ||
} | ||
|
||
func (a *middleCoordinates) visitForCircle(c *circle) { | ||
fmt.Println("Calculating middle point coordinates for circle") | ||
} | ||
func (a *middleCoordinates) visitForRectangle(t *rectangle) { | ||
fmt.Println("Calculating middle point coordinates for rectangle") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package visitor | ||
|
||
type rectangle struct { | ||
l int | ||
b int | ||
} | ||
|
||
func (t *rectangle) accept(v visitor) { | ||
v.visitForRectangle(t) | ||
} | ||
|
||
func (t *rectangle) getType() string { | ||
return "rectangle" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package visitor | ||
|
||
type shape interface { | ||
getType() string | ||
accept(visitor) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package visitor | ||
|
||
type square struct { | ||
side int | ||
} | ||
|
||
func (s *square) accept(v visitor) { | ||
v.visitForSquare(s) | ||
} | ||
|
||
func (s *square) getType() string { | ||
return "Square" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package visitor | ||
|
||
import "fmt" | ||
|
||
type visitor interface { | ||
visitForSquare(*square) | ||
visitForCircle(*circle) | ||
visitForRectangle(*rectangle) | ||
} | ||
|
||
func main() { | ||
square := &square{side: 2} | ||
circle := &circle{radius: 3} | ||
rectangle := &rectangle{l: 2, b: 3} | ||
|
||
areaCalculator := &areaCalculator{} | ||
|
||
square.accept(areaCalculator) | ||
circle.accept(areaCalculator) | ||
rectangle.accept(areaCalculator) | ||
|
||
fmt.Println() | ||
middleCoordinates := &middleCoordinates{} | ||
square.accept(middleCoordinates) | ||
circle.accept(middleCoordinates) | ||
rectangle.accept(middleCoordinates) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package visitor | ||
|
||
import "testing" | ||
|
||
func TestVisitor(t *testing.T) { | ||
main() | ||
} |