Obrazac dizajna fasade u PHP-u. Dizajnerski obrasci: analogija fasade iz života

Opis Remote Facade

Pruža zajednički objedinjujući interfejs za skup objektnih metoda za poboljšanje efikasnosti umrežavanja.

Obrazac Remote Facade u objektno orijentiranom modelu poboljšava rad s malim objektima koji imaju male metode. Male tehnike nude velike mogućnosti za kontrolu i promjenu ponašanja i poboljšavaju klijentovo razumijevanje aplikacije. Jedna od posljedica ovog fino zrnastog ponašanja je da obično postoji mnogo interakcija između objekata, s puno poziva metoda.

U jednom adresnom prostoru, „fino zrnate“ interakcije dobro funkcionišu, ali sve se menja kada dođe do interakcije između procesa. Pozivi na daljinu su skuplji jer treba dosta toga da se uradi: ponekad treba organizovati podatke, provjeriti sigurnost, pakete treba usmjeriti na komutatore. Ako dva procesa funkcionišu na različitim krajevima svijeta, čak i brzina svjetlosti može igrati ulogu. Teška istina je da je svaka međuprocesna komunikacija za redove veličine rasipnija od intraprocesnih poziva. Čak i ako se oba procesa izvode na istom stroju. Ovaj uticaj na performanse ne može se prevideti, čak ni lijeni entuzijasti optimizacije.

Kao rezultat toga, bilo kojem objektu koji je uključen u daljinsko upravljanje potrebno je općenitije sučelje koje minimizira broj zahtjeva potrebnih da se nešto uradi. Ovo ne utiče samo na metode, već i na objekte. Umjesto da zasebno zahtijevate fakturu i sve njene stavke, trebate pročitati i ažurirati sve stavke fakture u jednom zahtjevu. To utječe na cjelokupnu strukturu objekta. Moramo zaboraviti na dobru svrhu malih objekata i malih metoda. Programiranje postaje sve teže, produktivnost pada i pada.

Obrazac udaljene fasade predstavlja opštu „fasadu“ (prema GoF-u) na vrhu strukture više „fino zrnatih“ objekata. Nijedan od ovih objekata nema udaljeno sučelje, a Remote Facade ne uključuje nikakvu poslovnu logiku. Sve što Remote Facade radi je prevođenje općih zahtjeva u skup malih zahtjeva za podređene objekte.

11. mart 2010. u 10:30

Dizajnerski uzorak "Fasada" / "Fasada"

  • Savršen kod

Opis drugih uzoraka.

Problem

Minimizirati zavisnost podsistema nekog složenog sistema i razmjenu informacija između njih.

Opis

Prilikom projektovanja složenih sistema, tzv princip dekompozicije, u kojem se složeni sistem razlaže na manje i jednostavnije podsisteme. Štaviše, nivo dekompozicije (njegovu dubinu) određuje isključivo dizajner. Zahvaljujući ovom pristupu, pojedinačne komponente sistema mogu se razvijati izolovano, a zatim integrisati zajedno. Međutim, javlja se problem koji je očigledan na prvi pogled - visoka povezanost sistemskih modula. To se očituje, prije svega, u velikoj količini informacija koje moduli međusobno razmjenjuju. Osim toga, za takvu komunikaciju, neki moduli moraju imati dovoljno informacija o prirodi drugih modula.

Stoga je minimiziranje zavisnosti podsistema, kao i smanjenje količine informacija koje se prenose između njih, jedan od glavnih zadataka dizajna.

Jedan od načina da se riješi ovaj problem je korištenje šablona „Facade“.

Fasadni obrazac pruža unificirani interfejs umjesto skupa sučelja podsistema. Fasada definiše interfejs višeg nivoa koji
Ovo pojednostavljuje upotrebu podsistema.

Jednostavno rečeno, “Fasada” nije ništa drugo do objekat koji akumulira skup operacija visokog nivoa za rad sa nekim složenim podsistemom. Fasada agregira klase koje implementiraju funkcionalnost ovog podsistema, ali ih ne sakriva. Važno je shvatiti da klijent, u isto vrijeme, nije lišen pristupa nižeg nivoa klasama podsistema, ako mu je to, naravno, potrebno. Fasada pojednostavljuje određene operacije sa podsistemom, ali ne nameće njegovu upotrebu klijentu.

Praktični problem

