Use UFCS for reducing dependencies

Hipreme msnmancini at hotmail.com
Sat Jul 16 22:10:13 UTC 2022


Old habits die hard.

If you're coding in Java, imagine that you want to read a PNG 
from a file, you'll basically have a class like:
```d
class PNG
{
     public bool loadFromMemory(ubyte[] data){return decode(data);}
     public bool loadFromFile(string filePath){return 
readFromMemory(file.read(filePath));}
}
```

Usually it is very common adding API for loading files in your 
decoders, specially in high level wrappers, but this creates a 
problem: Decoding your file is totally unrelated to reading the 
file, yet, you did created the dependency between file and 
decoder.

After some refactoring in my project, trying to reduce 
dependencies, I came to a solution that we should not create 
dependencies like that.

Thanks to UFCS, we can extend the class without actually creating 
such dependency, even in high level wrappers, the way to extend 
your class without creating that kind of dependency is by 
basically creating a extension module:

```d
module png.extension;

//This module contain png extensions based on other libraries.

version(FileSystemPNG)
bool loadFromFile(PNG png, string filePath)
{
     return png.loadFromMemory(file.ready(filePath));
}

```

That way, one could easily call it like:
```d
import png.extension;

//One could even create a file which would import both 
png.decoder and png.extension

PNG png = new PNG();
png.loadFromFile("somewhere.png");
```

You could even save the path inside the PNG at the constructor 
and .loadFromFile would directly access its member.


I came here to show this technique because often people will try 
coding D without really thinking the D way to solve problems, as 
it happened to me. The code become a lot cleaner, one less 
function to worry in your class, one less dependency. I have been 
doing a real refactor on my code around that concept, that way, 
one could easily use any kind of file system reading without even 
needing to refactor the code. Even better, you could create your 
own extension without needing to modify the PNG code.


This is, together with the Range interfaces, one of really valid 
and useful usecase for UFCS. If you guys have any other 
techniques you use for reducing dependencies, I would be glad to 
know :)


More information about the Digitalmars-d mailing list