<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	 xmlns:media="http://search.yahoo.com/mrss/" >

<channel>
	<title>Angular &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<atom:link href="https://nearshore-it.eu/pl/tag/angular-2/feed/" rel="self" type="application/rss+xml" />
	<link>https://nearshore-it.eu/pl/</link>
	<description>We are Nearshore Software Development Company with 14years of experience in delivering a large scale IT projects in the areas of PHP, JAVA, .NET, BI and MDM.</description>
	<lastBuildDate>Thu, 07 Nov 2024 14:15:00 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://nearshore-it.eu/wp-content/uploads/2023/01/cropped-inetum-favicon-300x300-1-32x32.png</url>
	<title>Angular &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<link>https://nearshore-it.eu/pl/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Wprowadzenie do Angular Material design</title>
		<link>https://nearshore-it.eu/pl/artykuly/angular-material-design-wprowadzenie/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/angular-material-design-wprowadzenie/#respond</comments>
		
		<dc:creator><![CDATA[Eryk Schubert]]></dc:creator>
		<pubDate>Wed, 10 Jan 2024 12:37:23 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/angular-material-design-wprowadzenie/</guid>

					<description><![CDATA[Angular Material to często wybór numer jeden dla deweloperów, którzy pragną projektować i tworzyć przyciągające wzrok, spójne i użyteczne aplikacje webowe, i to niezależnie od posiadanego doświadczenia. Co warto wiedzieć na początek? Przeczytaj ten wpis, aby dowiedzieć się, jak niewielkim nakładem pracy zyskać zupełnie nową wartość i jakość w tworzeniu interfejsów aplikacji.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#Jak-tworzyć-zachwycające-i-funkcjonalne-interfejsy?">1.  Jak tworzyć zachwycające i funkcjonalne interfejsy?</a></li>
                    <li><a href="#Biblioteka-czy-framework?-Czym-jest-Angular-Material?-">2.  Biblioteka czy framework? Czym jest Angular Material? </a></li>
                    <li><a href="#Jak-zaimplementować-Angular-Material-w-naszej-aplikacji?-">3.  Jak zaimplementować Angular Material w naszej aplikacji? </a></li>
                    <li><a href="#Jak-korzystać-z-komponentów-dostępnych-w-Angular-Material?-">4.  Jak korzystać z komponentów dostępnych w Angular Material? </a></li>
                    <li><a href="#Korzystanie-z-komponentów-w-szablonach-">5.  Korzystanie z komponentów w szablonach </a></li>
                    <li><a href="#Dostosowanie-komponentu-do-potrzeb-aplikacji-">6.  Dostosowanie komponentu do potrzeb aplikacji </a></li>
                    <li><a href="#Jak-i-od-czego-zacząć-naukę?-">7.  Jak i od czego zacząć naukę? </a></li>
                    <li><a href="#własny-motyw-w-Angular-Material">8.  Jak stworzyć własny motyw w Angular Material? </a></li>
                    <li><a href="#Konfiguracja-kolorów-">9.  Konfiguracja kolorów </a></li>
                    <li><a href="#Dlaczego-warto-tworzyć-aplikacje-z-tą-biblioteką-komponentów?-">10.     Dlaczego warto tworzyć aplikacje z tą biblioteką komponentów? </a></li>
                    <li><a href="#Podsumowanieu002du002d">11.  Podsumowanie  </a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Jak-tworzyć-zachwycające-i-funkcjonalne-interfejsy?">Jak tworzyć zachwycające i funkcjonalne interfejsy?</h2>



<p>Czy zastanawiało cię kiedyś, jak to jest, że współczesne aplikacje internetowe zachwycają swoimi stylowymi, a jednocześnie funkcjonalnymi interfejsami użytkownika? Cóż, tajemnica często tkwi w bibliotekach UI/UX, a w świecie Angulara króluje Angular Material. Jest to kompleksowy zestaw narzędzi do budowania interfejsów, opracowany w duchu Material Design – zestawu dobrych praktyk projektowania opracowanego przez Google. Jego kluczowymi elementami są czytelność, spójność i reakcja na interakcję użytkownika, co sprawia, że jest on przyjazny i łatwy w obsłudze. Zainteresowanych zachęcam do zapoznania się z materiałami i przykładami implementacji na stronie <a href="https://material.io/" target="_blank" rel="noreferrer noopener">https://material.io/.</a></p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/icons_modified.gif" alt=" class=" class="wp-image-13477" style="width:762px;height:auto" title="Wprowadzenie do Angular Material design 1"><figcaption class="wp-element-caption">Ikony powinny być proste i czytelne, bez zbędnych efektów 3d&nbsp; &nbsp;<br><em>źródło: material.io</em></figcaption></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/dynamic-color-animation-modified.gif" alt=" class=" class="wp-image-13479" title="Wprowadzenie do Angular Material design 2"><figcaption class="wp-element-caption">Przykład zastosowania kolorów dynamicznych w Material Design&nbsp;<br><em>źródło: material.io</em></figcaption></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Biblioteka-czy-framework?-Czym-jest-Angular-Material?-">Biblioteka czy framework? Czym jest Angular Material?&nbsp;</h2>



<p>Najprościej ujmując, to biblioteka UI zawierająca zestaw gotowych do użycia, wysokiej jakości komponentów dla Angulara. Dzięki prostym i przetestowanym API oraz swojej wszechstronności i mnogości rozwiązań, biblioteka pozwala na doskonałą integrację i tworzenie świetnych customowych rozwiązań.&nbsp;</p>



<h2 class="wp-block-heading" id="Jak-zaimplementować-Angular-Material-w-naszej-aplikacji?-">Jak zaimplementować Angular Material w naszej aplikacji?&nbsp;</h2>



<p>To proste! Wszystko dzieje się automatycznie dzięki wspaniałemu Angular CLI, dlatego od razu przejdźmy do szczegółów! Załóżmy, że masz już aplikację w Angularze i chcesz wzbogacić ją o Angular Material. Wystarczy, że w terminalu, w lokalizacji projektu, wpiszesz:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ng add @angular/material </pre>



<p>Podczas instalacji możesz wybrać motyw kolorystyczny, ustawić globalne style dla typografii oraz zdecydować o włączeniu animacji. W nowej aplikacji polecam wybrać losowy motyw, ustawić style dla typografii i włączyć animacje.&nbsp;</p>



<p>Pamiętaj: W istniejącej już aplikacji unikaj włączania stylów typograficznych, jeśli chcesz zachować wcześniej przygotowane przez siebie style tekstowe.&nbsp;</p>



<p>Po instalacji zauważysz, że ścieżka do pliku CSS wybranego motywu została dodana do globalnych stylów aplikacji w pliku angular.json:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">"styles": [ 

              "@angular/material/prebuilt-themes/indigo-pink.css", 

              "src/styles.scss" 

], </pre>



<p>Dodatkowo paczka @angular/material została dodana do pliku package.json, ikony i fonty zostały zaimportowane w pliku index.html, body otrzymało klasę mat-typography i nowe globalne style pojawiły się w pliku styles.css.&nbsp;</p>



<p>I to wszystko! Teraz możesz zacząć bawić się komponentami.&nbsp;</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/">Który framework wybrać? Pojedynek gigantów: React vs Angular</a></p>



<h2 class="wp-block-heading" id="Jak-korzystać-z-komponentów-dostępnych-w-Angular-Material?-">Jak korzystać z komponentów dostępnych w Angular Material?&nbsp;</h2>



<p>Angular Material oferuje wachlarz komponentów UI, które są elastyczne i łatwe w użyciu, a przy tym zgodne z wytycznymi Material Design. Weźmy na przykład prosty przycisk.&nbsp;</p>



<h3 class="wp-block-heading">Importowanie modułu komponentu&nbsp;</h3>



<p>Każdy komponent z Angular Material ma swój dedykowany moduł. Dla przycisków będzie to MatButtonModule z przestrzeni @angular/material/button.&nbsp;</p>



<p>Jeśli twoja aplikacja jest podzielona na wewnętrzne moduły, zaimportuj potrzebny moduł do modułu, w którym zamierzasz użyć komponentu:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mport { MatButtonModule } from '@angular/material/button'; 

... 

@NgModule({ 

  declarations: [...], 

  imports: [MatButtonModule, ...], 

}) 

export class AppModule { } </pre>



<p>Jeśli korzystasz ze standalone component, wystarczy import bezpośrednio w komponencie:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { MatButtonModule } from '@angular/material/button'; 

... 

@Component({ 

  selector: 'app-root', 

  standalone: true, 

  imports: [MatButtonModule, ...], 

  templateUrl: './app.component.html', 

  styleUrl: './app.component.scss' 

}) 

export class AppComponent { }</pre>



<h2 class="wp-block-heading" id="Korzystanie-z-komponentów-w-szablonach-">Korzystanie z komponentów w szablonach&nbsp;</h2>



<p>Teraz możesz zacząć używać komponentów w szablonach HTML. Aby umieścić przycisk, wystarczy dodać odpowiedni tag w pliku HTML.&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;button mat-button>Kliknij mnie&lt;/button> </pre>



<p>Dzięki temu, że operujesz tutaj na natywnym obiekcie button, możesz obsługiwać wszystkie jego zdarzenia i korzystać z niego dokładnie w taki sam sposób, jak bez Angular Material.&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;button mat-button (click)="onClick()" (focus)="onFocus()" [disabled]="isDisabled">Kliknij mnie&lt;/button> </pre>



<p>Teraz pięknie ostylowany przycisk znajduje się w twojej aplikacji, a ty intuicyjnie wiesz już, jak z niego korzystać.&nbsp;</p>



<h2 class="wp-block-heading" id="Dostosowanie-komponentu-do-potrzeb-aplikacji-">Dostosowanie komponentu do potrzeb aplikacji&nbsp;</h2>



<p>Wszystkie komponenty możesz ostylowywać i konfigurować tak, aby pasowały do potrzeb twojej aplikacji. Na przykład przyciski oferują różne style <em>out of the box</em>, takie jak basic, raised, stroked, flat, icon, fab czy mini fab. Każdemu stylowi dodatkowo możesz nadać kolor: primary, accent, warn – które skonfigurowane są w wybranym przez ciebie motywie (o czym w dalszej części artykułu).&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image size-full">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/ButtonTypes.png" alt=" class=" class="wp-image-13481" title="Wprowadzenie do Angular Material design 3"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Aby dowiedzieć się, jaki moduł zaimportować oraz w jaki sposób konfigurować dany komponent, najlepiej jest zajrzeć do dokumentacji dostępnej w Internecie. Możesz tam poznać parametry do konfiguracji komponentu oraz przykłady użycia (wraz z kodem), na które warto spojrzeć w poszukiwaniu sposobu użycia lub inspiracji. Dla przycisku będzie to strona: <a href="https://material.angular.io/components/button/overview" target="_blank" rel="noreferrer noopener">Button | Angular Material.</a>&nbsp;</p>



<p>Natomiast całą listę dostępnych komponentów podzielonych na kategorie znajdziesz tutaj: <a href="https://material.angular.io/components/categories" target="_blank" rel="noreferrer noopener">Components | Angular Material</a>. Zachęcam do przejrzenia listy i pobawienia się każdym komponentem.&nbsp;&nbsp;</p>



<h2 class="wp-block-heading" id="Jak-i-od-czego-zacząć-naukę?-">Jak i od czego zacząć naukę?&nbsp;</h2>



<p>Moim punktem startowym w nauce byłoby skupienie się na tych komponentach, które znajdują najczęstsze zastosowanie w aplikacjach. Chodzi mi tu przede wszystkim o komponenty służące do interakcji z użytkownikiem – takie jak przyciski, pola wyboru (checkboxy, selecty, radio buttony), pola tekstowe formularzy – oraz o te, które pełnią funkcję prezentacji danych, na przykład paski postępu (progress bary/spinnery), snackbary czy tabele.&nbsp;</p>



<p>Zachęcam do utworzenia własnego <strong><em>playgroundu </em></strong>w Angularze, gdzie krok po kroku możesz eksperymentować z każdym z wymienionych komponentów w praktyce. Angular Material zapewnia dostęp do różnorodnych schematów, które można wykorzystać do generowania kodu. Aby w łatwy sposób dodać proste menu nawigacyjne do aplikacji, skorzystaj z navigation schematic:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ng generate @angular/material:navigation navigation </pre>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image size-full">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/AngularMaterialPlayground-1.png" alt=" class=" class="wp-image-13499" title="Wprowadzenie do Angular Material design 4"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Z aplikacją przygotowaną w ten sposób i z otwartą dokumentacją Angular Material, przejdź przez wszystkie komponenty, zgłębiając ich funkcje i sposoby wykorzystania.&nbsp;</p>



<h2 class="wp-block-heading" id="własny-motyw-w-Angular-Material">Jak stworzyć własny motyw w Angular Material?&nbsp;</h2>



<p>Tworzenie własnego motywu w Angular Material to temat, który zasługuje na osobny artykuł. Niemniej, warto wiedzieć, że Angular Material umożliwia dostosowanie wyglądu komponentów do indywidualnych potrzeb.&nbsp;</p>



<h3 class="wp-block-heading">Przygotowanie motywu dla siebie&nbsp;</h3>



<p>Przed przystąpieniem do tworzenia własnego motywu upewnij się, że twoje style są zapisane w formacie SCSS, a także usuń z angular.json odniesienie do pliku CSS wybranego wcześniej motywu.&nbsp;</p>



<h3 class="wp-block-heading">Wprowadzenie i użycie customowego motywu&nbsp;</h3>



<p>Możesz to zrobić, ponownie wywołując komendę:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ng add @angular/material </pre>



<p>Jednak tym razem, przy wyborze motywu, wskaż custom.&nbsp;</p>



<p>Zaobserwujesz, że twój plik styles.scss został wzbogacony o nowe linijki kodu, które:&nbsp;</p>



<ul class="wp-block-list">
<li>Importują wymagane style i funkcje&nbsp;</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">- @use '@angular/material' as mat; 
- @include mat.core(); </pre>



<ul class="wp-block-list">
<li>Definiują zestaw kolorów dla komponentów przy użyciu istniejących palet&nbsp;</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$angular-material-primary: mat.define-palette(mat.$indigo-palette); 

$angular-material-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); 

