- Krzysztof Molenda, ver. 01/2020.11.10
Dla wszystkich zadań utwórz jedno solution. Projekty nazywaj: Zadanie1
, Zadanie2
, ... . Będą to projekty typu Console Application.
Podobnie dla projektów typu unit tests, przyjmij nazwy Zadanie1UnitTests
, Zadanie2UnitTests
, ... .
Zadania wykonuj w podanej kolejności - są zależne od siebie.
Realizując to ćwiczenie, nabędziesz umiejętności modelowania obiektowego, uwzględniającego hierarchie interfejsów i klas, klasy abstrakcyjne, dziedziczenie, implementacje interfejsów (explicit i implicit), ... .
Zastosujesz relacje is-a oraz has-a, wzorzec delegacji, kompozycję zamiast dziedziczenia.
Orientacyjny czas realizacji ćwiczenia: od 60 do 90 minut.
Korzystając z załączonego kodu, diagramu klas oraz kodu testów jednostkowych zaprogramuj klasę Copier
symulującą działanie kserokopiarki (kserowanie dokumentów), z możliwością niezależnego drukowania oraz skanowania dokumentów.
- Plik Devices.cs
- Plik Documents.cs
- Plik UnitTestCopier.cs
Przyjmij, że:
-
property
PrintCounter
zwraca aktualną liczbę wydrukowanych dokumentów, -
property
ScanCounter
zwraca liczbę zeskanowanych dokumentów, -
property
Counter
zwraca liczbę uruchomień kserokopiarki -
Jeśli kserokopiarka jest wyłączona, wysyłanie do niej zadań nie ma żadnego skutku i żadnej reakcji z jej strony.
-
Włączanie urządzenia, które jest już włączone, nie przynosi żadnego skutku. Analogicznie dla wyłączania urządzenia.
-
Metoda
Print()
wypisuje na konsolę datę i godzinę wydruku, słowo Print oraz nazwę drukowanego dokumentuPrzykład:
15.11.2020 22:31:13 Print: aaa.pdf
-
Metoda
Scan()
wypisuje na konsolę datę i godzinę skanu, słowo Scan oraz nadaną nazwę pliku zeskanowanego dokumentu w formacie:- dla dokumentów typu
PDF
: PDFScanXXXX.pdf, gdzie XXXX oznacza numer skanowanego dokumentu od pierwszego uruchomienia kserokopiarki, - dla dokumentów typu
JPG
: ImageScanXXXX.jpg, gdzie XXXX oznacza numer skanowanego dokumentu od pierwszego uruchomienia kserokopiarki, - dla dokumentów typu
TXT
: TextScanXXXX.txt, gdzie XXXX oznacza numer skanowanego dokumentu od pierwszego uruchomienia kserokopiarki.
Przykład:
15.11.2020 22:31:13 Scan: ImageScan1.jpg
- dla dokumentów typu
-
Metoda
ScanAndPrint()
wykonuje skanowanie (doJPG
) i natychmiastowy wydruk zeskanowanego dokumentu.
Weryfikuj napisany kod za pomocą dołączonych testów jednostkowych.
W klasie Program
i metodzie Main()
napisz kod symulujący działanie kserokopiarki. Zobacz, jakie komunikaty tekstowe będą wypisywane na konsoli. Przykładowy kod:
class Program
{
static void Main()
{
var xerox = new Copier();
xerox.PowerOn();
IDocument doc1 = new PDFDocument("aaa.pdf");
xerox.Print(in doc1);
IDocument doc2;
xerox.Scan(out doc2);
xerox.ScanAndPrint();
System.Console.WriteLine( xerox.Counter );
System.Console.WriteLine( xerox.PrintCounter );
System.Console.WriteLine( xerox.ScanCounter );
}
}
Po rozwiązaniu zadania 1, wzorując się na istniejącym kodzie, dopisz i dołącz do hierarchii interfejsów i klas:
- interfejs
IFax
, - klasę
MultifunctionalDevice
(urządzenie wielofunkcyjne) modelującą urządzenie łączące w sobie funkcjonalność drukarki, skanera oraz faxu.
Opracuj brakujące testy jednostkowe dla zaprojektowanej klasy.
Zbadaj działanie swojego rozwiązania w programie konsolowym.
Utwórz nowy projekt i przekopiuj kod z zadania 1 (bez klasy Copier
).
Napisz ponownie klasę Copier
, ale przyjmując następujące założenia:
-
kserokopiarka jest luźnym połączeniem skanera i drukarki - jest urządzeniem, które składa się z dwóch innych urządzeń: skanera i drukarki, współpracującymi ze sobą (w poprzednim kroku kserokopiarka była urządzeniem o własności skanowania i drukowania),
-
kserokopiarka "steruje" swoimi składnikami (np. włącza je oraz wyłącza - w zależności od sytuacji),
-
funkcjonalności takie same jak w zadaniu 1,
-
będziesz musiał utworzyć klasy konkretne
Printer
orazScanner
(implementacjeIPrinter
orazIScanner
), -
dodaj klasę
MultidimensionalDevice
(uwzględniając faksowanie) - według tych samych zasad, -
przekopiuj, zmodyfikuj i dodaj brakujące testy jednostkowe.
Zbadaj działanie swojego rozwiązania w programie konsolowym.
Zadanie zrealizuj w C# 8, uwzględniając możliwość domyślnej implementacji metod interfejsu.
Utwórz nowy projekt. Przekopiuj kod z zadania 1 (ten, po jego zrealizowaniu).
Planujesz zmodyfikować definicję urządzenia (IDevice
) - urządzenie może być dodatkowo w stanie standby
(oszczędzania energii).
Musisz:
-
Dodać do
enum State
nowy stan o nazwiestandby
- ta korekta nie spowoduje pojawienia się błędów w kodzie. -
Dodać do
IDevice
dwie metody:StandbyOn()
orazStandbyOff()
- ta modyfikacja spowoduje błędy. -
Dodać do
IDevice
metodęabstract protected void SetState(State state);
. -
Zmodyfikować metody interfejsu
PowerOn
,PowerOf
,StandbyOn
,StandbyOff
domyślnie je implementując w interfejsie, z wykorzystaniemSetState
- narysuj diagram stanów dla kserokopiarki
- mamy trzy stany,
- przejścia między stanami definiują operacje
PowerOn
,PowerOf
,StandbyOn
,StandbyOff
.
- narysuj diagram stanów dla kserokopiarki
-
Usuń klasę
BaseDevice
, kserokopiarka tylko implementujeIPrinter
orazIScanner
. -
Wirtualnie kserokopiarka składa się z dwóch modułów - drukującego i skanującego. Ponieważ urządzenie ma być energooszczędne, moduł nieużywany jest w stanie standby
- przykładowo, jeśli drukujemy, to skaner jest w standby do momentu uruchomienia skanowania, a wtedy moduł drukujący wchodzi automatycznie w tryb standby; analogicznie w drugą stronę,
- możemy "ręcznie" (metody
StandbyOn()
,StandbyOff()
) wprowadzić całe urządzenie (oba moduły) w odpowiedni stan, - ponieważ drukarka musi długo się inicjować przed wydrukiem (np. rozgrzewać) przyjmijmy, że automatycznie przechodzi w tryb standby po wydrukowaniu 3 dokumentów (formalnie to przejście powinno nastąpić po upływie określonego czasu, ale teraz nie tworzymy aplikacji wielowątkowej); jeśli np. drukujemy pod rząd 5 dokumentów, to po pierwszych 3 drukarka wchodzi w standby po to, by za chwilę wzbudzić się i wydrukować dwa pozostałe dokumenty,
- analogicznie skaner - dla kolejnych 2 skanowań,
- narysuj diagram stanów dla tej logiki.
Zaimplementuj tę funkcjonalność bez tworzenia klas konkretnych
Printer
orazScanner
. Możesz część implementacji przenieść doIPrinter
orazIScanner
. W klasieCopier
albo skorzystasz z domyślnych implementacji metod w interfejsach, albo je przesłonisz.UWAGA: stan kserokopiarki (jako jednego urządzenia) będzie definiowany przez stany modułu drukującego i modułu skanującego:
- kserokopiarka jest w stanie
off
, jeśli oba jej składniki są równocześnie w stanieoff
, - kserokopiarka jest w stanie
standby
, jeśli oba jej moduły są w równocześnie staniestandby
, - kserokopiarka jest w stanie
on
w pozostałych przypadkach.
Zbadaj działanie swojego rozwiązania w programie konsolowym.
Uwzględniając korekty zrealizowane w zadaniu 4, w nowym projekcie zaimplementuj układ z Zadania 3 (kserokopiarka składa się z luźno połączonych drukarki i skanera).
Zbadaj działanie swojego rozwiązania w programie konsolowym.