Pregunta

I am concerned about whether or not I am using FactoryMethod correctly.

Background:

I am refactoring legacy code and I have identified a pattern: there is a God Object that is created in memory, and later various parts of it is saved to many different tables. For example, various parts are called Selection, Design, Plot.

What I've done

I created a SelectionPersisterFactory that returns a SelectionPersister object, which is responsible for saving Selection to database.

Next step would be to create DesignPersisterFactory that returns DesignPersister, which saves Design to database.

But then I stopped myself and ask:

Question

Can I create a single PersisterFactory and have that return SelectionPersister, DesignPersister, PlotPersister, etc? from one single factory?

Pro/Con

  • "The Pro" will be that all of them are using the same repository and I can initialize that repository one time, instead of doing it for every new type of Persister

  • "The Con" is that I will be tasking the factory with creating different types of Persisters, but I am not sure if it's a necessarily a bad thing. i.e. I am not sure whether or not I'll be breaking SRP.

To clarify my title, "similar purpose" - objects are meant to persist something, "different in focus" - the persister objects focus on different parts of God object.

Goal / Use Case

Current situation is that I have the god object containing everything generated during "customer activity". That object is an in-memory object. It also permeates a lot of the codebase and is impractical to change on a moment's notice. It is not always nicely separated into its own distinct sub-components, although it tries.

The task at hand is "Save this session of customer activity (aka the god object) into the database". That includes saving:

  • User-Selected Items to table items
  • Plot generated from above items into table plot
  • Design object data from above items, into table design
  • and so on (just 1-2 more)

Why you think you need all these different persisters?

Different parts draw from different sections of the god object. Originally it was all procedural code just doing SQL statements doing all of the above DB saving, spanning 500+ some lines. I wanted to break it up into more manageable pieces, and came up with an idea "Let's separate saving different parts of god-object into separate methods". Since they are being persisted into the database, why not call them Persisters.

it would be worth to know if you have only a small fixed number of parts class

Yes I have a fixed number of parts classes, say 5 or 6. Different "customer activity" generates slightly different needs. So some sessions may have the need to persist 1 or 2 parts, some might need all 5. I do not anticipate the need to add more part classes, but rather aim to keep code simple.

¿Fue útil?

Solución

If you have a small, fixed number of different part types which will be seldom extended, you can keep this pragmatic and give your PersisterFactory a handful of different methods like CreateDesignPersister, CreatePlotPersister or CreateSelectionPersister. If each of those classes contains only a single persisting method, even that maybe overengineering, a generic "Persister" with three methods Save(Design d), Save(Selection s), SavePlot(Plot p) might be fine.

However, if your situation looks differently, and you have many different part types, and you want that list to be easily extendable, you might consider to switch to a more sophisticated design. First, consider if you really need different "Persister" logic for each part type, or if the persisting part cannot be implemented in a more generic fashion, by some kind of GenericPersister class which uses reflection (assumed you use a programming language which supports this) to persist whatever you pass to it.

If that is not possible or not worth the generalization effort, next thing you can try is to have a Persister class which uses the strategy pattern, providing a DesignPersisterStrategy, SelectionPersisterStrategy, and so on. There will be only one Persister object, holding the one and only one reference to your repository (or whatever resources you want to reuse). It will also provide a public Save method which will choose the correct strategy according to the type of the object passed, and then uses it to save the object correctly. So you reduce the number of needed classes from "3 * N" to "2 * N+1" (where N is the number of part types), without violating the SRP, and still sharing common resources.

Otros consejos

What you are decribing is a common design pattern, and, as @Robert commented, its name is abstract factory remember SRP means, that a entity must have only one reason to change not that it must only do one thing at all, or return only one type of result. So no, you are not breaking SRP.

Licenciado bajo: CC-BY-SA con atribución
scroll top