Hello, I'm Mateusz Roth. Welcome to my blog. I'm open-minded Software Engineer that loves learning. Specialized in web apps and JavaScript, experienced in mobile dev, interested in Node.js, frontend and UX but also feels good with other programming languages like Swift, Kotlin, ObjC, Android, C#; eager to learn and work with Python, Golang, Node.js microservices or IoT.

[DRAFT] OOP - SOLID

Examples with JS code

S - SRP - Single Responsibility Principle

  • class should have just a one purpose - so for example Animal class shouldn’t perform logs to different outputs or shouldn’t perform a role of database of animals
  • don’t:
1
2
3
4
5
class Animal {
constructor(name: string) {}
getAnimalName() {}
saveAnimal(a: Animal) {}
}
  • do:
1
2
3
4
5
6
7
8
class Animal {
constructor(name: string) {}
getAnimalName() {}
}
class AnimalDB {
getAnimal(a: Animal) {}
saveAnimal(a: Animal) {}
}
  • animal class shouldn’t be responsible for database management like saving

O - OCP - Open/Closed Principle

  • classes should be open for extensions (new methods) but closed for modifications (don’t change method) - I’d say, you can change methods but not the contract what they receive and return
  • I’d say this role is more about abstraction and use of inheritance, for example by having a base class Animal with method makeSound, which is going to be implemented by child classes Lion or Snake
  • don’t:
1
2
3
4
5
6
7
8
9
10
11
12
//...
function AnimalSound(a: Array<Animal>) {
for(int i = 0; i <= a.length; i++) {
if(a[i].name == 'lion')
log('roar');
if(a[i].name == 'mouse')
log('squeak');
if(a[i].name == 'snake')
log('hiss');
}
}
AnimalSound(animals);
  • You see, for every new animal, a new logic is added to the AnimalSound function. This is quite a simple example. When your application grows and becomes complex, you will see that the if statement would be repeated over and over again in the AnimalSound function each time a new animal is added, all over the application. Do instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Animal {
makeSound();
//...
}
class Lion extends Animal {
makeSound() {
return 'roar';
}
}
class Squirrel extends Animal {
makeSound() {
return 'squeak';
}
}
class Snake extends Animal {
makeSound() {
return 'hiss';
}
}
//...
function AnimalSound(a: Array<Animal>) {
for(int i = 0; i <= a.length; i++) {
log(a[i].makeSound());
}
}
AnimalSound(animals);
  • another example:
1
2
3
4
5
6
7
8
9
10
class Discount {
giveDiscount() {
if (this.customer == "fav") {
return this.price * 0.2;
}
if (this.customer == "vip") {
return this.price * 0.4;
}
}
}
  • do instead:
1
2
3
4
5
6
7
8
9
10
11
class Discount {
giveDiscount() {
return this.price * 0.2;
}
};

class VIPDiscount: Discount {
getDiscount() {
return super.getDiscount() * 2;
}
};

L - LSP - Liskov Substitution Principle

  • if something uses a class, it should be able to use the class and the base class / child class of it
  • sub-class must be substitutable for its super-class
  • PL: nie sprawdzamy typu klasy, wykorzystujemy metody wirtualne i implementujemy je różnie w róznych klasach, ale wywołujemy tak samo

I - ISP - Interface Segregation Principle

  • you should write few interfaces instead of a big one interface that contains all the interfaces
  • make fine grained interfaces that are client specific
  • clients should not be forced to depend upon interfaces that they do not use
  • PL: nie tworzymy metod, których nie będziemy mogli zaimplementować w klasach korzystających z interfejsu, np. przykład z draw vs drawCircle, drawTriangle

D - DIP - Dependency Inversion Principle

  • you should create new class by placing in the constructor of it the interface of a class that the new class depends on
  • PL: polegamy na interfejsach, nie ich implementacjach - aby można było podmienić lub zamockować

[DRAFT] [PL] C# & OOP