$angular-material-warn: mat.define-palette(mat.$red-palette); </pre>



<ul class="wp-block-list">
<li>Definiują obiekt przechowujący wszystkie właściwości motywu&nbsp;</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$angular-material-theme: mat.define-light-theme(( 

  color: ( 

    primary: $angular-material-primary, 

    accent: $angular-material-accent, 

    warn: $angular-material-warn, 

  ) 

)); </pre>



<ul class="wp-block-list">
<li>Dołączają motyw do wszystkich komponentów wykorzystywanych w aplikacji&nbsp;</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@include mat.all-component-themes($angular-material-theme); </pre>



<p>W tym momencie jedyna różnica między wybranym wcześniej motywem a utworzonym nowym, customowym, opiera się na podstawowym zestawie kolorów.&nbsp;</p>



<h2 class="wp-block-heading" id="Konfiguracja-kolorów-">Konfiguracja kolorów&nbsp;</h2>



<p>W customowym motywie możesz zdefiniować trzy główne kolory:&nbsp;</p>



<ul class="wp-block-list">
<li>primary – jest to kolor, który pojawia się najczęściej w aplikacji&nbsp;</li>



<li>accent – kolor, którym będziesz akcentować wyróżniające się komponenty&nbsp;</li>



<li>Warn – kolor, który będzie zwracał uwagę, np. na błędy&nbsp;</li>
</ul>



