DEV Community

Discussion on: Basics of Object Design - Part One

Collapse
 
bajzathd profile image
Bajzáth Dávid

Really nice write up, thank you! 👍
I have only one complaint, with the "Do nothing in the constructor function, Only assign properties" part.
I think in the first solution (extracting to a method) it could be called from the constructor, this is what I usually do if it is not a complicated task. This way it only runs once, and the constructor is the place where you should prepare all of your dependencies, like you said above.
The second method (expecting bootstrapping) adds a hidden dependency, as the logging will fail if the file is not present. Moving it out of the class can be a good idea (especially if it is complex), but I would move it to a Factory class, and make the FileLogger constructor only visible to that class.
I would love to hear your opinion on this.

Collapse
 
olivermensahdev profile image
Oliver Mensah

Can you show your proposed solution in code? I mean that of the second method, bootstrapping.

Collapse
 
bajzathd profile image
Bajzáth Dávid • Edited

I wrote PHP code years ago, but I forgot it does not have nested classes like Java, that is what I was referencing with "make the FileLogger constructor only visible to that class", but you can do a similar thing if you make the constructor protected and move the Factory class to the same package.

final class FileLogger{
    private $logFilePath;
    protected function __construct(string $logFilePath){
        $this->logFilePath = $logFilePath;
    }
    public function log(): void{
        $this->ensureLogFileExists();
    }

}

final class FileLoggerFactory {

    public function create(string $logFilePath): FileLogger {
        ensureLogFileExists($logFilePath);
        return new FileLogger($logFilePath);
    }

    private function ensureLogFileExists(string $logFilePath): void{
        if (is_file($logFilePath)) {
            return;
        }
        $logFileDirectory = dirname($logFilePath);
        if (!is_dir($logFileDirectory)) {
            // create the directory if it doesn't exist yet
            mkdir($logFileDirectory, 0777, true);
        }
        touch($logFilePath);
    }
}

Also, I am new here and I have no idea how to have syntax highlight :(

Thread Thread
 
olivermensahdev profile image
Oliver Mensah • Edited

I have seen the approach as well. Thanks. So allowing the Factory object to new up the object.

For the code highlighting, you can use
3start-backticts
langauge(php, js, py, etc)

3end-backticks

Collapse
 
olivermensahdev profile image
Oliver Mensah

Yeah. You can absolutely call that in the constructor as well to make it run once on the entire object. That would be a good approach to do a sanity check before logging. Thanks for the feedback.

For the second approach with bootstrapping, the dependency is still not hidden. Just that we pass it from the bootstrap face. There are some exceptions that might happen with this, so you will need to throw some exception depending on the issue that might occur. The article just focussed on only one exception type but there are others that we can also look at.

Great feedback.

Collapse
 
bajzathd profile image
Bajzáth Dávid

Thank you for your answer!

I meant hidden as you can create a FileLogger instance without error even if you do not create the file for it, and it will only fail when the first logging takes place, not at creation time.

Thread Thread
 
olivermensahdev profile image
Oliver Mensah

Thank you for the explanation. Very much appreciated