Poniższe notatki to głównie skrót i spis pojęć z kursu dostępnego na stronie https://www.plukasiewicz.net/CSharp_dla_poczatkujacych/Ogolnie_o_jezyku i https://www.plukasiewicz.net/Csharp_dla_zaawansowanych/Atrybuty , uzupełniony o inne źródła.

Cechy C#:

  • warunki logiczne (boolean conditions)
  • garbage collector
    • TODO: jak działa?
  • standardowe biblioteki
    • TODO: na przykład jakie?
  • właściwości i zdarzenia (properties, events)
  • delegaty oraz zarządzanie zdarzeniami (Delegates, Events Management)
  • łatwość używania typów generycznych (Generics)
  • kompilacja warunkowa
  • wielowątkowość
  • LINQ i wyrażenia lambda (lambda expressions)
  • deklaracje przestrzeni nazw

Część 1

https://www.plukasiewicz.net/CSharp_dla_poczatkujacych/Ogolnie_o_jezyku

Notatki z C#:

  • główna metoda całego programu to Main

Podstawowe części języka:

  • instrukcje i wyrażenia
  • komentarze
  • kompilowanie i wykonywanie
  • słowa kluczowe

Typy:

  • typy wartościowe (value types) - w tym również struct
  • typy referencyjne (reference types)
  • typy wskaźnikowe (pointer types)
  • konwersja niejawna (implicit type conversion)
  • konwersja jawna (explicit type conversion)
  • zmienne, typy integralne (integral types)
  • typy zmiennoprzecinkowe (floating point types)
  • typy dziesiętne (decimal types)
  • typy logiczne (boolean types)
  • typy puste (nullable types)

Stałe i literały:

  • Stałe odnoszą się do wartości, których program nie może zmieniać w trakcie wykonywania. Te stałe wartości nazywane są również literałami. Stałe traktowane są jak zwykłe zmienne z zaznaczeniem, że ich wartości nie mogą być modyfikowane.
  • literały całkowite (integer literals)
  • literały zmiennoprzecinkowe (floating-point literals)
  • literały znakowe (character literals)
  • literały łańcuchowe (string literals)

Operatory:

  • operatory arytmetyczne
  • operatory relacyjne
  • operatory logiczne
  • operatory bitowe
  • operatory przypisania
  • różne inne operatory

Sterowanie:

  • instrukcja warunkowa if
  • instrukcja warunkowa if..else
  • zagnieżdżona instrukcja warunkowa if
  • instrukcja wyboru switch
  • zagnieżdżona instrukcja wyboru switch
  • pętla while
  • pętla for
  • pętla do..while
  • polecenie break
  • polecenie continue

Parametry, inne typy i tablice:

  • parametry typu wartościowego, referencyjnego, wyjściowego
  • typy puste
  • tablice wielowymiarowe
  • tablice postrzępione
  • klasa Array

Klasy:

  • Klasa może dziedziczyć z jednej klasy, ale może implementować wiele interfejsów
  • metody klasy (methods)
  • pola klasy (fields)
  • właściwości klasy (properties) - Właściwości nie służą do przechowywania wartości. Przy pomocy accesorów mają dostęp do pól, które reprezentują.

Class member, np. pole lub metoda

Class members, in C#, are the members of a class that represent the data and behavior of a class.

Class members are members declared in the class and all those (excluding constructors and destructors) declared in all classes in its inheritance hierarchy.

Class members can be of the following types:

  • Constants representing constant values
  • Fields representing variables
  • Methods providing services like calculation or other actions on its members
  • Properties that define the class features and include actions to fetch and modify them
  • Events generated to communicate between different classes /objects
  • Indexers that help in accessing class instances similar to arrays
  • Operators that define semantics when used in expressions with class instances
  • Instance constructors to initialize members of class instances
  • Static constructor to initialize the class itself
  • Destructors to execute actions necessary to be performed before class instances are discarded
  • Types that are local to the class (nested type)

Class members are initialized in constructors which can be overloaded with different signatures. For classes that do not have constructor, a default constructor that initializes the class members (to default values) will be generated.

Source: https://www.techopedia.com/definition/25589/class-members-c-sharp