<p></p>



<p>W tym celu możesz wykorzystać istniejące palety kolorów lub utworzyć własne. Ja skupię się na istniejących paletach, które możesz znaleźć tutaj: <a href="https://m1.material.io/style/color.html#color-color-palette" target="_blank" rel="noreferrer noopener">Color &#8211; Style &#8211; Material Design</a>&nbsp;</p>



<p>Aby użyć wybranej palety, wystarczy, że przy definicji koloru wprowadzisz jej nazwę w metodzie define-palette. Metoda ta pozwala na jeszcze dokładniejszą konfigurację kolorów, aby można było uzyskać pożądany efekt w aplikacji. Możesz bowiem dobrać konkretne kolory z danej palety tak, aby komponenty były pokolorowane w określony sposób:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">nenty były pokolorowane w określony sposób: 

@function define-palette($base-palette, $default: 500, $lighter: 100, $darker: 700, $text: $default) </pre>



<p>Czyli na przykład, jeśli chcesz, aby twój kolor primary był czerwony, ale jednocześnie preferujesz jaśniejsze odcienie czerwieni, możesz skonfigurować go w ten sposób, wybierając jaśniejsze odcienie czerwieni (200, 100, 300) dla wszystkich wariantów:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$angular-material-primary: mat.define-palette(mat.$red-palette, 200, 100, 300); </pre>



<p>Dzięki temu twój mat-raised-button w wybranym kolorze primary będzie wyglądał tak:&nbsp;</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Obraz1-1.png" alt=" class=" class="wp-image-13502" title="Wprowadzenie do Angular Material design 5"></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Jak pisałem wcześniej, temat tworzenia własnego motywu jest bardzo obszerny i zasługuje na osobny artykuł, dlatego chciałbym poprzestać na wprowadzeniu i zachęcie do wypróbowania możliwości. Natomiast jeśli udało mi się zainteresować cię tym tematem i chcesz zgłębić go bardziej, polecam ten przewodnik:&nbsp; <a href="https://material.angular.io/guide/theming" target="_blank" rel="noreferrer noopener">Theming Angular Material | Angular Material</a>&nbsp;</p>



<h2 class="wp-block-heading" id="Dlaczego-warto-tworzyć-aplikacje-z-tą-biblioteką-komponentów?-">Dlaczego warto tworzyć aplikacje z tą biblioteką komponentów?&nbsp;</h2>



<p>Zdecydowanie zachęcam do samodzielnego eksplorowania Angular Material.&nbsp;</p>



<p>Odkrywanie możliwości tej biblioteki na własną rękę może być nie tylko niezwykle rozwijające, ale również inspirujące. Praktyczne eksperymentowanie z różnymi komponentami, stylami i funkcjami pozwoli ci lepiej zrozumieć, jak można efektywnie wykorzystać Angular Material w projektach. Dodatkowo, samodzielne rozwiązywanie problemów i adaptacja komponentów do własnych potrzeb pomoże ci rozwinąć umiejętności i zwiększyć twoją pewność siebie w developmencie. Znajomość Angular Material otwiera drzwi do tworzenia bardziej zaawansowanych i estetycznie przyjemnych aplikacji webowych.&nbsp;</p>



<h2 class="wp-block-heading" id="Podsumowanie--">Podsumowanie&nbsp;&nbsp;</h2>



