/* Objektovo-orientovane programovanie 2006/2007 Valentino Vranić Skúška 22.6.2007 - opravný termín Toto je kód jedného z možných riešení pre otázku 18. Využíva idióm double dispatch. Každá trieda by mala byť v samostatnom súbore s názvom v tvare NázovTriedy.java. Pre úplnosť by na začiatku každého takého súboru mal byť uvedený balík do ktorého triedy patria a import balíkov java.util a java.io: package mymodel; import java.util.*; import java.io.*; */ import java.util.*; import java.io.*; // Dokumenty interface PrintDocument { void print(Printer p); // požiadavka na zaradenie dokumentu do tlače na príslušnej tlačiarni void printNow(Printer p); // vytlačenie dokumentu na príslušnej tlačiarni } class PDFDocument implements PrintDocument { public byte[] doc; public void printNow(Printer p) { p.process(this); // skutočné vytlačenie dokumentu na príslušnej tlačiarni } public void print(Printer p) { p.insert(this); // vloženie dokumentu do radu p.startPrinting(); // spustenie tlače } public PDFDocument(DataInputStream f) { /* . . . */ } } class PSDocument implements PrintDocument { public byte[] doc; public void printNow(Printer p) { p.process(this); } public void print(Printer p) { p.insert(this); p.startPrinting(); } public PSDocument(DataInputStream f) { /* . . . */ } } class BMPDocument implements PrintDocument { public byte[] doc; public void printNow(Printer p) { p.process(this); } public void print(Printer p) { p.insert(this); p.startPrinting(); } public BMPDocument(DataInputStream f) { /* . . . */ } } // Ovladáče interface Printer { void process(PDFDocument doc); // každý typ dokumentu sa spracúva inak void process(PSDocument doc); void process(BMPDocument doc); void insert(PrintDocument doc); // vloženie dokumentu do radu dokumentov na tlač void startPrinting(); // spustenie tlače radu dokumentov } class XPrinter implements Printer { private boolean printing; // príznak, či práve prebieha tlač private List queue = new ArrayList(); public synchronized void insert(PrintDocument doc) { queue.add(doc); } private synchronized void remove(int i) { queue.remove(i); } private synchronized void get(int i) { queue.get(i); } public void startPrinting() { final Printer thisPrinter = this; // referencia na tento Printer je potrebná vo vnútornej triede if (!printing) { new Thread() { // tlač sa spustí v samostatnej niti public void run() { while (!queue.isEmpty()) { (queue.get(0)).printNow(thisPrinter); remove(0); } } }.start(); } } public void process(PDFDocument doc) { /* . . . */ } public void process(PSDocument doc) { /* . . . */ } public void process(BMPDocument doc) { /* . . . */ } } class XPrinter1 extends XPrinter { public void process(PDFDocument doc) { /* . . . */ } public void process(PSDocument doc) { /* . . . */ } public void process(BMPDocument doc) { /* . . . */ } } class XPrinter2 extends XPrinter { public void process(PDFDocument doc) { /* . . . */ } public void process(PSDocument doc) { /* . . . */ } public void process(BMPDocument doc) { /* . . . */ } } class M { public static void main(String[] args) { DataInputStream f = ...; PrintDocument myDoc = new PDFDocument(f); Printer myPrinter = new XPrinter2(); myDoc.print(myPrinter); } }