Dalej o klasach:

  • instancje klasy
  • hermetyzacja/enkapsulacja, inaczej data hiding (or more accurately encapsulation)
  • modyfikatory dostępu w C# jako część hermetyzacji - public, private, protected, internal, protected internal
  • typy wyliczeniowe enum - wartościowy typ danych - wartości, których nie można dziedziczyć oraz przekazać przez dziedzicznie
1
2
3
4
5
6
7
8
9
10
enum DniTygodnia
{
Poniedzialek = 1,
Wtorek,
Sroda,
Czwartek,
Piatek,
Sobota,
Niedziela
}
  • struktury struct - W języku C# struktura to wartościowy typ danych.

Klasy i struktury mają następujące różnice:

  • klasy są typem referencyjnym a struktury typem wartościowym;
  • struktury nie wspierają dziedziczenia;
  • struktury nie mogą mieć domyślnego konstruktora.

Dalej o klasach:

  • konstruktor i destruktor klasy
  • statyczne składniki klasy

Składniki statyczne możemy zdefiniować za pomocą słowa kluczowego static. Jeżeli zadeklarujemy składową jako statyczną nie ważne jak wiele obiektów klasy utworzymy, istnieje zawsze tylko jedna kopia składowej statycznej.

  • klasa statyczna

Możemy utworzyć statyczną klasę. Klasa taka mówi, iż nie została napisana po to, aby tworzyć nowe obiekty. Nawet, gdybyśmy chcieli utworzyć nowy obiekt klasy statycznej kompilator zgłosi błąd. Mogą być wywołane bez tworzenia instancji danej klasy.

  • dziedziczenie - inheritance
  • klasa bazowa i pochodna - base/parent and derived/child class
  • polimorfizm - polymorphism
  • statyczny polimorfizm, tj. przeciążanie metod i przeciążanie operatorów
  • polimorfizm dynamiczny, czyli klasy abstrakcyjne i metody wirtualne

Polimorfizm dynamiczny jest realizowany za pomocą klas abstrakcyjnych oraz metod wirtualnych. Metoda może mieć różne implementacje dla różnych klas.


Klasa abstrakcyjna. Klasa taka zawiera abstrakcyjne metody, których implementacja zależy od wykorzystania w poszczególnych klasach pochodnych.

Poniżej lista zasad, o których należy pamiętać, tworząc klasy abstrakcyjne:

  • nie można utworzyć instancji klasy abstrakcyjnej;
  • nie można zadeklarować metody abstrakcyjnej poza klasą abstrakcyjną;
  • kiedy klasa opatrzona jest modyfikatorem dostępu sealed nie może być dziedziczona. Dodatkowo, klasa abstrakcyjna nie może być zdefiniowana jako sealed.

  • metody wirtualne

Jeżeli masz zdefiniowaną metodę w klasie bazowej, ale chcesz, żeby została zaimplementowana w klasach pochodnych możesz do tego celu zastosować metody wirtualne.

  • interfejsy

Język C# nie obsługuje wielokrotnego dziedziczenia. Klasa może dziedziczyć po jednej klasie bazowej, ale może implementować wiele interfejsów.

Inne cechy C#:

  • przestrzenie nazw
  • dyrektywy preprocesora
  • wyrażenia regularne
  • obsługa wyjątków
  • odczyt i zapis pliku

Część 2

https://www.plukasiewicz.net/Csharp_dla_zaawansowanych/Atrybuty

Indeksery:

Delegaty:

  • https://www.plukasiewicz.net/Csharp_dla_zaawansowanych/Delegaty
  • Delegaty to referencyjny typ danych, który przechowuje referencje do metody.
  • Delegaty złożone - Delegat złożony wywołuje dwa delegaty tak jakby były złączone. Operacja taka to tzw. multicasting.
  • W JS nie ma typu delegatów, przekazujemy funkcje przez referencje do zmiennej.

Zdarzenia:

Kolekcje:

Typy generyczne:

  • https://www.plukasiewicz.net/Csharp_dla_zaawansowanych/Typy_generyczne
  • Typy generyczne pozwalają na opóźnienie w dostarczeniu specyfikacji typu danych w elementach takich jak klasy czy metody do momentu użycia ich w trakcie wykonywania programu. Innymi słowy, typy generyczne pozwalają na napisanie klasy lub metody, która może działać z każdym typem danych.

