Home > Mobile >  Scala split large class into multiple files
Scala split large class into multiple files

Time:01-27

I have a class defined like:

trait BigService {
   def A
   def D
   def E
   /* etc */
}

class BigServiceImpl(...) extends BigService {
   def A = _

   private def B = _ // uses func A, and BigService's parameters

   private def C = _ // uses func B, and BigService's parameters

   def D = _ // uses func C, and BigService's parameters

   /* other members */
}

I'd like to move the private members into a separate file, but the problem is that they all depend on each other and the parameters/other members of the large class.

Is there any way to separate the class into multiple parts?

CodePudding user response:

I'm sure it's possible to split and refactor any code, but the question is very abstract so it's hard to offer any specific advice. So here are a few principles you can employ.

Composition vs Inheritance. Let's say your BigService is the actual business service class that uses some Database, WebService/API, etc. You can use composition to add these components to your service instead of inheriting them all from different classes.

Consider reversing function dependencies. Usually public method would depend on private methods, not the other way around. This will probably be the key for you. Extract many small methods that have single purpose and then you'll be able to see how to move them out with their dependencies to a different class. Tangentially keep in mind Inversion of Control.

Use Higher Order Functions to decouple behavior from implementation. If private def B uses function A and some class members you can express it as HOF: def B(functionA: (...) => ..., someArg: T) or similar.

Scala gives you power of OOP and FP so you can leverage both to refactor. They key is to understand underlying function types: what depends on what. You reduce dependencies significantly if you make function pure, single purpose and generic.

Cake Pattern is a debatable approach, but it might fit your needs. You mix in implementations of all those functions and keep dependencies abstract in the base traits.

I can go on and on but the main point is to try to structure your code in more linear fashion where dependencies only point one way without making a circle. I.e. dependency graph A -> B -> C is better than A -> C, C -> B, B -> A.

  •  Tags:  
  • Related