Koristeći obrazac “Facade”, implementiraćemo objedinjeni interfejs na neki podsistem autorizacije korisnika. Sam autorizacijski podsistem (u ovom primjeru) svakako ne pretenduje da bude „složen sistem“, ali jasno odražava glavne prednosti obrasca.

Dijagram klasa

Pogledajmo dijagram. Okvir autorizacionog podsistema, radi jasnoće, istaknut je u pravougaoniku. Fasada Authorizator pruža klijentu jedinstveni interfejs za rad sa podsistemom. U ovom slučaju postoji samo jedan metod - autorize(), ali ih može biti više. U ovom slučaju, klijent može koristiti fasadu za rad sa podsistemom, ili može direktno koristiti klase koje ga čine. Sam proces autorizacije je prilično jednostavan. Na osnovu korisničkog imena, odgovarajući unos u bazi se pretražuje kroz DB ​​interfejs. Zatim se lozinka pronađenog unosa upoređuje sa lozinkom koju je odredio korisnik.

Implementacija u C#

U kodu za implementaciju br klasa PgSQLDB.
korištenje sistema;
koristeći System.Collections.Generic ;
koristeći System.Linq;
koristeći System.Text;
koristeći System.Security;

namespace Fasada
{
//Apstraktna korisnička klasa
apstraktna klasa Korisnik
{
zaštićeni string korisničko ime;
zaštićeni niz passwd;

javni apstraktni string getUserRole();

javni niz getPasswdHash()
{
// Ovaj red nema nikakvo semantičko značenje.
// Naravno, ovo nam daje nesiguran hash lozinke
return passwd.GetHashCode().ToString();
}
}

// Odredite korisnika kao zadanog korisnika
klasa Zadani korisnik: korisnik
{
javni DefaultUser(niz korisničko ime, string passwd)
{
ovo .username = korisničko ime;
ovo .passwd = passwd;
}


{
return "DEFAULT_USER" ;
}
}

// Odredite korisnika kao administratora
Administrator klase: Korisnik
{
javni administrator (niz korisničko ime, string passwd)
{
ovo .username = korisničko ime;
ovo .passwd = passwd;
}

javno nadjačavanje stringa getUserRole()
{
vrati "ADMINISTRATOR" ;
}

// Interfejs za pristup bazi podataka
interfejs DB
{
Pretraga korisnika(niz korisničko ime);
}

// Implementacija sučelja baze podataka za SQLite
klasa SQLiteDB:DB
{
javni SQLiteDB(string ime datoteke)
{
// Inicijaliziranje drajvera baze podataka
}

javno pretraživanje korisnika (niz korisničko ime)
{
// Stub
izbaci novi NotImplementedException();
}
}

// Autorizacija korisnika
public void authorize (niz korisničko ime, string passwd)
{
DB db = novi SQLiteDB("db.sqlite" );
Korisnik korisnik = db.search(korisničko ime);
if (user.getPasswdHash() == passwd)
{
// sve je u redu, korisnik je prepoznat
}
ostalo
{
// Nešto je pošlo po zlu
throw new SecurityException("Pogrešna lozinka ili korisničko ime!");
}
}
}

razred Program
{
static void Main (args niza)
{
// Fiktivni korisnik
string korisničko ime = "Vasya" ;
string passwd = "qwerty" .GetHashCode().ToString();

Autorizator auth = novi Autorizator();
probaj
{
auth.authorizate(korisničko ime, passwd);
}
uhvatiti (SecurityException ex)
{
// Korisnik nije autentificiran
}
}
}
}


* Ovaj izvorni kod je istaknut sa izvornim kodom Highlighter.

PS: Ja sam jedini kome habraeditor ne radi?

Svrha šablona fasade

  • Fasadni obrazac pruža unificirani interfejs umjesto skupa sučelja podsistema. Fasada definiše interfejs višeg nivoa koji čini podsistem lakšim za korišćenje.
  • Fasadni uzorak obavija složeni podsistem sa jednostavnijim interfejsom.

Problem koji treba riješiti

Kupci žele pojednostavljeno sučelje za cjelokupnu funkcionalnost složenog podsistema.

Diskusija o obrascu fasade

