0

Python, has the library pathlib with the concrete class Path.

I have a class called Cleanup, that looks like this:

from pathlib import Path

Cleanup:

    def __init__(self, source : Path, destination: Path):
        self._source = source
        self._destination = destination

The Cleanup class uses certain methods of the Path class, for example, suffix, is_dir()/is_file, etc.

I was reading here, and the answers suggested that instead of allowing the object to be aware of the other object, it should be made into an abstract class.

From this link:

I don't like A directly knowing about B. But that's a DIP thing not a POJO thing.

My issue is, Cleanup knows about Path, but I can't make Path an abstract class because I have no control over it.

When you have no control over a class you need to pass as a attribute of another class, how do you make an abstraction?

2
  • Path is the abstraction. You can pass in a sub-class to the constructor of Cleanup if you want. Dec 4, 2019 at 18:41
  • @BobDalgleish - According to the documentation, PurePath is the abstraction.
    – user351248
    Dec 4, 2019 at 19:31

2 Answers 2

0

One approach, in Python at least, would be to use multiple inheritance. For example:

from pathlib import Path

class IPath:
  """This is your interface, define all methods and attributes you utilize
  here."""

  def is_dir(self): raise NotImplementedError()

class PathlibPath(Path, IPath):
  """This is the pathlib implementation of your interface."""

The other possibility is to write an "adapter"/"proxy" of pathlib.Path that inherits from your interface, and uses an internal pathlib.Path object to actually do the work. Obviously this requires a lot more boilerplate-y code, but in languages without multiple inheritance it could be the only option.

Keep in mind this interface pattern is only useful if you plan on defining multiple implementations of the interface. If you know pathlib.Path supports your use case entirely, it's unnessesary.

1
  • Keep in mind this interface pattern is only useful if you plan on defining multiple implementations of the interface. If you know pathlib.Path supports your use case entirely, it's unnessesary. You hit it! So I guess I keep it the way it is.
    – user351248
    Dec 1, 2019 at 14:50
0

answers suggested that instead of allowing the object to be aware of the other object, it should be made into an abstract class.

This looks too extreme to me. I know people in internet like talking about abstracting each and every class. But it mostly applicable for developers of libraries and generic algorithms.

Basically, for application development, there are 2 cases to introduce abstraction:

  1. You actually intend to use several implementations of some interface in production.

  2. Your class is a part of big stateful service which you may want to mock for purpose of unit testing.

In other cases it should be ok to use a concrete class.

It looks like the Path does not fall into any category of the above and should be ok to depend on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy