Question

I need to design a receipt object that will take line items in a transaction and format them for a 40 column display. In the future I will also need another format for regular sized printer paper.

The transaction has different types of line items (items, comments, discounts, tenders, etc.).

My first thought was to create an interface for each of these so that they would be responsible for formatting themselves, and I could add a new method to the interface for each type of receipt format I need. My next thought was to create one class for each type of receipt format I need and let it be responsible for looking at what type each line is and formatting it appropriately.

So my question is whether there is a better design pattern that I may be overlooking, and if not then is there significant reason to favor one of the above designs over the other?

So I could add something like this:

public interface IReceiptFormat
{
    string FormatFor40Column();
    string FormatForRegularPaper();
}

to my Item, Comment, etc. classes. Or I could create something like this:

public ReceiptFormatterFor40Column
{
    public Ticket Ticket {get; private set;}

    public ReceiptFormatterFor40Column(Ticket ticket)
    {
        Ticket = ticket;
    }

    public List<string> GenerateReceipt()
    {
        var lines = new List<string>();

        foreach(var line in Ticket.Lines)
        {
            // check what type of object line is and add
            // add an appropriately formatted string to lines
        }
    }
}
Was it helpful?

Solution

Why don't you just create a IRecieptPrinter interface and then a RegularPaperPrinter and ColumnPrinter?

then you could do:

var printer = new RegularPaperPrinter();
printer.Print(receipt);

If you don't want to create the printers yourself you could use the factory pattern:

var printer = printerFactory.Create("regularpaper");
printer.Print(receipt);

OTHER TIPS

My initial thoughts are that a Strategy pattern is what you're looking for. This would be useful if you wanted to separate the formatting from the content. The line could be injected with its appropriate formatting strategy on creation, and maybe have a default for convenience. Then the lines could all implement a single IFormattable interface that delegated to the injected strategy.

I had the same case to solve and I finaly used a bridge design pattern separating the receipt and his content from the printing.

abstract class Receipt{
private Printer printer;

public Receipt (Printer printer){
if (printer==null){
throw new NullArgumentException ("Printer can't be null.");
}
this.printer=printer;
}

public abstract PrintJobStatus printReceipt ();
}

abstract class Printer {

public abstract void printLine (String txt, Alignement al, Font fo, Size si);
public abstract void printQrCode(String qrCodeStr, QrType qrType, Size si);
}

public class VatReceipt extend Receipt{

public VatReceipt (Printer printer){
super (printer);
}

@Overide
public PrintJobStatus printReceipt ()
PrintJobStatus result=PrintJobStatus.UNDEFINE;

printer.printLine ("Hello i'm the receipt.header",
Alignement.CENTER,  Font.A, Size.SMALL);
...
...
return result;
}

public class EpsonT88Printer extend Printer{
private EpsonPrinterSdk epsonSdkPrinter;

@Overide
public void printLine(String txt, Alignement al, Font fo, Size si){
int epsonAlignement=convertGenericAligToEpsonAlig(al);
int epsonFont=convertGenericFontToEpsonFont(fo);
...
epsonSdkPrinter.printTextLine (txt, epsonAlignement,...);
}
}

I'm answering from my phone...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top