Fasadni obrazac inkapsulira složeni podsistem u jedan objekat interfejsa. Ovo smanjuje vrijeme potrebno za učenje podsistema i također pomaže u smanjenju stepena sprege između podsistema i potencijalno velikog broja klijenata. S druge strane, ako je fasada jedina pristupna tačka podsistemu, onda će to ograničiti mogućnosti koje naprednim korisnicima mogu biti potrebne.

Objekt Facade koji implementira posredničke funkcije trebao bi ostati prilično jednostavan i ne biti sveznajući "proročanstvo".

Struktura fasadnog uzorka

Klijenti komuniciraju sa podsistemom preko Facade. Kada se primi zahtjev od klijenta, objekt Facade ga prosljeđuje željenoj komponenti podsistema. Za klijente, komponente podsistema ostaju „misterija, obavijena tamom“.

Podsistemi SubsystemOne i SubsystemThree nemaju direktnu interakciju s internim komponentama podsistema SubsystemTwo. Oni koriste SubsystemTwoWrapper "fasadu" (tj. apstrakciju višeg nivoa).

Fasadni obrazac definiše ujedinjeni interfejs visokog nivoa za podsistem, što ga čini lakšim za korišćenje. Kupci se suočavaju sa fasadom prilikom naručivanja kataloških proizvoda putem telefona. Kupac poziva službu za korisnike i navodi artikle koje želi kupiti. Predstavnik servisa djeluje kao "front", pružajući sučelje odjelu za ispunjenje, odjelu prodaje i službi isporuke.

  • Definirajte jednostavno, objedinjeno sučelje za podsistem.
  • Dizajnirajte klasu "omotača" koja inkapsulira podsistem.
  • Cjelokupna složenost podsistema i interakcija njegovih komponenti su skriveni od klijenata. "Fasada"/"omotač" prosljeđuje zahtjeve korisnika odgovarajućim metodama podsistema.
  • Klijent koristi samo "fasadu".
  • Razmotrite izvodljivost stvaranja dodatnih "fasada".

Karakteristike fasadnog uzorka

  • Fasada definira novi interfejs, dok Adapter koristi postojeći. Zapamtite, Adapter čini da dva postojeća interfejsa rade zajedno bez kreiranja novih.
  • Dok Flyweight pokazuje kako napraviti mnogo malih objekata, Facade pokazuje kako napraviti jedan objekat koji predstavlja cijeli podsistem.
  • Mediator je sličan Facadeu po tome što apstrahuje funkcionalnost postojećih klasa. Međutim, Mediator centralizira funkcionalnost između ravnopravnih objekata koja nije svojstvena nijednom od njih. Kolege međusobno razmjenjuju informacije putem Mediatora. S druge strane, Facade definira jednostavan interfejs za podsistem, ne dodaje novu funkcionalnost i nije poznat klasama podsistema.
  • Abstract Factory se može koristiti kao alternativa Facade za sakrivanje klasa specifičnih za platformu.
  • Objekti "Facade" su često Singleton jer je potreban samo jedan Facade objekt.
  • Adapter i Fasada su oba omota, ali su različite vrste omotača. Cilj Facade je kreiranje jednostavnijeg interfejsa, cilj Adaptera je da prilagodi postojeći interfejs. Fasada obično obavija više objekata, Adapter omotava jedan objekat.

Implementacija obrasca fasade

Razbijanje sistema na komponente smanjuje njegovu složenost. Možete olabaviti veze između komponenti sistema koristeći Fasadni uzorak. Fasadni objekat pruža jedno, pojednostavljeno sučelje komponentama sistema.

Primjer ispod modelira sistem mrežnih usluga. FacilitiesFacade skriva unutrašnju strukturu sistema. Korisnik se, nakon što je jednom podnio zahtjev za servis, zatim 1-2 puta sedmično u trajanju od 5 mjeseci raspituje o toku posla dok njegov zahtjev ne bude u potpunosti servisiran.

