Visitor

godo·2022년 8월 19일
0

Swift - Design Patterns

목록 보기
23/24

Intrusive Expressing Printing

protocol Expression
{
    func print(_ buffer: inout String)
}


class DoubleExpression: Expression
{
    private var value: Double
    init(_ value: Double)
    {
        self.value = value
    }
    
    func print(_ buffer: inout String)
    {
        buffer.append(String(value))
    }
    
}


class AdditionExpression: Expression
{
    private var left, right : Expression
    init(_ left: Expression, _ right: Expression)
    {
        self.left = left
        self.right = right
    }
    
    func print(_ buffer: inout String)
    {
        buffer.append("(")
        left.print(&buffer)
        buffer.append("+")
        right.print(&buffer)
        buffer.append(")")
    }
    
}


func main()
{
    // 1 + (2+3)
    let e = AdditionExpression(DoubleExpression(1),
                               AdditionExpression(DoubleExpression(2),
                                                  DoubleExpression(3)))
    
    var s = ""
    e.print(&s)
    print(s)


}

Reflection-Based Printing

class ExpressionPrinter
{

    func print(_ e: Expression, _ s: inout String)
    {
        if let de = e as? DoubleExpression
        {
            s.append(String(de.value))
        }
        
        else if let ae = e as? AdditionExpression
        {
            s.append("(")
            print(ae.left, &s)
            s.append("+")
            print(ae.right, &s)
            s.append(")")
        }
        
    }
    
}

Classic Visitor (Double Dispatch)

protocol Expression
{
    func accept(_ visitor: ExpressionVisitor)
    func print(_ buffer: inout String)
}


class DoubleExpression: Expression
{
    var value: Double
    init(_ value: Double)
    {
        self.value = value
    }
    
    func print(_ buffer: inout String)
    {
        buffer.append(String(value))
    }
    
    func accept(_ visitor: ExpressionVisitor) {
        visitor.visit(self)
    }
    
}


class AdditionExpression: Expression
{
    var left, right : Expression
    init(_ left: Expression, _ right: Expression)
    {
        self.left = left
        self.right = right
    }
    
    func print(_ buffer: inout String)
    {
        buffer.append("(")
        left.print(&buffer)
        buffer.append("+")
        right.print(&buffer)
        buffer.append(")")
    }
    
    func accept(_ visitor: ExpressionVisitor) {
        visitor.visit(self)
    }
    
}

protocol ExpressionVisitor
{
    func visit(_ de: DoubleExpression)
    func visit(_ ae: AdditionExpression)
}


class ExpressionPrinter: ExpressionVisitor, CustomStringConvertible
{
    private var buffer = ""
    
    func visit(_ de: DoubleExpression) {
        buffer.append(String(de.value))
    }
    
    func visit(_ ae: AdditionExpression) {
        buffer.append("(")
        ae.left.accept(self)
        buffer.append("+")
        ae.right.accept(self)
        buffer.append(")")
    }
    
    var description: String
    {
        return buffer
    }
}

class ExpressionCalculator: ExpressionVisitor
{

    
    var result = 0.0
    
    
    func visit(_ de: DoubleExpression)
    {
        result = de.value
    }
    
    
    func visit(_ ae: AdditionExpression)
    {
        ae.left.accept(self)
        let a = result
        ae.right.accept(self)
        let b = result
        result = a + b
    }
    
}


func main()
{
    // 1 + (2+3)
    let e = AdditionExpression(DoubleExpression(1),
                               AdditionExpression(DoubleExpression(2),
                                                  DoubleExpression(3)))
    
    let ep = ExpressionPrinter()
    ep.visit(e)
    print(ep)
    
    let calc = ExpressionCalculator()
    calc.visit(e)
    print("\(ep) = \(calc.result)")

}

profile
☀️☀️☀️

0개의 댓글