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?

  • 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. – Vincent Savard Jun 21 '18 at 16:58
  • @VincentSavard edited to include an example – TheCatWhisperer Jun 21 '18 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. – TheCatWhisperer Jun 21 '18 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. – Vincent Savard Jun 21 '18 at 17:26
  • The second one is a factory method, the class is incidental. – immibis Jun 22 '18 at 2:42
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.

  • 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 – TheCatWhisperer Jun 21 '18 at 17:55
  • 1
    So really the challenge is how to reuse "use case" code, and the validation logic that goes in it. – Greg Burghardt Jun 21 '18 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? – TheCatWhisperer Jun 21 '18 at 18:18
  • 1
    Maybe the creation of the audit trail is its own use case? – Greg Burghardt Jun 21 '18 at 18:20
  • but it is an audit trail specific to the Widget it also creates the various widget parts – TheCatWhisperer Jun 21 '18 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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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