2

I want to design a framework which developers will be able to subclass, plug in a single method and have it fit into the rest of my processing framework as a result. The method they implement gives them a Kafka message and they do whatever logic is required to produce a DomainReportItem object which they return. The rest of my framework schedules, queues, publishes batches of these items and I want them to have no way to tap into that, manipulate it or do things manually.

The problem is my implementation exposes an abstract class which they have to subclass and implement one abstract method. This is all fine.

The only catch is that the Abstract class functionality depends on a lot of DI objects which get passed via constructor. Of course when the developer subclasses it, they have to pass these items into their own constructor and call base(DI params)

Having the DI objects would allow them to manipulate things manually and send submissions themselves which I don't want.

What is the best way to handle this? The only way I could think of was to design some sort of builder factory where you pass it a delegate method that implements the required functionality and it gives you an object back. So it handles the construction of the objects itself, keeps it private from users and plugs in the DI objects within the black box. Inserts the delegate functionality that the developer supplies into the abstract method reference and passes back a built item.

But I'm not entirely sure what pattern or how to build such a factory. Does anyone have a link or explanation of how to do this?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
NZJames
  • 4,963
  • 15
  • 50
  • 100

1 Answers1

0

When you hit a situation like this, go back to the #1 rule - always prefer composition over inheritance.

You're creating a class with too many responsibilities. You really just need a way to ensure your consumers write custom conversions from Kafka message to DomainReportItem - which is completely independent from sending submissions or manipulating reports. Those shouldn't go in the same class.

I don't know the details of the use case or application architecture, but the Strategy Pattern may make your life much easier. Your class can take a IMessageConversionStrategy (or whatever you want to call it) as a method parameter. It can read from the queue, call the conversion strategy to get back a DomainReportItem, then go on processing. Then consumers can implement that interface wherever and however they want.

Community
  • 1
  • 1
Tim Copenhaver
  • 3,282
  • 13
  • 18