#include class MisDepartment ( public: void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _state++; if (_state == Complete) return 1; return 0; ) private: enum States ( Received, DenyAllKnowledge, ReferClientNocilToFacilities, ReferClientNocilToFaHaperities , ElectricianDidItWrong, DispatchTechnician, SignedOff, DoesNotWork, FixElectriciansWiring, Complete ); int _state; ); class ElectricianUnion ( public: void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _state++; if (_state == Complete) return 1; return 0; ) private: enum States ( Received, RejectTheForm, SizeTheJob, SmokeAndJokeFor WaitFor , DoTheWrongJob, BlameTheEngineer, WaitToPunchOut, DoHalfAJob, ComplainToEngineer, GetClarification, CompleteTheJob, TurnInThePaperwork, Complete ); int _state; ); class FacilitiesDepartment ( public: void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _state++; if (_state == Complete) return 1; return 0; ) private: enum States ( Received, AssignToEngineer, EngineerResearches,RequestIeCompany, RequestI , AssignToNewEngineer, NewEngineerResearches, ReassignEngineer, EngineerReturns, EngineerResearchesAgain, EngineerFillsOutPaperWork, Complete ); int _state; ); class FacilitiesFacade ( public: FacilitiesFacade() ( _count = 0; ) void submitNetworkRequest() ( _state = 0; ) bool checkOnStatus() ( _count++; /* Primljen je zahtjev za uslugu */ if (_state == Primljeno) ( _state++; / * Preusmjerite zahtjev na inženjera */ _engineer.submitNetworkRequest(); cout<< "submitted to Facilities - " << _count << " phone calls so far" << endl; } else if (_state == SubmitToEngineer) { /* Если инженер свою работу выполнил, перенаправим запрос электрику */ if (_engineer.checkOnStatus()) { _state++; _electrician.submitNetworkRequest(); cout << "submitted to Electrician - " << _count << " phone calls so far" << endl; } } else if (_state == SubmitToElectrician) { /* Если электрик свою работу выполнил, перенаправим запрос технику */ if (_electrician.checkOnStatus()) { _state++; _technician.submitNetworkRequest(); cout << "submitted to MIS - " << _count << " phone calls so far" << endl; } } else if (_state == SubmitToTechnician) { /* Если техник свою работу выполнил, то запрос обслужен до конца */ if (_technician.checkOnStatus()) return 1; } /* Запрос еще не обслужен до конца */ return 0; } int getNumberOfCalls() { return _count; } private: enum States { Received, SubmitToEngineer, SubmitToElectrician, SubmitToTechnician }; int _state; int _count; FacilitiesDepartment _engineer; ElectricianUnion _electrician; MisDepartment _technician; }; int main() { FacilitiesFacade facilities; facilities.submitNetworkRequest(); /* Звоним, пока работа не выполнена полностью */ while (!facilities.checkOnStatus()) ; cout << "job completed after only " << facilities.getNumberOfCalls() << " phone calls" << endl; }

Izlaz programa:

predato objektima - 1 telefonski poziv do sada upućen Električaru - 12 telefonskih poziva do sada predato MIS-u - 25 telefonskih poziva do sada završen posao nakon samo 35 telefonskih poziva

Fasada je strukturalni obrazac dizajna koji pruža jednostavan interfejs za složeni sistem klasa, biblioteku ili okvir.

Problem

Vaš kod mora raditi s velikim brojem objekata iz neke složene biblioteke ili okvira. Morate sami inicijalizirati ove objekte, osigurati da su zavisnosti u ispravnom redoslijedu itd.

Kao rezultat toga, poslovna logika vaših klasa je usko isprepletena sa detaljima implementacije klasa treće strane. Takav kod je prilično teško razumjeti i održavati.

Rješenje

Fasada je jednostavan interfejs za rad sa složenim podsistemom koji sadrži mnogo klasa. Fasada može imati smanjeni interfejs koji nema 100% funkcionalnosti koja se može postići direktnim korišćenjem složenog podsistema. Ali pruža upravo one karakteristike koje su klijentu potrebne i skriva sve ostalo.

Fasada je korisna ako koristite neku složenu biblioteku s puno pokretnih dijelova, ali vam je potreban samo dio njenih mogućnosti.

Na primjer, program koji postavlja video zapise mačaka na društvene mreže može koristiti profesionalnu biblioteku kompresije videa. Ali sav klijentski kod za ovaj program je jednostavan metod kodiranja (ime datoteke, format). Kreiranjem klase ovom metodom implementirate svoju prvu fasadu.

Analogija iz života


Kada nazovete prodavnicu i naručite telefonom, predstavnik službe za korisnike je vaša ulazna vrata za sve službe i odjele trgovine. Pruža vam pojednostavljeni interfejs za sistem kreiranja narudžbi, sistem plaćanja i odjel za isporuku.

