Swift:工厂模式,子类方法不可见

MaK*_*MaK 0 factory factory-pattern ios swift

我是Swift编程的新手,我在构建Factory设计模式方面遇到了阻碍.以下是我的代码:

protocol IInterface {
   func InterfaceMethod() -> Void
}

public class SubClass: IInterface {
   init() {}

   func InterfaceMethod() { }

   public func SubClassMethod() { }
}

public class Factory() {
    class func createFactory() -> IInterface {
         return SubClass()
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我试图像下面这样访问它

let mgr = Factory.createFactory()

//calling Interface Method
mgr.InterfaceMethod() -- This works, when i keep a dot (mgr.) it shows the method name
//calling subclass method
mgr.SubClassMethod() -- This doesn't work, when i keep a dot (mgr.) it doesnt even show the subclass method name
Run Code Online (Sandbox Code Playgroud)

即使我使用mgr.SubClassMethod它,也会引发错误说法

类型IInterface的值没有成员SubClassMethod

虽然SubClass对象是通过工厂返回的,但我相信我只能通过协议方法公开

我浏览和看过的所有示例都只显示了如何使用协议指定的方法,但我还没有看到一个示例,它显示了除了协议方法之外如何使用子类自己的方法

mix*_*xel 5

你错过了工厂模式的观点.Factory模式的思想是提供具有特定返回类型和返回实例的方法,这些实例具有此类型或从此类型继承(如果是class类型)或符合此类型(如果是protocol).

protocol Animal {
    func voice() -> String
}

class Dog: Animal {
    func voice() -> String {
        return "bark"
    }

    func sit() {
    }
}

class Cat: Animal {
    func voice() -> String {
        return "meow"
    }
}

class AnimalFactory {
    func getAnimal() -> Animal {
        return Dog()
    }
}
Run Code Online (Sandbox Code Playgroud)

客户端代码调用Factory方法不应该推测它的返回值并尝试将其强制转换为具体类.这完全破坏了使用Factory模式的重点.

正如您在上面的示例中看到的,AnimalFactory.getAnimal()返回符合Animal协议的某种类型的实例.调用此方法的代码不知道也不应该知道该实例的特定类型.

如果调用Factory方法的代码期望返回的实例具有类型Dog或从此类型继承,那么您应该创建并使用单独的DogFactory:

class EvilDog: Dog {
    override func voice() -> String {
        return "bark-bark"
    }
}

class DogFactory {
    func getDog() -> Dog {
        return EvilDog()
    }
}
Run Code Online (Sandbox Code Playgroud)

当客户端代码根据工厂方法返回的实例实例类型实现不同的行为时,您可能会遇到这种情况.在这种情况下, AnimalFactory应实现提供将在客户端代码中使用的所有类型的实例的方法:

class AnimalFactory {
    func getDog() -> Dog {
        return EvilDog()
    }

    func getCat() -> Cat {
        return Cat()
    }
}

func trainAnimal(iLikeDogs: Bool, animalFactory: AnimalFactory) {
    if iLikeDogs {
        let dog = animalFactory.getDog()
        dog.voice()
        dog.sit() // only dog can sit
    } else {
        let cat = animalFactory.getCat()
        cat.voice()
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上有三种模式 - 工厂,抽象工厂工厂方法.你可以在这里阅读差异.