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. Commented Jun 21, 2018 at 16:58
  • @VincentSavard edited to include an example Commented 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. Commented 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. Commented Jun 21, 2018 at 17:26
  • The second one is a factory method, the class is incidental. Commented 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 Commented 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. Commented 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? Commented Jun 21, 2018 at 18:18
  • 1
    Maybe the creation of the audit trail is its own use case? Commented Jun 21, 2018 at 18:20
  • but it is an audit trail specific to the Widget it also creates the various widget parts Commented 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? Commented Jun 21, 2018 at 16:56
  • I can't go into more detail without more details.
    – esoterik
    Commented Jun 21, 2018 at 16:59
  • added more detail to my question Commented Jun 21, 2018 at 17:19
  • Where would this initialization method go? Commented Jun 21, 2018 at 17:26

Your Answer

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

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