Struktura



    Fasada omogućava brz pristup određenim funkcijama podsistema. On "zna" koje klase trebaju proslijediti zahtjev i koji su podaci potrebni za to.

    Dodatna fasada može se uvesti tako da se pojedinačna fasada ne „zatrpava“ heterogenom funkcionalnošću. Može se koristiti i za klijenta i za druge fasade.

    Složeni podsistem sastoji se od mnogo različitih klasa. Da biste ih natjerali da nešto urade, morate znati detalje strukture podsistema, redoslijed inicijalizacije objekata i tako dalje.

    Klase podsistema ne znaju za postojanje fasade i direktno rade jedna s drugom.

    Klijent koristi fasadu umjesto direktnog rada sa objektima složenog podsistema.

Pseudocode

U ovom primjeru Fasada pojednostavljuje rad sa složenim okvirom za video konverziju.


Primjer izolacije više ovisnosti u jednoj fasadi.

Umjesto direktnog rada sa desetak klasa, fasada daje kodu aplikacije jednu metodu za konverziju videa, koja se sama brine o ispravnom konfigurisanju potrebnih okvirnih objekata i dobijanju traženog rezultata.

// Klase za složeni okvir za konverziju videa treće strane. Mi // ne kontroliramo ovaj kod, tako da ga ne možemo pojednostaviti. class VideoFile // ... class OggCompressionCodec // ... class MPEG4CompressionCodec // ... class CodecFactory // ... class BitrateReader // ... class AudioMixer // ... // Umjesto toga, kreiramo Facade - jednostavno sučelje za rad // sa složenim okvirom. Fasada nema svu funkcionalnost // okvira, ali skriva svoju složenost od klijenata. class VideoConverter je metoda pretvaranja(ime datoteke, format):Datoteka je datoteka = novi VideoFile(ime datoteke) sourceCodec = novi CodecFactory.extract(file) if (format == "mp4") destinationCodec = novi MPEG4CompressionCodec() else destinationCodec = novi OggCompressionCodec( ) buffer = BitrateReader.read(filename, sourceCodec) result = BitrateReader.convert(buffer, destinationCodec) result = (novi AudioMixer()).fix(result) return new File(result) // Aplikacija ne ovisi o kompleksu okvir konverzije / / video. Usput, ako iznenada odlučite promijeniti okvir, // morat ćete samo prepisati klasu fasade. klasa Aplikacija je metoda main() je pretvarač = novi VideoConverter() mp4 = convertor.convert("funny-cats-video.ogg", "mp4") mp4.save()

Primjenjivost

Kada trebate predstaviti jednostavno ili smanjeno sučelje složenom podsistemu.

Često podsistemi postaju složeniji kako se program razvija. Primjena većine obrazaca rezultira manjim razredima, ali većim brojem. Lakše je ponovo koristiti takav podsistem, prilagođavajući ga svaki put za specifične potrebe, ali u isto vrijeme postaje teže koristiti podsistem bez prilagođavanja. Fasada podrazumevano nudi određeni tip sistema koji odgovara većini klijenata.

Kada želite da dekomponujete podsistem u zasebne slojeve.

Koristite fasade za definiranje ulaznih tačaka na svaki nivo podsistema. Ako podsistemi zavise jedan od drugog, onda se zavisnost može pojednostaviti dozvoljavajući podsistemima da razmjenjuju informacije samo preko fasada.

Na primjer, uzmimo isti složeni sistem video konverzije. Želite da ga razbijete na slojeve audio i video rada. Za svaki od ovih dijelova možete pokušati napraviti fasadu i omogućiti da klase audio i video obrade komuniciraju jedna s drugom preko ovih fasada, a ne direktno.

Koraci implementacije

    Odredite da li je moguće kreirati jednostavnije sučelje od onog koji pruža složeni podsistem. Na pravom ste putu ako ovaj interfejs eliminiše potrebu da klijent zna o detaljima podsistema.

    Kreirajte klasu fasade koja implementira ovo sučelje. Mora proslijediti klijentske pozive na ispravne objekte podsistema. Fasada će morati da vodi računa da pravilno inicijalizuje objekte podsistema.

    Maksimalnu korist ćete dobiti ako klijent radi samo sa fasadom. U ovom slučaju, promjene u podsistemu će utjecati samo na fasadni kod, a klijentski kod će i dalje raditi.

