Swift中的通用飞锤模式

Swift中的通用飞锤模式,swift,flyweight-pattern,Swift,Flyweight Pattern,我正在尝试在Swift中实现一个通用的flyweight模式。在我的代码中,我使用弱引用字典来表示弱引用。基本协议(节点)只有一个位置。更改位置将创建一个新的节点 我在网上看到的实现在不再有任何对给定flyweight的引用时不会试图清理问题 符合节点的类可以使用维护现有对象字典的工厂选择加入flyweighting 当一个值被释放时,散列函数会发生变化(请参见Weak.hash(into:))。那会破坏一切吗 在deinit中取消这些值的所有权并以某种方式将其从工厂中删除是否更好?我可以用一

我正在尝试在Swift中实现一个通用的flyweight模式。在我的代码中,我使用弱引用字典来表示弱引用。基本协议(
节点
)只有一个位置。更改位置将创建一个新的
节点

我在网上看到的实现在不再有任何对给定flyweight的引用时不会试图清理问题

符合
节点
的类可以使用维护现有对象字典的
工厂
选择加入flyweighting

  • 当一个值被释放时,散列函数会发生变化(请参见
    Weak.hash(into:)
    )。那会破坏一切吗
  • deinit
    中取消这些值的所有权并以某种方式将其从工厂中删除是否更好?我可以用一般的方法吗
  • 不能在协议类型上使用标识运算符
    ==
    。我能在考试中绕过这个问题吗
  • 有没有更简单的方法
完整的操场代码

import Foundation

protocol Node {
    // Immutable: changing the position returns a new node
    func position(_ p:CGPoint) -> Node
    func printAddress()
}

protocol HashableNode : class, Hashable, Node { }

struct Weak<T : HashableNode> : Hashable {
    static func == (lhs: Weak<T>, rhs: Weak<T>) -> Bool {
        return lhs.value == rhs.value
    }

    weak var value : T?

    func hash(into hasher: inout Hasher) {
        value?.hash(into: &hasher)
    }
}

class Factory<T:HashableNode> {
    var values = [Weak<T> : Weak<T>]()

    func make(_ proto: T) -> T {
        let w = Weak<T>(value: proto)
        if let v = values[w] {
            if let r = v.value {
                return r
            }
        }
        values[w] = w
        return proto
    }
}

class TestNode : HashableNode {

    deinit {
        print("TestNode deinit")
    }

    // Can I define equality and hash automatically?
    static func == (lhs: TestNode, rhs: TestNode) -> Bool {
        return lhs.p == rhs.p
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(p.x)
        hasher.combine(p.y)
    }


    let p:CGPoint

    init(p: CGPoint) {
        print("TestNode init")
        self.p = p
    }

    func position(_ p: CGPoint) -> Node {
        return testNodeFactory.make(TestNode(p: p))
    }

    func printAddress() {
        print(Unmanaged.passUnretained(self).toOpaque())
    }

}

let testNodeFactory = Factory<TestNode>()

func runTest() {

    let n0 = testNodeFactory.make(TestNode(p: CGPoint.zero))
    let n1 = testNodeFactory.make(TestNode(p: CGPoint.zero))

    assert(n0 === n1)

    n0.printAddress()
    n1.printAddress()

    let n2 = n0.position(CGPoint(x: 1, y: 1))

    n2.printAddress()

    // Doesn't compile:
    // Binary operator '!==' cannot be applied to operands of type 'Node' and 'TestNode'
    // assert(n2 !== n0)

}

runTest()
print("done!")

<代码>导入基础 协议节点{ //不可变:更改位置将返回一个新节点 func位置(p:CGPoint)->节点 func printAddress() } 协议HashableNode:类,Hashable,节点{} 结构弱:可散列{ 静态函数==(左:弱,右:弱)->Bool{ 返回lhs.value==rhs.value } 弱var值:T? func散列(放入散列程序:inout散列程序){ 值?.hash(放入:&hasher) } } 阶级工厂{ var值=[弱:弱]() func make(u-proto:T)->T{ 设w=弱(值:proto) 如果设v=值[w]{ 如果让r=v.value{ 返回r } } 值[w]=w 返回原型 } } 类TestNode:HashableNode{ 脱硝{ 打印(“TestNode Denit”) } //我可以自动定义相等和散列吗? 静态函数==(lhs:TestNode,rhs:TestNode)->Bool{ 返回lhs.p==rhs.p } func散列(放入散列程序:inout散列程序){ 联合散列器(p.x) 联合收割机(p.y) } 设p:CGPoint 初始(p:CGPoint){ 打印(“TestNode init”) self.p=p } func位置(p:CGPoint)->节点{ 返回testNodeFactory.make(TestNode(p:p)) } func printAddress(){ 打印(Unmanaged.passUnretained(self.toOpaque()) } } 设testNodeFactory=Factory() func runTest(){ 设n0=testNodeFactory.make(TestNode(p:CGPoint.zero)) 设n1=testNodeFactory.make(TestNode(p:CGPoint.zero)) 断言(n0==n1) n0.printAddress() n1.打印地址() 设n2=n0位置(CGPoint(x:1,y:1)) n2.打印地址() //不编译: //二进制运算符“!==”不能应用于“Node”和“TestNode”类型的操作数 //断言(n2!==n0) } 运行测试() 打印(“完成!”) 此行:

let n2 = n0.position(CGPoint(x: 1, y: 1))
这里调用的position方法是返回一个
节点,而不是为
n1
n2
显式创建的
TestNode
。编译器不知道如何比较这两种类型


您可以为TestNodeNode实现
Comparable
,也可以将n2类型转换为TestNode

我担心会出现yeilds错误:类型“TestNode”不符合协议“Node”是的,我只是回来更改这个。我相信你会有“添加为”?将TestNode添加到值分配。很抱歉,我现在不在电脑旁。很高兴我能帮忙!