This article is going to be a more casual conversation, which I think will be more interesting. In order to complete the dialogue, I decided to split myself into “wind sea” and “Gong”.

Feng Hai: Hello, Causeway, I hear you’ve been working on your file browser project?

Causeway: Yes, that’s right, still hard at work. I’ll tell everyone when I do. I don’t know what to tell you.

Fenghai: Hey, I have been learning about design patterns recently, and I saw the factory pattern. So I want to ask if you have used the factory pattern in your project.

Causeway: Well, actually, for a senior programmer, when developing software, I do not deliberately think about what patterns I will use to design what, but when encountering specific problems, I do not find a “natural” solution, and start to look for inspiration from design patterns… Well, anyway, speaking of factory mode, I did have a scene that I could use recently.

Wind sea: Oh oh? Tell me! Because I saw a lot of textbooks writing about the factory model, with the example of “creating shapes”, ah, for many college students, the factory model is equivalent to creating shapes, without richer case support, it is not deep to understand ah.

Gong: Yes, but “creating shapes” is a good example, since everyone understands it… Well, back to your question. You just asked me where I used the factory model in the development, this is quite a lot. I’ll just give you the code I’m writing right now. You know, I am writing a file manager, so since it is a file manager, naturally there is file open logic.

Fenghai: Right, so if I open an image file, then I go to the image view, if I open a video file, then it plays the video.

Gong: That’s right. For uniformity of design, I’ve adopted a consistent visual processing strategy for all file clicks in the File manager, navigating to a new interface, which I call FileViewerView. Also known as the file view interface.

Fenghai: So, the file viewer is a unified viewer, but the behavior of viewing is determined by the specific file type, right?

Gong: Oh, good, that’s right. So for image files, there is a “picture file viewer”, for video files, it is a “video file viewer”, and even according to the user’s own decision, any file viewing behavior can be turned into a “binary file viewer”.

Wind sea: that is to say, iron file viewer, water view type…… So how do you actually do that in code?

Causeway: Well, Show me the code. In this case, we need a “file viewer factory” to determine which viewer to produce. Here, here’s the initial code.

Since SwiftUI isn’t “typical” enough to introduce factory patterns, I’ve reworked the code here to UIKit instead.

import UIKit

class FileViewerController: UIViewController {}class FileViewerFactory {
    static let shared = FileViewerFactory(a)private init(a) {}
    
    func createView(filePath: String) -> FileViewerController? {
        nil}}Copy the code

Fenghai: Wow, it’s reassuring to see the code… Wait, your FileViewerFactory looks like a singleton, and speaking of singletons…

Causeway: Well, that’s true, but we’re talking about factory mode, focus, focus. In my case, the FileViewerFactory factory identifies the specific file type by passing in the file path, and returns the specific file viewer interface based on the file type. See, it’s natural to use the factory model here.

Fenghai: Yes, indeed, so the code to write in the end, if I pass in the file is an image file, how to write in your code implementation.

Causeway: Ok, so I’m going to go down, but I’m not going to write the complete code, you get the idea.

import UIKit

class FileViewerController: UIViewController {}class FileViewerFactory {
    static let shared = FileViewerFactory(a)private init(a) {}
    
    func createView(filePath: String) -> FileViewerController? {
        if isFilePicture(filePath) {
            return PictureFileViewerController(filePath)
        }
        return nil}}Copy the code

Sea of wind: YES! You get the idea. When we click on a file we need to invoke the file viewer interface, but we don’t know or care which interface we invoke, only that it’s an “interface.” (in this case, a UIViewController), and it’s up to the FileViewerFactory to decide which interface to generate.

Gong: Bingo! And you were right! In fact, the factory model is quite simple to understand, as long as activating the blood, can solve a lot of problems.

Fenghai: Well, in your code, the logical handler doesn’t care what viewer to invoke when clicking on a file, but at the very least it tells the factory that it should create a specific viewer for it.

Causeway: That’s right, the logical processor does not need to know exactly what viewer is being evoked, but it must provide the “necessary information” to the factory in the form of input parameters so that the factory can properly create the specific viewer. For example, if I develop a product that not only requires opening files to automatically select viewers, but also allows users to select some of their own viewers, we’ll need to change the parameters.

Wind sea: Oh oh, I might. Let’s say I want a binary viewer. Can I append an openWithBinary argument to createView?

Gong: You mean the code goes like this:

import UIKit

class FileViewerController: UIViewController {}class FileViewerFactory {
    static let shared = FileViewerFactory(a)private init(a) {}
    
    func createView(filePath: String.openWithBinary: Bool = false) -> FileViewerController? {
        if openWithBinary {
            return BinaryFileViewerController(filePath)
        }
        if isFilePicture(filePath) {
            return PictureFileViewerController(filePath)
        }
        return nil}}Copy the code

Yeah, yeah, nice. That does solve the problem. Of course, this is not extensible enough, for example, users may have a variety of options, such as text viewers as well as binary viewers… There are other circumstances that may not be supported, all of which should be taken into account. Of course, this requirement has nothing to do with the factory pattern itself, but is a matter of code design.

Wind sea: Aha. We’re not talking about the definition of the factory pattern, we’re talking about the project… But it feels like there is no wrong, at least after seeing the specific example of the concept.

Causeway: Indeed, it is much easier to read the form once the concept is understood. Ok, let’s read the definition of the factory pattern. (From Wikipedia)

Factory Method Pattern is an object-oriented design pattern that implements the concept of “Factory”. Like other creation patterns, it deals with the problem of creating objects without specifying their specific types. The essence of the factory method pattern is to “define an interface for creating an object, but let the class implementing the interface decide which class to instantiate. Factory methods defer class instantiation to subclasses.”

Sea of Winds: HMM… Really understand the case before looking at the concept, it seems to be better to understand a little bit.

Gong: Aha. Isn’t it. Wikipedia also explains this in a specific Java code.

// Several Button classes
class Button{/ *... * /}
class WinButton extends Button{/ *... * /}
class MacButton extends Button{/ *... * /}

// Their factory class
interface ButtonFactory{
    abstract Button createButton(a);
}
class WinButtonFactory implements ButtonFactory{
    Button createButton(a){
        return newWinButton(); }}class MacButtonFactory implements ButtonFactory{
    Button createButton(a){}}Copy the code

Fenghai: Yes, it is concise and to the point. In a word, I understand everything, but how well I use it in the actual project is another matter.

Causeway: So, it helps to think about the old and learn the new. It helps to ruminate on your own projects. You see, after talking to you, I felt like I had a whole new level of awareness.

Sea of wind: did it rise? How high?

Gong: HMM… Tall is very abstract, like three or four stories.

The wind sea:……………………… Well, that’s all we have to talk about today, otherwise we won’t get the code done.

Gong: Ah yeah yeah, ok, bye-bye.

Reference:

Wikipedia:zh.wikipedia.org/wiki/ Factory methods


Friends who want to discuss together can apply for adding group in the group menu bar of my public account Fenghai Causeway to complete adding group application, and make progress together.