Fasada je obrazac ponašanja. Ovaj obrazac vam omogućava da sakrijete složenost sistema smanjenjem svih mogućih poziva na jedan objekat koji ih delegira odgovarajućim sistemskim objektima.

Najjednostavnija shema kako obrazac funkcionira:

Zamislimo da pišemo softver za mikrovalnu pećnicu. Radi jednostavnosti, zamislimo da ima samo sljedeće funkcije: skretanje lijevo i desno, podešavanje potrebne snage, obavještavanje o početku i kraju rada.

Da biste pripremili ukusno jelo, nešto zagrijali ili odmrznuli, potrebno je izvršiti određeni broj različitih radnji u određenom slijedu. Na primjer, prilikom odmrzavanja potrebno je, počevši od velikih snaga, nekoliko puta resetirati napajanje, rotirajući platformu s proizvodom.

Kada bi korisnik morao sam da prati svaki korak procesa, to bi bilo veoma dugotrajno i neefikasno. Uostalom, svi znaju da je na modernoj mikrovalnoj pećnici dovoljno odabrati željeni program i pritisnuti start, nakon čega će učiniti sve što je potrebno, a po završetku će obavijestiti korisnika.

Obrazac dizajna fasade bavi se upravo takvim slučajevima. Omogućava vam da sakrijete svu složenost procesa iza jednostavnog interfejsa.

Kreirajmo klase za rad mikrovalnog pogona (rotacija), napajanje i obavještavanje.

U klasi vožnje bit će samo 2 radnje: skrenite desno i skrenite lijevo.

Class Drive ( public void TurlLeft() ( Console.WriteLine("Rotate Left"); ) public void TurlRight() (Console.WriteLine("Rotate Right"); ) )

U klasi koja specificira snagu, dodano je svojstvo za dobivanje i postavljanje potrebne snage rada.

Class Power (privatni int _power; javni int MicrowavePower ( get ( return _power; ) set ( _power = vrijednost; Console.WriteLine("Power set (0)w ", _power); ) ) )

U klasu obavještenja dodane su metode za obavještavanje o početku i kraju rada.

Obavijest o klasi ( public void StopNotification() ( Console.WriteLine("Peak-peak-peak - operacija je završena"); ) public void StartNotification() ( Console.WriteLine("Peak - proces kuhanja je počeo"); ) )

Ostaje samo implementirati samu klasu mikrovalne pećnice. U ovom primjeru to će biti i fasada. Na času implementiramo metode za odmrzavanje i zagrijavanje hrane.

Klasa Mikrovalna pećnica (privatni pogon _pogon; privatno napajanje _napajanje; privatno obavještenje _obavještenje; javna mikrovalna pećnica (pogon pogona, napajanje, obavijest o obavijesti) ( _drive = pogon; _power = napajanje; _notification = obavijest; ) public void Defrost() ( _notification.StartNotification (); _power.MicrowavePower = 1000; _drive.TurlRight(); _drive.TurlRight(); _power.MicrowavePower = 500; _drive.TurlLeft(); _drive.TurlLeft(); _power.MicrowavePower(); _power.MicrowavePower() =MicrowavePower(); ; _drive.TurlRight(); _power.MicrowavePower = 0; _notification.StopNotification(); ) public void Heating() ( _notification.StartNotification(); _power.MicrowavePower = 350; _drive.TurlRight(); _Rdrive(); _Rdrive(); _Rdrive(); _drive.TurlRight(); _drive.TurlRight(); _drive.TurlRight(); _drive.TurlLeft(); _drive.TurlLeft(); _drive.TurlRight(); _drive.TurlRight(); _drive.TurlLeft(); _drive.TurlLeft(); TurlLeft(); _drive.TurlLeft(); _drive.TurlLeft(); _power.MicrowavePower = 0; _notification.StopNotification(); ) )

To je sve, primjer je spreman, ostaje samo da ga testiramo.

Var drive = new Drive(); var power = new Power(); var notification = novo obavještenje(); var mikrovalna = nova mikrovalna.Mikrovalna(pogon, napajanje, obavijest); Console.WriteLine("Odmrzavanje"); mikrovalna.Odmrzavanje(); Console.WriteLine(); Console.WriteLine("Hajde da se zagrejemo"); mikrovalna.Heating();

Rezultat će biti sljedeći:


Slični članci

2023 ap37.ru. Vrt. Dekorativno grmlje. Bolesti i štetočine.