top | item 36642887

(no title)

andor | 2 years ago

Shape.getOfType(type) would also be a factory. A factory does not need to be a class, it can also just be a function.

I see two reasons for using a factory:

1. Reducing the scope of what a piece of code is responsible for (a.k.a. "Single-Responsibility-Principle").

Assume you are working on a graphics app that can draw 50 different shapes. The currently selected tool is stored in a variable, and there is a long switch statement that returns a new Shape depending on that variable. You wouldn't want the switch statement to dominate the rest of the code:

    handleClick(x, y) {
        selectedTool = getSelectedTool();

        shape = switch (selectedTool) {
            case "CIRCLE" -> new Circle();
            // 49 more lines here...
        }

        drawShape(shape, x, y);
    }
Not only would it get more difficult to read the code, but also the test for handleClick() would have to test for all 50 shapes. If the instantiation of the shape is separated out into its own function, handleClick() can be shorter. If the factory function is injectable, the tests for handleClick() can focus on the coordination work that the function does: it asks the factory for the shape and draws it in the right place.

2. Allowing to reconfigure what kind of objects are created through Dependency Injection. For instance:

    class CommentRepository {
        constructor(dataSource, queryFactory) { ... }

        getComments(articleId) {
            commentsQuery = queryFactory.getCommentsQuery(articleId);
            return dataSource.query(commentsQuery).map(toResponseType);
        }
    }

    class PostgresQueryFactory { ... }

    class RedisQueryFactory { ... }

discuss

order

winrid|2 years ago

Something has to map your click events to each of the button classes, and you have to test that code anyway. So I would just put that delegation in the Button class, I don't see the point in the extra abstraction to the factory yet. But to each their own I guess :)

winrid|2 years ago

Also the fact that you use the repository pattern, which I would absolutely never do even though I know it's fairly common, shows that we have different ideals (no offense). :)