Refleksja:

Unsafe code:

Część 3

Inne materiały i informacje

Implicit Interface Implementation vs Explicit Interface Implementation

  • Implicit: you access the interface methods and properties as if they were part of the class.
1
2
3
4
5
6
7
8
9
10
11
public class Test : ITest
{
public string Id // Generated by Implement Interface
{
get { throw new NotImplementedException(); }
}
}

Test t = new Test();
t.Id; // OK
((ITest)t).Id; // OK
  • Explicit: you can only access methods and properties when treating the class as the implemented interface.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test : ITest
{
string ITest.Id // Generated by Implement Interface Explicitly
{
get { throw new NotImplementedException(); }
}
}

Test t = new Test();
t.Id; // Not OK
((ITest)t).Id; // OK

ITest it = t;
it.Id; // OK

It allows you to implement two interfaces that define the same method. However, if you explicitly implement the interface, the methods can only be accessed when the variable is typed to that explicit interface.

In terms of “when” you have to implement an interface explicitly, it is when your class already has a method with the same signature as one of the methods of your interface, or when your class implements several interfaces that share methods with the same signatures but incompatible contracts. Source: https://softwareengineering.stackexchange.com/questions/136319/whats-the-difference-between-implementing-an-interface-explicitly-or-implicitly

More about explicit interface implementation: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation

Casting struct to interface

The fact that a struct can implement an interface is well known and so is the fact that casting a value type into an interface leads to boxing of the value type. This is because methods in interfaces are defined as virtual and to resolve virtual references, vtable (method table) look up is required. Since value types do not have pointers to vtable they are first boxed into a reference type and then the look up happens. https://blogs.msdn.microsoft.com/abhinaba/2005/10/05/c-structs-and-interface/

Po polsku, chodzi o to, że kiedy jako struct zaimplementujemy jakiś interface , to struct będzie zapakowany w dodatkowy obiekt. Metody wywoływane na instancji tego struct, który jest rzutowany na interface , na przykład:

1
2
3
4
5
6
7
8
Employee employee = new Employee("Cool Guy", 65);
IPromotion p = employee;
Console.WriteLine(employee);
p.promote();
Console.WriteLine(employee);

//Cool Guy (65)
//Cool Guy (65)

modyfikują wartości tego dodatkowego obiektu, a nie w oryginalnym obiekcie employee. Jeśli zmienimy struct na class to nie będzie tego boxowania, tworzenia dodatkowego obiektu i wszystko będzie działać jak należy. Wynika to z tego, że:

  • casting a value type into an interface leads to boxing of the value type
  • This is because methods in interfaces are defined as virtual and to resolve virtual references, vtable (method table) look up is required. Since value types do not have pointers to vtable they are first boxed into a reference type and then the look up happens.

więcej tutaj: https://blogs.msdn.microsoft.com/abhinaba/2005/10/05/c-structs-and-interface/

Deadlocks

  • TODO: jak dochodzi do deadlocków?
  • Transaction levels: snapshot, commitread

ASP.NET MVC, ASP.NET Core MVC:

[DRAFT] JavaScript Node.js Scripts

Node.js Scripts

Difference between a node module and a npm package: npm package might be not a single node module but it can consists of many node modules.

How to create a npm package and publish it to NPM

Short instruction to create a new npm package

First login to NPM using npm adduser or npm login command source. Now go to a new project folder and run npm init and create an index.js file with exports object. Then run npm publish, now you can install your package in another project. You can also use npm link to link your package globally.

Release a new version of a npm package

Simply use command npm version <update_type> where <update_type> is one of the semantic versioning release types, patch, minor, or major source.

Node Scripts

Shebang line:

#! /usr/bin/env node

How to build a command line tool with shelljs

http://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npm

How to build CLI with commander

https://medium.freecodecamp.org/writing-command-line-applications-in-nodejs-2cf8327eee2