I'm creating a math library that will deal with points as function inputs (as shown below).

public struct Point { public int X; public int Y; }

public static class MyLib
    public static float CalculateSomething(Point point1, Point point2) 
    { ... }

My plan is to be able to use it alongside various graphics/gaming libraries and as such that will require transformation from whatever that Point type is from the graphics library to the one provided by my library before it can be used.

Using a Point struct (or class in Java version) as a Parameter Object, which would be object parameter coupling is a clean and nice way to simplify knowing what to pass in but it also requires mapping it to my Point struct/object first before every function call:

var mappedPoint1 = new Point(point1.x, point1.y);
var mappedPoint2 = new Point(point2.x, point2.y);
var result = MyLib.CalculateSomething(mappedPoint1, mappedPoint2);

An alternative could be to use a simple data parameter coupling where only primitive types are passed as parameters:

var result = MyLib.CalculateSomething(point1.x, point1.y, point2.x, point2.y);

I can also see pros/cons to this approach as well since it doesn't require mapping to a data object but does have problems if they mess up the order of primitive types being passed in. Or if more parameters are needed, it would start to become a large parameter list.

What kind of coupling here will be the least taxing on the calling code? While primitive parameters are the simplest to interface with the point abstraction brings clarity and context but also demands more work and mapping code.

  • 1
    which way looked more convenient for calling code when you tried it in unit tests? – gnat Jun 11 '17 at 20:13
  • @gnat, that is an excellent question to consider as the answer to that question can tell me which one is less of a burden when using my library directly (doesn't consider mapping costs but maybe that's ok). Unfortunately my tests are data-driven so either way it only happens in a few places for my tests. I'm going to have to think about what that would be like if I did have to write it for a bunch of tests. – morbidhawk Jun 11 '17 at 20:21
  • data-driven means you focus only on correctness, right? In that case you miss about half of what makes unit tests useful (or about 90% in case if you have strong QA team, cause' it's their profession to verify correctness and discover bugs and they typically do it better than you) – gnat Jun 11 '17 at 20:28
  • I agree with your assessment. Currently it's just a solo developer side project. Since I'm writing the code in multiple programming language versions data tests were the easiest way to quickly verify correctness after porting the code. – morbidhawk Jun 11 '17 at 20:42

Gaming engines and libraries I've worked with usually provide both object parameter and simple data parameter coupling via overloaded methods.

Are you going to use Point internally to your algorithms, or is the first step always going to be to decompose Point into simple data? Most definitions of geometry in game engines have useful operations on them such as distance that you yourself might want to use in your functions. If you plan to use the objects internally to your function definitely define object parameters and define simple data parameter overloads, otherwise don't even bother with the object parameters. Simplicity is often better.

If you have a handful of game engines that you want to target specifically, a third option is to define library-specific bindings of your functions that use the libraries objects as parameters. E.g. I can pass in a Vector2 from LibGDX by importing the LibGDX bindings of your library. This seems like too much work though.

Properly documented code will be the best way to help a user with your library.

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.