swift 听筒模式_Swift中的“工厂方法”模式

swift 听筒模式

定义 (Definition)

‘Factory Method’ pattern is a creational design pattern that abstracts the instantiation process. Creational pattern controls who creates an object and what/how/when it gets created.

“工厂方法”模式 是一种抽象化实例化过程的创新设计模式。 创建模式控制谁创建对象以及创建对象的方式/方式/时间。

The ‘Factory Method’ pattern defines an interface for creating an object and delegates the object creation to subclasses.

“工厂方法”模式定义用于创建对象的接口,并将对象创建委托给子类。

我们什么时候应该使用这种模式? (When should we use this pattern?)

提供用于创建对象的接口 (To provide an interface for creating an object)

This pattern should be used when we have a lot of different objects that we use in different ways. Their instantiations might be complex and need computations in order to create them. The ‘Factory Method’ pattern encapsulates their instantiations in order to simplify their creations across places.

当我们有许多不同方式使用的不同对象时,应使用此模式。 它们的实例化可能很复杂,需要进行计算才能创建它们。 “工厂方法”模式封装了它们的实例化,以简化跨位置的创建。

定义单个实例化位置 (To define a single place for instantiation)

This pattern should be used when a class cannot anticipate the type of objects it needs to create️. If we have an object that is already doing what we need, we have to reuse and instantiate it somewhere in the code. Moving these instantiations, from the client class to an interface, make the class depends on abstraction and does not make it depend on low-level components (Dependency Inversion Principle). This interface, called the factory method, has the logic to determine which type of object we need to instantiate. Moreover, delegating the creation logic to a subclass avoids code duplication and provides a single place for maintenance.

当类无法预期需要创建的对象类型时,应使用此模式。 如果我们有一个已经在做我们需要的对象,我们就必须在代码中的某个地方重用并实例化它。 将这些实例化从客户端类移动到接口,使该类依赖于抽象而不是依赖于低级组件(“ 依赖关系反转原理”)。 这个称为工厂方法的接口具有确定我们需要实例化的对象类型的逻辑。 此外,将创建逻辑委托给子类可以避免代码重复,并为维护提供了一个单一的场所。

使对象的实现与其使用脱钩 (To decouple the implementation of an object from its use)

This pattern should be used when the creation logic and instantiations are done by the client. A client is tightly coupled to an object if its type is used within its class. By moving the logic and instantiation of objects in a subclass, we protect the code from API changes. If some modifications are added to a concrete class and its API, the client code does not get impacted by changes it does not care about. By implementing an interface, the factory method returns an abstraction rather than a concrete type so we protect the code from implementation details.

当客户端完成创建逻辑和实例化时,应使用此模式。 如果客户端的类型在其类中使用,则客户端与该对象紧密耦合。 通过移动子类中对象的逻辑和实例化,我们可以保护代码免受API更改的影响。 如果对具体的类及其API添加了一些修改,则客户端代码不会受到其不关心的更改的影响。 通过实现接口,工厂方法将返回抽象而不是具体类型,因此我们可以保护代码免受实现细节的影响。

我们应该如何使用这种模式? (How should we use this pattern?)

Let’s start with a common approach of this pattern. In this example, we are working on a mobile app and we want to create a factory method responsible for creating UI components.

让我们从这种模式的常见方法开始。 在此示例中,我们正在开发一个移动应用程序,并且想要创建一个负责创建UI组件的工厂方法。

class ComponentFactory {
private init() {} static func createView(component: ComponentType) -> UIView {
switch component {
case .textfield:
let textfield = UITextField()
// textfield customatization...
return textfield case .switch:
let `switch` = UISwitch()
// `switch` customatization...
return `switch` case .button:
let button = UIButton()
// button customatization...
return button case .label:
let label = UILabel()
// label customatization...
return label case .image:
let image = UIImageView()
// image customatization...
return image
}
}
}

This first approach abstracts the detail implementations through an interface. The createView method, which is the factory method, takes a parameter that identifies the type of object to create. All of the created objects share a common UIView interface.

第一种方法通过接口抽象了详细的实现。 createView方法是工厂方法,它采用一个参数来标识要创建的对象的类型。 所有创建的对象共享一个公共的UIView接口。

However, this code only cares about the object creation, but not how to manage it. It means we cannot subclass and change the behavior of the createView method. This code is not an implementation of the ‘Factory Method’ pattern but of the Simple/Static Factory.

