Based on the minimal amount of code, I'd venture the following answer:
Layers pattern (and maybe Facade)
The static class LearnerResponse
plays the role (maybe) of a Facade in the layers pattern. The comment clearly says that it handles business logic. Facade classes don't have to have static methods, but there are several examples in Java such as JOptionPane.
Assuming class X
is in another layer (e.g., the presentation layer or GUI), it's not wise to handle business logic there, since often we make different presentation layers for different interactions with the user.
A great example is Siri on iOS, which does voice recognition. When you ask Siri to "Play artist Led Zeppelin" it's an equivalent command to clicking in the GUI to select music by the artist. The code to recognize, present, etc. is different, but the business logic (starting the play operation) is the same. If we put the business logic in the presentation layer, when we make a new version of the layer, then we'd repeat ourselves in repeating the logic.
Here's what the dynamic of your sample code looks like in UML:

In this diagram, classes X
and Y
are variations of the layer that will call the LearnerResponse
facade. They both need to perform the GetPaperResults operation, but since it's business logic, the design delegates that responsibility to another layer (beyond the facade).
This pattern is also a variation of using indirection, which also achieves protected variations (which is a form of information hiding and related to encapsulation and abstraction). It allows changing the implementation of LearnerResponse.GetPaperResults()
without breaking the X
and Y
classes, provided the signature of the methods doesn't change.
You could even argue that this is a form of the open-closed principle, since LearnerResponse
is open to extension with respect to its clients.