Visitor tasarımı
- TypeScript kursu
- İleri seviye
- Ders 50/57
- 5 dk
AST ziyaretçisini visitor deseniyle yazarsın.
Visitor tasarımı
Visitor deseni, bir veri yapısını dolaşırken her düğüm türü için ayrı işlem yapmayı sağlar. AST ziyaretçisi, her düğüm türüne karşılık bir visit yöntemi içerir; traverse fonksiyonu düğümü alır ve uygun visit yöntemini çağırır.
interface Visitor {
visitNumber(value: number): void;
visitString(value: string): void;
visitAdd(): void;
}
function traverse(n: Node, v: Visitor): void {
switch (n.kind) {
case "number": v.visitNumber(n.value); break;
case "string": v.visitString(n.value); break;
case "add": v.visitAdd(); break;
}
}Traverse ile dolaşma
traverse fonksiyonu, AST'yi özyinelemeli olarak dolaşır. Her düğüm için ilgili visit yöntemi çağrılır; alt düğümler olan (örneğin add) düğümler için alt düğümler de dolaşılır. Bu, tüm ağacı işlemeyi sağlar.
function traverse(n: Node, v: Visitor): void {
switch (n.kind) {
case "number": v.visitNumber(n.value); break;
case "string": v.visitString(n.value); break;
case "add":
v.visitAdd();
traverse(n.left, v);
traverse(n.right, v);
break;
}
}Uygulama Visitor ile AST dolaş
Node discriminated union türünü tanımla ("number" (value: number), "string" (value: string), "add" (left: Node, right: Node)). Visitor interface'ini tanımla: visitNumber(value: number): void, visitString(value: string): void, visitAdd(): void yöntemleriyle. traverse(n: Node, v: Visitor): void fonksiyonunu switch ile yaz. Bir Visitor uygulaması oluştur: visitNumber console.log("n:" + value), visitString console.log("s:" + value), visitAdd console.log("add") yapsın. traverse({ kind: "add", left: { kind: "number", value: 1 }, right: { kind: "string", value: "x" } }, visitor) çağrısı yap.
Başlangıç kodu
// Node discriminated union türünü tanımla (kind: number, string, add)
// Visitor interface tanımla (visitNumber, visitString, visitAdd)
// traverse fonksiyonunu switch ile yaz
// Visitor uygulaması oluştur ve traverse çağırÖrnek çözüm
type Node =
| { kind: "number"; value: number }
| { kind: "string"; value: string }
| { kind: "add"; left: Node; right: Node };
interface Visitor {
visitNumber(value: number): void;
visitString(value: string): void;
visitAdd(): void;
}
function traverse(n: Node, v: Visitor): void {
switch (n.kind) {
case "number":
v.visitNumber(n.value);
break;
case "string":
v.visitString(n.value);
break;
case "add":
v.visitAdd();
traverse(n.left, v);
traverse(n.right, v);
break;
}
}
const visitor: Visitor = {
visitNumber: (value) => console.log("n:" + value),
visitString: (value) => console.log("s:" + value),
visitAdd: () => console.log("add"),
};
traverse({ kind: "add", left: { kind: "number", value: 1 }, right: { kind: "string", value: "x" } }, visitor);Beklenen çıktı
add n:1 s:x
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Visitor deseninin temel amacı nedir?
- Çalışma zamanı hatalarını gizlemek
- Düğüm türlerini birleştirmek
- Her düğüm türü için ayrı işlem yapmayı sağlamak Doğru cevap
- Düğümleri silmek
Açıklama: Visitor deseni, her düğüm türü için ayrı visit yöntemi tanımlar; traverse fonksiyonu düğüm türüne göre doğru yöntemi çağırır.
2 Visitor interface yöntemi
interface Visitor {
visitNumber(value: number): void;
visitString(value: string): void;
visit____(): void;
}
interface Visitor {
visitNumber(value: number): void;
visitString(value: string): void;
visitAdd(): void;
}
Açıklama: Visitor deseni her düğüm türü için ayrı visit yöntemi içerir; visitAdd add düğümü için çağrılır.
3 Visitor tasarımı parçaları
| Kavram | Anlamı |
|---|---|
Visitor interface |
visit yöntemleri |
traverse fonksiyonu |
ağacı dolaşır |
switch (n.kind) |
doğru visit'i çağırır |
özyinelemeli traverse |
alt düğümleri işler |