但是,此代码仅关心对象的创建,而不关心如何管理它。 这意味着我们不能继承并改变createView方法的行为。 此代码不是“工厂方法”模式的实现,而是简单/静态工厂的实现。

实作 (Implementation)

工厂方法 (Factory Method)

Let’s say, in our mobile app, we have different looking components depending on the player theme settings.

假设,在我们的移动应用中,根据播放器主题设置,我们具有外观不同的组件。

In order to create different behaviors of the createView method, we need to create an interface so many factory methods can be created with the desired behavior. Let’s create a layer of abstraction to implement subclasses.

为了创建createView方法的不同行为,我们需要创建一个接口,以便可以使用所需行为创建许多工厂方法。 让我们创建一个抽象层来实现子类。

protocol ComponentFactory {
func createView(component: ComponentType) -> UIView
}

In its settings, the player chooses to display components with the Disney world theme. Let’s build a factory method that is responsible for creating these components. To do so, we need to define a class that conforms to this interface:

在其设置中,播放器选择显示具有迪士尼世界主题的组件。 让我们构建一个负责创建这些组件的工厂方法。 为此,我们需要定义一个符合该接口的类:

class DisneyComponentFactory: ComponentFactory {
func createView(component: ComponentType) -> UIView {
switch component {
case .textfield: return DisneyTextField()
case .switch: return DisneySwitch()
case .button: return DisneyButton()
case .label: return DisneyLabel()
case .image: return DisneyImageView()
}
}
}

“工厂方法” UML图 (‘Factory Method’ UML Diagram)

Image for post

The key elements in this diagram are the ComponentFactory and UIView abstractions. The client has to subclass them in order to create components. In our example, we create the DisneyComponentFactory subclass which is responsible for creating Disney specific components. The ‘Factory Method’ pattern allows the client to only know about an interface, but it instantiates concrete classes. So, the client does not make the decision for the object it needs to create, but the factory method does.

该图中的关键元素是ComponentFactory和UIView抽象。 客户必须对它们进行子类化才能创建组件。 在我们的示例中,我们创建了DisneyComponentFactory子类,该子类负责创建迪士尼特定的组件。 “工厂方法”模式允许客户端只知道一个接口,但是它实例化了具体的类。 因此,客户端不会为需要创建的对象做出决定,但是工厂方法会做出决定。

在操场上运行代码 (Run code in a Playground)

Here is an Online Swift Playground so an Xcode Playground does not have to be created in order to test this implementation of the ‘Factory Method’ pattern. Then, copy the code below that corresponds with the full implementation of the ‘Factory Method’ pattern for our mobile app with Disney components.

这是一个在线Swift游乐场,因此不必为了测试“工厂方法”模式的实现而创建Xcode游乐场。 然后,复制下面的代码,该代码与带有迪士尼组件的移动应用程序的“工厂方法”模式的完整实现相对应。

// ‼️ This online playground is platform agnostic, so we need to declare a UIView interface and its subclasses.
protocol
UIView {}class UITextField: UIView {}class UISwitch: UIView {}class UIButton: UIView {}class UILabel: UIView {}class UIImageView: UIView {}class DisneyTextField: UITextField {}class DisneySwitch: UISwitch {}class DisneyButton: UIButton {}class DisneyLabel: UILabel {}class DisneyImageView: UIImageView {}enum ComponentType {
case textfield
case `switch`
case button
case label
case image
}protocol ComponentFactory {
func createView(component: ComponentType) -> UIView
}class DisneyComponentFactory: ComponentFactory {
func createView(component: ComponentType) -> UIView {
switch component {
case .textfield:
print("DisneyTextField created")
return DisneyTextField() case .switch:
print("DisneySwitch created")
return DisneySwitch() case .button:
print("DisneyButton created")
return DisneyButton() case .label:
print("DisneyLabel created")
return DisneyLabel() case .image:
print("DisneyImageView created")
return DisneyImageView()
}
}
}// Clientlet disneyFactory = DisneyComponentFactory()
disneyFactory.createView(component: .label)

Finally, paste and run the code.

最后,粘贴并运行代码。

翻译自: https://levelup.gitconnected.com/factory-method-pattern-in-swift-1f1b73488072

swift 听筒模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值