0

I am writing a simple console application and i want to be able to print to the screen.

public class Car{
    public void Drive(){
        //Here I want to print that the car is driving
    }
}

I could just use Console.Writline() in my Drive() function but I don't think that is a good design because in the future i may want to log that to a file instead. What is the best design to achieve this multi-output logging feature? is there a common interface for Console and File output (Iwritable) that I can perhaps pass to the Driver() so i can handle both types of output. Or is there an even better design to achieve this?

Sach
  • 10,091
  • 8
  • 47
  • 84
flexxxit
  • 2,440
  • 5
  • 42
  • 69
  • 'Best' often depends on requirements and circumstances. There's no one stand-out 'best'. Here's an idea to get you started; you can pass a parameter (perhaps an `enum`) to your `Drive()` method saying what type of logging you desire: FILE, CONSOLE etc, and write output accordingly. – Sach Sep 20 '17 at 23:08
  • The Console write methods output to standard output. You can redirect that to a file, without any change to your program. – hatchet - done with SOverflow Sep 20 '17 at 23:11
  • Printing is a feature of your application that has nothing to do with the rest of the logic, I would either use a singleton for that or use AOP which is used for cross cutting concerns such as security. Look into Spring AOP or AspectJ – DPM Sep 20 '17 at 23:12

1 Answers1

3

It's good to be thinking about things like this. It will definitely help you out with more complex projects. You could certainly create an IWritable interface or an abstract class with concrete implementations. Something like:

public interface IWritable
{
    void Write(string text);
}

public class ConsoleWriter : IWritable
{
    public void Write(string text)
    {
        Console.WriteLine(text);
    }
}

And then your Drive() method can accept an IWritable parameter.

public class Car
{
    public void Drive(IWritable writable)
    {
        writable.Write("I'm driving!");
    }
}

new Car().Drive(new ConsoleWriter());

Of course, if your class has several methods that need to do something similar, you might consider changing the constructor to accept an IWritable parameter and storing it in a field:

public class Car
{
    private readonly IWritable _writer;

    public Car(IWritable writer)
    {
        _writer = writer;
    }

    public void Drive()
    {
        _writer.Write("I'm driving!");
    }
}

Another benefit of doing things this way is it makes unit testing your class much simpler. You can pass it some innocuous writer that won't mess with your log file or update your database, but still let's you test the class.

itsme86
  • 19,266
  • 4
  • 41
  • 57
  • Thank you for pointing out that its necessary to think like this. Perhaps you would like to remove the hasty downvote upthere :) – flexxxit Sep 20 '17 at 23:53