<p>Angular Material jest potężnym narzędziem, które umożliwia tworzenie zaawansowanych, atrakcyjnych i funkcjonalnych interfejsów użytkownika, jednocześnie upraszczając i przyspieszając proces tworzenia aplikacji webowych. Jeśli chcesz tworzyć funkcjonalne i estetyczne interfejsy użytkownika, wykorzystując w pełni możliwości nowoczesnych bibliotek, nie wahaj się wejść do fascynującego świata Angular Material!&nbsp;</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/angular-material-design-wprowadzenie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Zasady SOLID w programowaniu obiektowym</title>
		<link>https://nearshore-it.eu/pl/artykuly/zasady-solid-dobre-praktyki-w-programowaniu/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/zasady-solid-dobre-praktyki-w-programowaniu/#respond</comments>
		
		<dc:creator><![CDATA[Eryk Schubert]]></dc:creator>
		<pubDate>Wed, 17 May 2023 06:51:48 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/zasady-solid-dobre-praktyki-w-programowaniu/</guid>

					<description><![CDATA[Z pewnością każdy programista choć raz zastanawiał się nad tym, jak sprawić, aby jego kod był bardziej czytelny, a tworzony system – skalowalny i elastyczny. Z pomocą przychodzą zasady SOLID, które stanowią świetną podstawę w projektowaniu i implementacji systemów informatycznych. Dzięki nim nie musimy wymyślać wszystkiego od nowa, ponieważ zasady te mają sprawdzone narzędzia, które pozwalają nam na tworzenie optymalnego kodu.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">PRZEJDŹ DO:</p>
    <ol>
                    <li><a href="#kod">1.  Po pierwsze, czysty kod </a></li>
                    <li><a href="#programowaniu">2.  Czym jest SOLID w programowaniu? </a></li>
                    <li><a href="#SOLID">3.  Najważniejsze zasady SOLID </a></li>
                    <li><a href="#SOLID-–-przykłady-z-wykorzystaniem-Angularau002du002d">4.  SOLID – przykłady z wykorzystaniem Angulara  </a></li>
                    <li><a href="#Podsumowanieu002du002d">5.  Podsumowanie </a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="kod">Po pierwsze, czysty kod</h2>



<p>Pisanie czystego kodu (ang. <strong>clean code</strong>) powinno być kluczowym elementem w pracy każdego programisty. To właśnie czysty kod pozwala nam utrzymywać nasze systemy w dobrym stanie, zapewniając łatwość w utrzymaniu i rozwoju oraz większą elastyczność. Dlaczego jeszcze dbanie o czysty kod jest tak ważne? Według raportu „The state of software code&#8221;, <strong>40% developerów przyznaje, że najbardziej frustruje ich wykrywanie i naprawiane błędów w kodzie</strong>, co nieraz może przyczyniać się do przepracowania, a nawet wypalenia zawodowego. Nie wspominając o opóźnieniach w rozwoju oprogramowania.</p>



<p>Czysty kod to taki, który jest czytelny, łatwy do zrozumienia, modyfikacji i testowania. Łatwość w zrozumieniu kodu jest szczególnie ważna w przypadku większych projektów, gdzie nad tymi samymi plikami pracuje zwykle wiele osób. Zwłaszcza w tego typu projektach powinniśmy dążyć do tego, aby pisany przez nas kod był przejrzysty i klarowny, nawet dla osób, które nie pracowały nad danym projektem od samego początku. Tu z pomocą przychodzą zasady znane jako SOLID.</p>



<h2 class="wp-block-heading" id="programowaniu">Czym jest SOLID w programowaniu?</h2>



<p>SOLID to zestaw pięciu zasad, które zostały opracowane przez Roberta C. Martina, znanego jako „<strong>Uncle Bob</strong>”, w latach 90. XX wieku. Dzięki tym zasadom otrzymaliśmy narzędzia, które nie tylko pomagają w projektowaniu i implementacji systemów, ale także umożliwiają ich utrzymywanie, rozwój i skalowanie. Korzystanie z tych zasad często pozwala znacząco skrócić czas pracy nad projektem oraz zmniejszyć ilość błędów, co przekłada się na zwiększenie efektywności i jakości samego kodu.</p>



<h2 class="wp-block-heading" id="SOLID">Najważniejsze zasady SOLID</h2>



<p>W tym artykule o SOLID omówię zasady, na których opiera się filozofia pisania czystego kodu. SOLID to skrótowiec utworzony od pięciu zasad projektowania obiektowego, których celem jest ułatwienie modyfikowania, skalowania i utrzymywania kodu.&nbsp;</p>



<h3 class="wp-block-heading">Single Responsibility Principle&nbsp;</h3>



<p>Pierwszą z zasad SOLID jest zasada pojedynczej odpowiedzialności (ang. <strong>Single Responsibility Principle – SPR</strong>). Zgodnie z nią klasa powinna mieć tylko jedną odpowiedzialność, czyli powinna być odpowiedzialna tylko za jedną rzecz. O ile nie można jednoznacznie stwierdzić, która zasada SOLID jest najważniejsza, ponieważ każda zasada wpływa na jakość kodu w różny sposób, o tyle wielu programistów uważa, że to właśnie zasada pojedynczej odpowiedzialności jest absolutnym minimum, które każdy z nas powinien stosować w swoim kodzie.&nbsp;</p>



<h3 class="wp-block-heading">Open/Closed Principle&nbsp;</h3>



<p>Drugą ważną zasadą jest zasada otwarte/zamknięte (ang. <strong>Open/Closed Principle – OCP</strong>). Według tej zasady klasa powinna być otwarta na rozszerzanie, ale jednocześnie zamknięta na modyfikację. To oznacza, że gdy chcemy dodać nową funkcjonalność do naszej aplikacji, nie powinniśmy modyfikować istniejącego kodu, a jedynie dodawać nowy. Dzięki temu zmiany w jednej części systemu nie spowodują awarii w innych jego częściach.&nbsp;</p>



<h3 class="wp-block-heading">Liskov Substitution Principle&nbsp;</h3>



<p>Kolejną zasadą jest zasada podstawienia Liskov (ang. <strong>Liskov Substitution Principle – LSP</strong>). Zasada ta określa, że obiekty typu pochodnego powinny być zawsze zastępowalne przez obiekty typu bazowego. To oznacza, że klasa dziedzicząca powinna być w pełni zgodna z klasą, po której dziedziczy. Dzięki tej zasadzie możemy uniknąć błędów wynikających z niezgodności między klasami, a także ułatwić sobie przyszły rozwój aplikacji.&nbsp;</p>



<h3 class="wp-block-heading">Interface Segregation Principle&nbsp;</h3>



<p>Czwartą zasadą jest zasada segregacji interfejsów (ang. <strong>Interface Segregation Principle – ISP</strong>). Według niej interfejsy powinny być małe i jednorodne, a klienci powinni korzystać tylko z tych, których potrzebują. Oznacza to, że klasa powinna implementować tylko te metody, których potrzebuje, a więc interfejs nie powinien zmuszać jej do implementacji pozostałych metod. To pozwala uniknąć skomplikowania kodu.&nbsp;</p>



<h3 class="wp-block-heading">Dependency Inversion Principle&nbsp;</h3>



<p>Piątą i ostatnią zasadą SOLID jest zasada odwrócenia zależności (ang. <strong>Dependency Inversion Principle – DIP</strong>). Zgodnie z nią zależności między klasami powinny być odwrócone. Oznacza to, że klasy powinny zależeć od abstrakcji, a nie od konkretnych implementacji. Dzięki temu kod jest łatwiejszy do testowania i modyfikowania.&nbsp;&nbsp;</p>



<h3 class="wp-block-heading">Dlaczego zasady SOLID są tak ważne?&nbsp;&nbsp;</h3>



<p>Podsumowując, zasady SOLID są kluczowe dla tworzenia skalowalnych, elastycznych i łatwych w utrzymaniu aplikacji. Wymagają one od nas abstrakcyjnego myślenia, projektowania i wdrażania czytelnego kodu. Właściwe stosowanie zasad SOLID pozwala uniknąć licznych problemów, takich jak trudność we wprowadzaniu zmian i testowaniu czy nieczytelność i niejednoznaczność kodu.&nbsp;</p>



<p>W kolejnych rozdziałach skupię się na każdej z zasad SOLID, rozwinę ich znaczenie i omówię przykłady, dzięki czemu będziemy w stanie lepiej zrozumieć, jak można stosować je w praktyce.</p>



<p><strong>Przeczytaj także: </strong><a href="https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/">Który framework frontendowy jest najlepszy?</a></p>



<h2 class="wp-block-heading" id="SOLID-–-przykłady-z-wykorzystaniem-Angulara--">SOLID – przykłady z wykorzystaniem Angulara&nbsp;&nbsp;</h2>



<h3 class="wp-block-heading">Zasada pojedynczej odpowiedzialności&nbsp;</h3>



<p>Zasada pojedynczej odpowiedzialności ma na celu poprawę jakości kodu i ułatwienie jego rozwijania. Zgodnie z nią każdy element kodu powinien mieć tylko jedną odpowiedzialność, a zmiany w jednej funkcjonalności nie powinny wpływać na pozostałe. Innymi słowy, klasa, funkcja czy moduł powinny robić tylko to, do czego zostały stworzone i nie powinny mieć dodatkowych zadań, które nie są związane z ich główną odpowiedzialnością.&nbsp;&nbsp;</p>



<p>Zastosowanie zasady pojedynczej odpowiedzialności przynosi wiele korzyści. Przede wszystkim <strong>ułatwia utrzymywanie i rozwijanie kodu</strong>, ponieważ kod staje się bardziej modularny i łatwiej jest zidentyfikować miejsca, w których należy dokonać zmian. Ponadto, dzięki temu, że każdy element ma tylko jedną odpowiedzialność, łatwiej jest go testować i staje się on dużo bardziej zrozumiały dla innych programistów.&nbsp;</p>



<p>W jaki sposób możemy rozpoznać, że zasada pojedynczej odpowiedzialności nie jest spełniona? Często nie jest łatwo zidentyfikować miejsce, w którym kończy się odpowiedzialność jednego komponentu, a zaczyna drugiego. Z pomocą przychodzi reguła wykorzystująca spójnik “i”. Jeśli opisując odpowiedzialność danego elementu użyjemy słowa “i”, możemy potraktować to jako sygnał, że nasz element zajmuje się zbyt wieloma rzeczami – jego odpowiedzialność nie jest pojedyncza.&nbsp;&nbsp;</p>



<p>Zarówno ten przykład, jak i wszystkie kolejne będą napisane we frameworku Angular. Weźmy komponent <strong>DataComponent</strong>, którego zadaniem jest pobranie danych z serwera <strong>i</strong> ich przetworzenie <strong>i </strong>ich wyświetlenie. W opisie odpowiedzialności natrafiliśmy na słowo “i”, co może oznaczać, że będziemy potrzebowali udoskonalić nasz kod.&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Component({ 

  selector: 'app-data', 

  template: ` 

    &lt;ul> 

      &lt;li *ngFor="let item of items"> 

        {{ item }} 

      &lt;/li> 

    &lt;/ul> 

  `, 

}) 

export class DataComponent implements OnInit { 

  items: string[] = []; 

 

  constructor(private http: HttpClient) {} 

 

  ngOnInit(): void { 

    this.http.get&lt;Item[]>('http://example.com/data').subscribe((data: Item[]) => { 

      this.items = data.map((item) => item.name.toUpperCase()); 

    }); 

  }   

}</pre>



<p>I faktycznie takie podejście łamie zasadę pojedynczej odpowiedzialności, ponieważ komponent ten powinien być odpowiedzialny tylko za prezentację danych. Aby go poprawić i spełnić zasadę pojedynczej odpowiedzialności, możemy wydzielić logikę pobierania danych i ich przetwarzania do oddzielnych serwisów. Nasz komponent i wydzielone serwisy będą wtedy wyglądały tak:&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Component({ 

  selector: 'app-data', 

  template: ` 

    &lt;ul> 

      &lt;li *ngFor="let item of items"> 

        {{ item }} 

      &lt;/li> 

    &lt;/ul> 

  `, 

}) 

export class DataComponent implements OnInit { 

  items: string[] = []; 

 

  constructor(private itemsService: ItemsService,  

    private dataService: DataService) {} 

 

  ngOnInit(): void { 

    this.itemsService.getItems().subscribe((items) => { 

      this.items = this.dataService.processData(items); 

    }); 

  }   

} 

 

@Injectable() 

export class ItemsService { 

  constructor(private http: HttpClient) { } 

 

  getItems(): Observable&lt;Item[]> { 

    return this.http.get&lt;Item[]>('http://example.com/data'); 

  } 

} 

 

@Injectable() 

export class DataService { 

  processData(data: Item[]): string[] { 

    return data.map((item) => item.name.toUpperCase()); 

  } 

}</pre>



<p>Dzięki takiemu podejściu odpowiedzialność została rozproszona, a każdy z obiektów ma tylko jedną.&nbsp;</p>



<ul class="wp-block-list">
<li>Komponent <strong>DataComponent</strong> zajmuje się tylko prezentacją danych,&nbsp;</li>



<li>Serwis<strong> ItemsService</strong> odpowiedzialny jest tylko za pobranie danych,&nbsp;</li>



<li>Serwis <strong>DataService</strong> zawiera tylko logikę przetwarzania danych.&nbsp;</li>
</ul>



<p></p>



<p>Dzięki takiemu podziałowi jesteśmy w stanie w bardzo łatwy sposób przygotować wymagane testy, a także w przyszłości będziemy w stanie szybko zlokalizować miejsca, które potencjalnie będą mogły wymagać jakichś zmian lub udoskonaleń.&nbsp;</p>



<p>Wniosek jest taki, że zasada pojedynczej odpowiedzialności jest <strong>kluczowa dla tworzenia czytelnego i łatwego w utrzymaniu kodu</strong>. Przez wielu programistów uważana jest za najważniejszą spośród wszystkich zasad SOLID. Poprawne jej zrozumienie i stosowanie pozwalają na łatwiejsze rozwijanie oprogramowania oraz zmniejszenie ryzyka pojawienia się błędów w kodzie.&nbsp;</p>



<h3 class="wp-block-heading">Zasada otwarte/zamknięte&nbsp;</h3>



<p>Zasada ta pomaga w tworzeniu kodu, który jest bardziej elastyczny i łatwiejszy do rozbudowy. Dzięki niej możemy dodawać nowe funkcje bez obawy o to, że wprowadzimy błędy w już istniejącym kodzie.&nbsp;&nbsp;</p>



<p>„<strong>Tworzone moduły powinny być otwarte na rozbudowę</strong>” &#8211; ale jak to rozumieć? Oznacza to tyle, że gdy chcemy wprowadzić nową funkcjonalność do aplikacji, nie powinniśmy modyfikować już istniejącego kodu, tylko dodawać nowy kod, a istniejące moduły powinny to umożliwiać. W ten sposób nowa funkcjonalność może zostać dodana bez wpływu na dotychczasowe działanie aplikacji.&nbsp;&nbsp;</p>



<p>Aby spełnić tę zasadę, warto w kodzie wykorzystywać zalety programowania obiektowego, czyli mechanizmy dziedziczenia, polimorfizmu i interfejsów. Dzięki nim możemy oddzielić kod, który się zmienia, od kodu, który pozostaje stały.&nbsp;</p>



<p>Zasada otwarte/zamknięte jest szczególnie ważna w dużych projektach, w których każda zmiana w kodzie może przynieść nieoczekiwane skutki uboczne i prowadzić do błędów. Dzięki spełnieniu tej zasady możemy uniknąć tych problemów i tworzyć bardziej niezawodne oprogramowanie.&nbsp;</p>



<p>Powinniśmy stosować tę zasadę również wtedy, kiedy tworzymy nową bibliotekę. Z założenia użytkownicy naszej biblioteki nie będą mogli wprowadzać w niej zmian, lecz byłoby dobrze, aby tam, gdzie miałoby to sens, w jakiś sposób byli w stanie rozszerzać jej możliwości w swoim projekcie.&nbsp;&nbsp;</p>



<p>Jako przykład weźmy serwis <strong>PaymentService</strong> do przetwarzania płatności:&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Injectable() 

export class PaymentService {   

  processPayment(paymentMethod: string): void { 

    switch (paymentMethod) { 

        case 'creditCard': 

            this.processCreditCardPayment(); 

            break; 

        case 'cashOnDelivery': 

            this.processCashOnDeliveryPayment(); 

            break;     

        default: 

            throw new Error('Unsupported payment method'); 

    } 

  } 

 

  private processCreditCardPayment(): void { 

    // logika przetwarzania płatności kartą kredytową 

  } 

 

  private processCashOnDeliveryPayment(): void { 

    // logika przetwarzania płatności przy odbiorze 

  } 

}</pre>



<p>Serwis ten łamie zasadę otwarte/zamknięte, ponieważ implementacja nowej metody płatności wymagałaby od nas wprowadzenia zmian w samym serwisie. Zamiast tego powinniśmy przygotować serwis w taki sposób, aby nowe metody płatności mogły być dodawane bez ingerencji w jego kod.&nbsp;</p>



<p>Możemy to zrobić, przygotowując interfejs <strong>PaymentMethod</strong>, który będzie implementowany przez nowe metody płatności, a same metody płatności będą przekazywane jako argument do funkcji <strong>processPayment</strong>.&nbsp;</p>



<p>Nowy serwis<strong> PaymentService</strong> wraz z interfejsem <strong>PaymentMethod</strong> i kolejnymi metodami płatności wyglądałyby tak:&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Injectable() 

export class PaymentService { 

  processPayment(paymentMethod: PaymentMethod): void { 

    paymentMethod.processPayment(); 

  } 

} 

 

interface PaymentMethod { 

  processPayment(): void; 

} 
 

@Injectable() 

export class CreditCardService implements PaymentMethod { 

  processPayment(): void { 

    // logika przetwarzania płatności kartą kredytową 

  } 

} 
 

@Injectable() 

export class CashOnDeliveryService implements PaymentMethod { 

  processPayment(): void { 

    // logika przetwarzania płatności przy odbiorze 

  } 

} 
 

@Injectable() 

export class PaypalService implements PaymentMethod { 

  processPayment(): void { 

    // logika przetwarzania płatności Paypal 

  } 

} 

 

// ... </pre>



<p>Dzięki temu każdą nową metodę płatności możemy dodać, tworząc nową klasę implementującą interfejs <strong>PaymentMethod</strong>. Tym samym nie musimy wprowadzać zmian w serwisie <strong>PaymentService</strong>, a co za tym idzie, spełnia on teraz zasadę otwarte/zamknięte.&nbsp;&nbsp;</p>



<p>Podsumowując, zasada otwarte/zamknięte zakłada, że klasy powinny być otwarte na rozszerzanie, ale zamknięte na modyfikację. Oznacza to, że nowe funkcjonalności należy wprowadzać nie poprzez wprowadzanie zmian w istniejących elementach programu, lecz za pomocą dodawania nowych klas i modułów. Poprawne zastosowanie tej zasady może przyczynić się do zwiększenia elastyczności kodu oraz zmniejszenia ilości błędów w trakcie tworzenia aplikacji.&nbsp;</p>



<h3 class="wp-block-heading">Zasada podstawienia Liskov&nbsp;</h3>



<p>Zasada podstawienia Liskov mówi o tym, że<strong> powinniśmy mieć możliwość zastąpienia klasy bazowej klasą dziedziczącą bez zmiany działania programu</strong>. Innymi słowy, jeśli klasa A dziedziczy po klasie B, to powinno być możliwe użycie klasy A zamiast obiektu klasy B, a program nadal powinien działać poprawnie. W mojej opinii jest to najbardziej skomplikowana zasada spośród wszystkich zasad SOLID.&nbsp;</p>



<p>Zasada ta umożliwia łatwe dodawanie nowych funkcjonalności do istniejącego już kodu. Klasa dziedzicząca po klasie bazowej może wprowadzać nowe funkcjonalności, ale musi zachowywać interfejs klasy bazowej. Dzięki temu aplikacja może korzystać z obiektów klas dziedziczących jak z obiektów klasy bazowej, co umożliwia łatwe rozszerzanie funkcjonalności.&nbsp;</p>



<p>Zasada ta została sformułowana przez Barbarę Liskov w latach 80. XX wieku i była pierwotnie stosowana w językach programowania proceduralnego. Z czasem stała się równie ważna w kontekście programowania obiektowego.&nbsp;</p>



<p>Jako przykład utworzymy komponent <strong>BirdComponent</strong>, w ramach którego będziemy chcieli wyprowadzać nasze ptaki „na spacer”. Stworzymy zatem klasę bazową <strong>Bird </strong>i dla przykładu spróbujemy utworzyć dla niej jakąś klasę dziedziczącą.&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Bird { 

  fly(distance: number): void { 

    console.log(`Bird flew ${distance} meters`); 

  } 

} 

 

class Penguin extends Bird { 

  fly(distance: number): void { 

    throw new Error('Penguins do not fly'); 

  } 

} 
 

@Component({ 

  selector: 'app-bird', 

  template: `&lt;p>Bird Component&lt;/p>` 

}) 

export class BirdComponent implements OnInit { 

  ngOnInit(): void { 

    const bird = new Penguin(); 

    this.takeToFly(bird, 10);   

  } 
 

  takeToFly(bird: Bird, distance: number) { 

    bird.fly(distance); 

  } 

} </pre>



<p>Możemy zaobserwować, że zasada podstawienia Liskov została tutaj złamana, ponieważ kiedy wywołamy metodę <strong>takeToFly </strong>dla obiektu typu dziedziczącego <strong>Penguin</strong>, nie otrzymamy tego samego, oczekiwanego rezultatu, jaki chcielibyśmy uzyskać, gdybyśmy wywołali tę samą metodę dla obiektu typu bazowego <strong>Bird</strong>.&nbsp;</p>



<p>A w jaki sposób zasada umożliwia łatwe dodawanie nowych funkcjonalności? Zmienimy trochę przykład i założymy, że nie wszystkie ptaki latają, ale wszystkie potrafią śpiewać. Utworzymy znów klasę bazową <strong>Bird </strong>i dodamy do niej klasę dziedziczącą, która tym razem będzie implementować poprawnie wszystkie metody z klasy <strong>Bird</strong>, ale również dodawać nowe.&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Bird { 

    sing(lyrics: string): void { 

        console.log(`Bird sang ${lyrics} beautifully`); 

    } 

} 
 

class FlyingBird extends Bird { 

    fly(distance: number): void {  

        console.log(`Bird flew ${distance} meters`);      

    }  

} 
 

@Component({ 

    selector: 'app-bird', 

    template: `&lt;p>Bird Component&lt;/p>` 

}) 

export class BirdComponent implements OnInit { 

    ngOnInit(): void { 

        const bird = new FlyingBird(); 

        this.makeBirdSign(bird, "We are the champions!"); 

    } 
 

    makeBirdSign(bird: Bird, lyrics: string) { 

        bird.sing(lyrics); 

    } 

} </pre>



<p>Zgodnie z zasadą podstawienia Liskov &#8211; <strong>FlyingBird</strong> zachowuje się tak samo jak <strong>Bird</strong>, a ma dodatkową funkcjonalność. W rezultacie w kodzie, który do tej pory korzystał z typu <strong>Bird</strong>, możemy użyć typu <strong>FlyingBird</strong>. Ptak jest w stanie dodatkowo latać, a istniejący kod nie został popsuty.&nbsp;</p>



<p>Podsumowując, zasada podstawiania Liskov to ważna zasada programowania obiektowego, która zapewnia, że nasz kod jest elastyczny, łatwy w utrzymaniu i testowaniu oraz spełnia wysokie standardy jakościowe, a stosowana poprawnie, pomaga uniknąć błędów.</p>



<p><strong>Przeczytaj także: </strong><a href="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/">Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS</a></p>



<h3 class="wp-block-heading">Zasada segregacji interfejsów&nbsp;</h3>



<p>Celem tej zasady jest zwiększenie elastyczności, łatwości w utrzymaniu i rozwoju oprogramowania. Mówi ona, że „<strong>klient nie powinien być zmuszony do zależności od interfejsów, których nie używa</strong>”.&nbsp;</p>



<p>Zgodnie z nią nie powinno być jednego dużego interfejsu, który jest implementowany przez wszystkie klasy, gdy tylko część z jego metod jest potrzebna w danym kontekście. Zamiast tego interfejsy powinny być podzielone na mniejsze i bardziej konkretne, które są bardziej dostosowane do potrzeb klientów.&nbsp;</p>



<p>Ta zasada jest ważna, ponieważ pozwala nam na utrzymanie czystości kodu oraz zwiększenie jego czytelności i zrozumiałości. Dzięki temu, że każda klasa implementuje tylko te metody, które są jej potrzebne, kod staje się bardziej modułowy i łatwiejszy w utrzymaniu.&nbsp;</p>



<p>Powinniśmy używać tej zasady zwłaszcza wtedy, kiedy projektujemy interfejsy, które mają być implementowane przez wiele klas. W szczególności, gdy interfejs jest zbyt duży, powinien być rozbity na mniejsze interfejsy, aby uniknąć sytuacji, w której klasy są zmuszone implementować metody, których nie potrzebują.&nbsp;</p>



<p>Jako przykład, załóżmy, że chcemy utworzyć strony w naszej aplikacji oraz aby komponenty reprezentujące strony miały tę samą strukturę. Stwórzmy zatem interfejs <strong>PageContent</strong> i zaimplementujemy go w naszym komponencie.&nbsp;&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> 
export interface PageContent { 

    id: string; 

    content: string; 

    loading: boolean; 

    load(): void; 

} 
 

@Component({ 

    selector: 'app-errors', 

    template: `&lt;p>Erros Component&lt;/p>` 

}) 

export class ErrorsComponent implements PageContent { 

    id = "; 

    content = "; 

    loading = false; 

    load(): void { 

        // Logika ładowania strony... 

    } 

} </pre>



<p>Dodaliśmy przy okazji logikę ładowania strony, która mogłaby zawierać np. animację ładowania. Nasz interfejs gwarantuje, że każdy komponent, który go implementuje, będzie działał prawidłowo. Załóżmy teraz, że dostaliśmy zadanie, aby utworzyć nową stronę, która będzie przechowywała stałą zawartość. Oznacza to, że w komponencie nie potrzebujemy już mechanizmu ładowania. Chcąc zaimplementować ten sam interfejs, musielibyśmy zostawić metodę <strong>load </strong>pustą, a w naszym komponencie musielibyśmy utworzyć metodę, której nie potrzebujemy. I dlatego ten przykład łamie zasadę segregacji interfejsów.&nbsp;&nbsp;</p>



<p>Aby go poprawić, powinniśmy wydzielić dodatkowy interfejs, który służyłby nam do ładowania stron, i użyć go wszędzie tam, gdzie tego potrzebujemy. Pozostałe strony implementowałyby inny interfejs, z którego wycięlibyśmy mechanizm ładowania strony. W ten sposób:&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">export interface PageContent { 

    id: string; 

    content: string; 

} 
 

export interface PageLoad { 

    loading: boolean; 

    load(): void; 

} 
 

@Component({ 

    selector: 'app-errors', 

    template: `&lt;p>Erros Component&lt;/p>` 

}) 

export class ErrorsComponent implements PageContent, PageLoad { 

    id = "; 

    content = "; 

    loading = false; 

    load(): void { 

        // Logika ładowania strony... 

    } 

} 
 

@Component({ 

    selector: 'app-static', 

    template: `&lt;p>Static Component&lt;/p>` 

}) 

export class StaticComponent implements PageContent { 

    id = "; 

    content = "; 

} </pre>



<p>Dzięki temu interfejsy zostały posegregowane, a komponenty nie muszą implementować metod, których nie potrzebują. Tym samym zasada segregacji interfejsów została spełniona.&nbsp;</p>



<p>Podsumowując, każda klasa powinna implementować tylko te metody, które są jej potrzebne. Dzięki temu kod staje się bardziej modułowy i łatwiejszy w utrzymaniu. Zasada segregacji interfejsów jest szczególnie ważna, gdy projektujemy interfejsy, które mają być implementowane przez wiele klas. Poprawne stosowanie tej zasady pozwala na stworzenie bardziej elastycznego i czytelnego kodu.&nbsp;</p>



<h3 class="wp-block-heading">Zasada odwracania zależności&nbsp;</h3>



<p>Zasada ta głosi, że moduły wysokiego poziomu nie powinny zależeć od modułów niskiego poziomu, a oba rodzaje modułów powinny zależeć od abstrakcji. Innymi słowy, <strong>powinniśmy unikać silnych zależności między modułami,</strong> a zamiast tego wykorzystywać abstrakcję i interfejsy.&nbsp;</p>



<p>Zasadę odwracania zależności należy stosować w sytuacjach, gdy mamy do czynienia z kodem, w którym jedna część aplikacji jest mocno powiązana z inną i trudno jest ją zrefaktoryzować lub zmienić. W takiej sytuacji należy rozważyć zastosowanie abstrakcji i interfejsów, które pozwolą na łatwiejszą wymianę jednej części aplikacji na inną bez konieczności modyfikowania całej reszty kodu.&nbsp;</p>



<p>Innym ważnym aspektem zasady odwracania zależności jest to, że umożliwia ona pisanie kodu, który jest bardziej elastyczny i łatwiejszy w utrzymaniu. Dzięki zastosowaniu abstrakcji i interfejsów nasza aplikacja staje się bardziej modularna, co ułatwia jej rozwijanie i testowanie.&nbsp;</p>



<p>Sprawdźmy, jak dobrze jest to zrobione w Angularze. Jeśli postanowimy stworzyć serwis i wstrzyknąć go w naszym komponencie, Angular sprawi, że ten <strong>komponent nie będzie zależny od konkretnej implementacji</strong> tego serwisu, a jedynie od jego abstrakcji. Oznacza to, że będziemy mogli w każdej chwili dostarczyć inną jego implementację. Dzięki temu Angular automatycznie poniekąd zapewnia, że zasada odwracania zależności jest spełniona. Spójrzmy na przykład.&nbsp;</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Component({ 

    selector: "app-some-component", 

    providers: [ 

       provide: SomeService, 

       useClass: SomeImplementationOfSomeService 

    ] 

}) 

export class SomeComponent implements OnInit { 

    constructor(private someService: SomeService) {} 

 

    ngOnInit(): void { 

        this.someService.someMethod(); 

    } 

} </pre>



<p>Dzięki sekcji <strong>providers </strong>i parametrowi <strong>useClass </strong>możemy podstawić dowolną implementację serwisu <strong>SomeService </strong>w każdym komponencie, w którym tego potrzebujemy. Jeśli tego nie zrobimy, komponent wykorzysta domyślną implementację serwisu. Moglibyśmy pójść o krok dalej i potraktować <strong>SomeService </strong>z założenia abstrakcyjnie, czyli nie przywiązywać się nigdzie do jego domyślnej implementacji i wtedy w każdym module/komponencie podstawiać interesującą nas implementację w zależności od kontekstu i wymagań.&nbsp;</p>



<p>Podsumowując, zasada odwracania zależności jest kluczowa dla tworzenia kodu, który jest łatwiejszy w utrzymaniu, bardziej elastyczny i modułowy. Stosowanie abstrakcji i interfejsów pozwala nam uniknąć silnych zależności między różnymi częściami aplikacji i ułatwia nam wymianę jednej implementacji na inną.&nbsp;</p>



<p>Ważne jest również, aby pamiętać, że zasada odwracania zależności nie oznacza całkowitego uniezależnienia od konkretnej implementacji. Często potrzebujemy konkretnej implementacji, ale dzięki zastosowaniu abstrakcji i interfejsów możemy łatwo zamienić jedną implementację na inną, bez potrzeby zmieniania całego kodu.&nbsp;</p>



<p><strong>Przeczytaj także:</strong><a href="/?p=6617" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/" rel="noreferrer noopener"><strong> </strong>Jeśli nie&nbsp;Redux, to&nbsp;co?&nbsp;Zarządzanie stanem aplikacji w&nbsp;React</a></p>



<h2 class="wp-block-heading" id="Podsumowanie--">Podsumowanie&nbsp;&nbsp;</h2>



<p>Zasady SOLID w programowaniu obiektowym to nie tylko teoria, ale przede wszystkim praktyka, która zmienia sposób, w jaki tworzymy oprogramowanie. Ich stosowanie <strong>zapewnia łatwiejsze utrzymanie i rozwijanie kodu, zwiększa elastyczność, ułatwia testowanie</strong>, a także <strong>przyczynia się do zmniejszenia kosztów</strong> i czasu potrzebnego na późniejsze modyfikacje.&nbsp;</p>



<p>Dzięki nim unikamy powszechnych problemów w projektowaniu, takich jak klasyczny problem „<strong>spaghetti code</strong>”, w którym często trudno jest zrozumieć zależności między klasami. Zasady SOLID zapewniają lepszą separację zadań, co ułatwia pracę w zespole oraz pozwala na tworzenie bardziej modułowego kodu. Kod, który jest łatwy w utrzymaniu i testowaniu, jest też bardziej stabilny i odporny na błędy. A to z kolei przekłada się na mniejszą liczbę błędów w produkcie końcowym oraz mniejsze ryzyko opóźnień w projekcie.&nbsp;</p>



<p>Na koniec warto wspomnieć, że zasady SOLID nie są czymś, co zawsze należy stosować w 100%. Są to narzędzia, które można dostosować do konkretnych potrzeb projektu. Ważne jest jednak, by pamiętać o ich istnieniu i korzystać z nich, gdy tylko jest to możliwe.&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/zasady-solid-dobre-praktyki-w-programowaniu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
