1

In my current project, I find my self making factories, but for two very distinct reasons:

Reason #1: To assist my IoC container if a particular class needs an parameter that is only known when the class is created. This might also include reading data from a config. This kind of factory contains no business logic, only initialization logic.

Reason #2: The creation of an entity needs complex validation logic, and I want to keep this logic out of my constructor so it stays simple. This kind of factory is only about business logic around the creation of a new entity.

Furthermore, when I create a factory for reason #2, I find myself tempted to put deletion logic there as well, as the deletion of the entity is often complex and beyond the scope of the entity being deleted; however, one would be hard pressed to call a class with a deletion method a factory.

Reason #1 Example:

class WidgetRepositoryFactory
{
    IUserRepository Create(userType)
    {
         int configValue = int.Parse(Config.get("ConfigValue"));
         IUserRepository repo = userType == "user1" : new User1Repo(configValue) : new User2Repo(configValue);
         return repo;
    }
}

Reason #2 Example:

class WidgetFactory
{
     Result<Widget> Create(var1, var2)
     {
          Result r = new Result();
          if (var1 < 0)
          {
              r.AddError("var1 too low!");
              return r;
          }

          if (var1 > var2)
          {
              r.AddError("var1 too high!");
              return r;
          }

          r.Obj = new Widget(var1, var2);
          r.Success = true;
          return r;
     }
}

When I create a factory for reason #2, is it really correct to call it a factory? Is there a better term for this kind of class? Is there preexisting terminology to describe these two very distinct cases?

5
  • Do you have an example for your reason #2? I'm a bit curious as to why the deletion of an entity is complex. If you mean to delete it from a database, then what you describe is most likely not a factory, but a repository. Jun 21, 2018 at 16:58
  • @VincentSavard edited to include an example Jun 21, 2018 at 17:16
  • @VincentSavard the repository simply sends the delete command to the DB. However, there is delete logic which may not be appropriate for the repository layer. For example, do not allow a delete on a Widget which has been marked as an important widget. Jun 21, 2018 at 17:18
  • I think that would be the responsibility of either the Widget object, or whatever holds the Widgets and deletes them. I'm actually not too sure how you could fit this in a factory. Jun 21, 2018 at 17:26
  • The second one is a factory method, the class is incidental.
    – user253751
    Jun 22, 2018 at 2:42

2 Answers 2

1

When creating or deleting an entity, where the logic for both is non trivial, the code validating the conditions has more to do with a Use Case and should go in the layer of your application where use cases are handled.

For architectures similar to Onion Architecture, this would be the service layer.

5
  • Good answer. My application does actually make use of UseCases, but I thought that since multiple Use Cases might want to create an application, that validation logic should go below the use case level Jun 21, 2018 at 17:55
  • 1
    So really the challenge is how to reuse "use case" code, and the validation logic that goes in it. Jun 21, 2018 at 18:06
  • Indeed. I already have a CreateWidget use case, but it does more than just validation. It also manages laying down a proper audit trail, ect when an Widget is created. How would you go about sperating these two functions (if at all)? and how would you deal with the naming conflict? Jun 21, 2018 at 18:18
  • 1
    Maybe the creation of the audit trail is its own use case? Jun 21, 2018 at 18:20
  • but it is an audit trail specific to the Widget it also creates the various widget parts Jun 21, 2018 at 18:22
2

I find myself tempted to put deletion logic there as well

This is a sign that you should put validation logic into an initialize method; then you can control the deletion logic as well.

When I create a factory for reason #2, ...

Reason #2 may point else where; I think that this extra logic from reason #2 needs to be moved either into the class as another member or moved somewhere else, For example if you are reading a config, the validation may belong there.

is it really correct to call it a factory?

In your example I might call it a SpecialWidgetFactory; assuming this code doesn't belong in the caller.

4
  • Could you add a bit more detail? Jun 21, 2018 at 16:56
  • I can't go into more detail without more details.
    – esoterik
    Jun 21, 2018 at 16:59
  • added more detail to my question Jun 21, 2018 at 17:19
  • Where would this initialization method go? Jun 21, 2018 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.