Should my document class have methods for printing or should there be a dedicated printer class?

Viewed 185

I want to write an application that prints an document.

Which design would be better? Variant A:

class Document
{
    public string Title { get; set; }
    public string Author { get; set; }
    public string Content { get; set; }
    // ...
}

class DocumentPrinter
{
    public void PrintDocument(Document document)
    {
       // ...
    }
}

This would provide a dedicated DocumentPrinter-class which only does the printing. Or would it be better to add a Print()-method to the Document class itself, like here (Variant B):

public class Document
{
    public string Title { get; set; }
    public string Author { get; set; }
    public string Content { get; set; }

    public void Print()
    {
       // ...
    }
}

What are the implicit trade-offs for both variantes? Which one is better in terms of maintainablity and architecture?

I would say Variant A is the better, because it will satisfy the " Single responsibility principle". But Variant B would be more intuitive to use.

3 Answers

From my opinion, solution A is better because it followed SOLID, and it easier for maintain, extend,... your app.

In addition, I think you should implement DocumentPrinter based on an interface( maybe IDocumentPrinter).

interface IDocumentPrinter
{
    void PrintDocument(Document document);
}

class DocumentPrinter: IDocumentPrinter
{
    public void PrintDocument(Document document)
    {
       // ...
    }
}

Let's think: if in the future you need to have many printers, then with solution A( including IDocumentPrinter) you just need to implement new classes based on IDocumentPrinter (DocumentPrinterA, DocumentPrinterB,...) and you don't need to change your current classes( Document, DocumentPrinter) and it will not violated Open-Close priciple.

The most common general response to this problem is to give Document a formatting function (possibly defined in an interface) that takes a string and substitutes its parameters thereinto, and then have a Printer or DocumentPrinter class that applies a given format and then "prints" the result (whether that means writing output, sending it to a print queue, saving a PDF file or emailing a request to a print company).

If that sounds like something you might want to do at some point in the near future, then do that. Otherwise you're going to have to tightly couple your Print logic to your Document logic one way or another, so choose whichever is easiest.

I would do as below. Your Printer class does not need to understand the intrinsics of a document as it can get the final output that is to be printed.

interface IPrintable
{
     string GetOutput();
}

class Document : IPrintable
{
    ...
    public string GetOutput()
    {
        return ...; // final formatted representation
    }
}

class Printer
{
    public void Print(IPrintable printable)
    {
        var output = printable.GetOutput();
        ... // print it out
    }
}
Related