Podział aplikacji na podprojekty

Podział aplikacji na podprojekty
MI
  • Rejestracja:około 11 lat
  • Ostatnio:9 miesięcy
  • Postów:22
0

Cześć, ostatnio robię aplikacje internetową asp.net (organizer pracy) w technologii mvc4 i mam pytanie odnośnie podziału aplikacji na pod projekty. Doradzono mi bym stworzył 3 pod projekty. Jeden z operujący bazą danych, drugi zawierający całą logikę i trzeci główny zawierający web interfejs.
Czy taki podział aplikacji ma duży wpływ na jej jakość tzn. jest potrzebny?
Czy jeśli pobieram enity frameworka, to tylko załączam go do tego projektu operującego bazą danych?
Może lepiej użyć nhibernate, bo baza danych nie będzie jakaś obszerna?

Z góry dzięki i pozdrawiam :)

0

Poczytaj o wzorcu MVC. Tu nie chodzi o "podprojekty", tylko podział jednego projektu na trzy warstwy Model-View-Controller. Odpowiednio model danych, widok (prezentację), i logikę biznesową.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
0
Mikios napisał(a):

Cześć, ostatnio robię aplikacje internetową asp.net (organizer pracy) w technologii mvc4 i mam pytanie odnośnie podziału aplikacji na pod projekty. Doradzono mi bym stworzył 3 pod projekty. Jeden z operujący bazą danych, drugi zawierający całą logikę i trzeci główny zawierający web interfejs.
Czy taki podział aplikacji ma duży wpływ na jej jakość tzn. jest potrzebny?

Podział na warstwy ma wpływ na jakość, bo dzięki niemu kod jest usystematyzowany, a nie staje się spaghetti. Poszczególne warstwy mogą być w oddzielnych projektach, dzięki temu też łatwiej zapanować nad strukturą, bo fizycznie oddzielamy pliki z poszczególnych warstw, więc trudniej wprowadzić bałagan.
Należy tylko pamiętać, ze sam podział na warstwy i moduły nie gwarantuje jakości.

Czy jeśli pobieram enity frameworka, to tylko załączam go do tego projektu operującego bazą danych?
Może lepiej użyć nhibernate, bo baza danych nie będzie jakaś obszerna?

LOL
Entity Framework to zabawka dla przedszkolaków, słabe rozwiązanie dla małych baz i aplikacji. Niektórzy co prawda używają EF do dużych systemów, ale cierpi na tym wydajność i produktywność.
NHibernate to znacznie dojrzalsze, wydajniejsze i elastyczniejsze rozwiązanie, znacznie lepsze właśnie do dużych projektów.

Hrypa
  • Rejestracja:około 18 lat
  • Ostatnio:około miesiąc
1
Nie Mam Konta napisał(a):

Poczytaj o wzorcu MVC. Tu nie chodzi o "podprojekty", tylko podział jednego projektu na trzy warstwy Model-View-Controller. Odpowiednio model danych, widok (prezentację), i logikę biznesową.

Chyba mylisz MVC z n-tier. Całe MVC jest wzorcem warstwy prezentacji (a nie sam widok), pakowanie tam logiki biznesowej nie jest najlepszym pomysłem. Projekt MVC powinien tylko operować na gotowych serwisach innej warstwy.

Odyn
  • Rejestracja:około 16 lat
  • Ostatnio:ponad 5 lat
  • Postów:493
0

Samo MVC wskazuje Nam na 3 wydzielone warstwy naszej aplikacji. Ewentualnie 4 ze względu na to, że można wziąć pod uwagę ViewModele aby odciążyć system bazodanowy.

Oprócz tego mam taką praktykę ( nie wiem czy tak się fachowo robi ), że w osobnym projekcie wydzielam sobie warstwe dostępu do danych np. DataAccessLayer(DAL), tam również zawieram Repository i UoW.

Natomiast dodatkowo, jeśli korzystasz z serwisów to warto do osobnego projektu sobie je również wydzielić.

Ogólnie chodzi o lepszą organizacje kodu co ułatwia później rozwój aplikacjii.


somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
3
Odyn napisał(a):

Samo MVC wskazuje Nam na 3 wydzielone warstwy naszej aplikacji. Ewentualnie 4 ze względu na to, że można wziąć pod uwagę ViewModele aby odciążyć system bazodanowy.

ViewModele to nie jest ani warstwa ani odciążenie bazy danych, to tylko klasy.
MVC to jest wzorzec dla jednej warstwy - warstwa prezentacji. Za to Model może już się składać z n warstw.

Oprócz tego mam taką praktykę ( nie wiem czy tak się fachowo robi ), że w osobnym projekcie wydzielam sobie warstwe dostępu do danych np. DataAccessLayer(DAL), tam również zawieram Repository i UoW.

To akurat dobra praktyka, z dokładnością do tego, że w DAL umieszcza się implementacje repozytoriów, bo repozytoria to logika biznesowa.

0

Repozytoria w żadnym wypadku nie są logiką biznesową aplikacji. Powinny się ograniczać wyłącznie do operacji CRUD. MVC to jak ktoś już wspomniał wzorzec prezentacji. Nie potrafie sobie wyobrazić jak View Modele miałyby odciążyć bazę danych:D, wręcz odwrotnie, obciążają serwer. View modele są wykorzystywane do zapewnienia większej separacji w warstwie prezentacji. W tym wypadku wszystkie POCO/DTO z warstw niższych mapowane są na ViewModels w np. warstwie usług aplikacji, dzięki temu warstwa prezentacji nie zawiera do nich referencji. Porównywanie NHibernate z ET to jakaś głupota, oba frameworki służą do tego samego i różnią się detalami. Zamiast męczenia się relacyjnymi bazami danych polecam NOSQL (np. RavenDb czy MonboDb) - w 95% aplikacje które budujemy nie potrzebują atomowości danych czy narzędzi do raportowania z MSSQL. Do tego praca z takim RavenDb to czysta przyjemność. Można nawet pokusić się o zrezygnowanie z repo bo RavenDb jest implementowany w postaci właśnie UOW. Wszystko zależy od tego jakiej wielkości budujesz aplikacje i co będzie się z nią działo póżniej. Jednak minimum architektury zawsze należy zapewnić. Jeśli nie masz wielu reguł biznesowych - skorzystaj z Transaction Script - odsyłam do Fowlera. Ew Domain Model z kontraktami repo + implementacja repo w wartwie infrastruktury. Wszelka logika biznesowa która wymaga zestawów danych powinna być implementowana w warstwie usług DM w której można związać logikę biznesową z danymi. Zamiast warstwy usług można także skorzystać z imo ciekawszego rozwiązania jakim jest ServiceBus i zbudować aplikację w oparciu o CQRS (przykład tutaj: https://github.com/gregoryyoung/m-r/tree/master/SimpleCQRS). Podsumowując, dla bardzo prostej aplikacji która nie będzie w przyszłości rozwijana: Transaction Script, bardziej złożona (choć nie koniecznie jeśli czujesz się bardziej pewnie w paradygmacie obiektowym) Domain Model i/lub CQRS.

msm
Administrator
  • Rejestracja:prawie 16 lat
  • Ostatnio:4 miesiące
1

Nie potrafie sobie wyobrazić jak View Modele miałyby odciążyć bazę danych:D, wręcz odwrotnie, obciążają serwer

Dlaczego? Najczęstszą przyczyną problemów typu N+1 SELECT jest korzystanie z modeli bazodanowych bezpośrednio w widokach.

Porównywanie NHibernate z ET to jakaś głupota, oba frameworki służą do tego samego i różnią się detalami

No tak, oba są ORMami więc służą do tego samego więc pewno różnią się tylko detalami :P. A feature listy obu się bardzo różnią.

Repozytoria w żadnym wypadku nie są logiką biznesową aplikacji. Powinny się ograniczać wyłącznie do operacji CRUD.

Jesli korzystamy z ORMa to CRUDowe repozytoria są krokiem wstecz.

Można nawet pokusić się o zrezygnowanie z repo bo RavenDb jest implementowany w postaci właśnie UOW

To tak jak przy NHibernate czy ET, ORM sam robi za repozytorium.

Zamiast warstwy usług można także skorzystać z imo ciekawszego rozwiązania jakim jest ServiceBus i zbudować aplikację w oparciu o CQRS

Może jest ciekawsze, ale IMO w 90% aplikacji niepotrzebne.

edytowany 2x, ostatnio: msm
msm
Autor zaczął
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
1
Zimny Młot napisał(a):

Repozytoria w żadnym wypadku nie są logiką biznesową aplikacji. Powinny się ograniczać wyłącznie do operacji CRUD.

Repozytoria to kontrakty źródeł danych dla logiki biznesowej, z jej punktu widzenia mają się zachowywać po prostu jak kolekcja encji. To, że konkretne implementacje repozytoriów wykonują operacje CRUD na bazie nie zmienia faktu, że ich kontrakty muszą być częścią logiki biznesowej, żeby mogła ona na nich operować. W tym sensie repozytoria są częścią logiki biznesowej - co nie znaczy, że ją wykonują.

Nie potrafie sobie wyobrazić jak View Modele miałyby odciążyć bazę danych:D, wręcz odwrotnie, obciążają serwer.

To uwaga do wszystkich - same ViewModele nie odciążają ani nie obciążają bazy danych... No chyba, że trzymamy w niej kod C#. ;)

Odciążyć może generowanie ViewModeli na poziomie warstwy dostępu do danych, która zbuduje optymalne zapytania. Tylko to wymaga odejścia od podejścia z repozytoriami zwracającymi encje na rzecz prostoty i wydajności.

Porównywanie NHibernate z ET to jakaś głupota, oba frameworki służą do tego samego i różnią się detalami.

NHibernate oferuje wbudowane cache drugiego poziomu, kilka generatorów PK, obsługuje różne rodzaje kolekcji, możliwość batchowego wykonywania zapytań, pełną konfigurowalność (w dowolnym miejscu można się wpiąć i zmienic domyślne zachowanie lub wykonać dodatkową operację), możliwość wykonywania operacij bez wczytywania obiektów (w EF, żeby usunąć obiekt z bazy, musisz go najpierw odczytać!) i daje pełną kontrolę nad generowanym kodem SQL.

EF ma za to tylko LINQ providera generującego kod SQL metodą Monte Carlo. No i od grudnia zeszłego roku obsługuje takie skomplikowane elementy składni SQL 2012 jak OFFSET FETCH. Do tego implementuje własną matematykę, bo domyślnie przy zapisie liczby zmiennoprzecinkowej nie wykonuje zaokrąglenia tylko ucięcie miejsc po przecinku.

To są detale?

Do tego praca z takim RavenDb to czysta przyjemność. Można nawet pokusić się o zrezygnowanie z repo bo RavenDb jest implementowany w postaci właśnie UOW.

No, a w ORM to nie można? Dziwne, bo ja (o ile mam wpływ na projekt) repozytoriów nigdy nie używam. Repozytoria w 99% aplikacji nie są potrzebne, bo 99% aplikacji nie potrzebuje DDD. A ISession czy nawet głupi DbContext są same w sobie implementacjami UoW.

msm
Ale miałeś porównywać NH do ET, a porównałeś z EF.
somekind
W końcu się domyśliłem, że to nie o kosmitę lecz kosmiczną technologię chodzi. ;)
MI
  • Rejestracja:około 11 lat
  • Ostatnio:9 miesięcy
  • Postów:22
0

A ma ktoś może jakiś project example z podpiętym i skonfigurowanym NHibernatem?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
0

@Mikios, podpięcie to zainstalowanie paczki Fluent NHibernate z NuGeta i napisanie banalnej klasy budującej konfigurację. Masz jakiś konkretny problem?

QO
  • Rejestracja:około 11 lat
  • Ostatnio:10 miesięcy
  • Postów:40
0

@somekind @Mikios Entity Framework z racji popularności, doczekał się m.in. takiego projektu https://genericunitofworkandrepositories.codeplex.com/ .
Po stwierdzeniu

Entity Framework to zabawka dla przedszkolaków, słabe rozwiązanie dla małych baz i aplikacji.
aż z ciekawości sobie sprawdzę jakiś przykładowy projekt napisany z NHibernate, bo przyznam że choć EF 6.1 jest zdecydowanie lepszy względem poprzednich wersji, to jednak ciągle jednak nie zachwyca.
Znalazłem coś takiego: https://github.com/sharparchitecture/Sharp-Architecture

somekind
Nie wgryzałem się w Twój link, ale na pierwszy rzut oka widzę antywzorzec w postaci generycznego repozytorium, które na dodatek wystawia metody zwracające IQueryable. Straszne.
MS
A nowe metody dla konkretnego repozytorium dodaje się przez extension methods - chociaż to było oczywiste, skoro wykorzystano antywzorzec. Już chyba lepiej działać bezpośrednio na DbContext.
QO
Hmm, na pierwszy rzut oka nie widzę czemu niby generyczne repozytorium czy wystawianie IQueryable traktować za antywzorce. W podanym projekcie do generycznego repozytorium można dodawać metody https://genericunitofworkandrepositories.codeplex.com/SourceControl/latest#main/Sample/Northwind.Repository/Repositories/CustomerRepository.cs , a samą logikę można wrzucić do warstwy service'ów https://genericunitofworkandrepositories.codeplex.com/SourceControl/latest#main/Sample/Northwind.Service/CustomerService.cs . Całość wydaje się przemyślana.
MS
nie widzę czemu niby generyczne repozytorium czy wystawianie IQueryable traktować za antywzorce - jak pisałem - mamy dodawanie nowych metod przez extensiony, które opierają się na słowie static, w dodatku nie ma to żadnej przewagi nad gołym DbContextem. Co do IQueryable - grozi to tym, że ktoś, gdzieś i w kilku miejscach zrobi np. .ToList() na 1mln obiektów, albo zacznie sobie po tym iterować.
QO
W takim razie Microsoft forsuje antywzorce? http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options#server-paging Spójrzmy na OData, nawet przykład dokładnie odnoszący się do 1mln obiektów ; )
MS
Ale jak link ma się do tego co napisałem? IQueryable nie jest antywzorcem, tylko akurat zwracanie tego w kontekście repozytorium nie należy do dobrych praktyk, bo naraża nas na potencjalne problemy.
MS
Co do artykułów w sieci - byłem kiedyś na wykładzie prowadzonym przez jednego z guru MS. Prezentacja miała dotyczyć technologii X - by szybko pokazać możliwości prowadzący utworzył projekt w WinForms, dodał buttona, kliknął w niego dwa razy i zaczął kodzić... Po czym dodał: "mam nadzieję, że wiecie, że się tak nie robi." Sorry, ale w artykułach muszą być jakieś uproszczenia inaczej każdy artykuł musiałby się zaczynać od 100 unit testów ;)
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
3

@QwertzOne, repozytoria z definicji powinny definiować ścisłe kontrakty dla logiki biznesowej i izolować ją od źródła danych. Udostępnianie generycznych repozytoriów logice biznesowej to po prostu łamanie tego wzorca, bo po pierwsze w ten sposób wcale nie definiujesz żadnego kontraktu (bo nie masz specyficznych dla danej encji metod), dla większości przypadków takie repozytorium zawiera zbyt wiele metod (nie zawsze potrzebujesz GetAll, Save albo Delete. A udostępnianie metod zwracających IQueryable to po pierwsze wyciek abstrakcji, bowypuszczasz szczegół implementacji technologi dostępu do danych do logiki biznesowej, a po drugie przyczyna problemów wydajnościowych, bo logika biznesowa czy nawet warstwa prezentacji powodują wtedy materializację, a co za tym idzie dzięki lazy loading mogą spowodować problem n+1.

Repozytoria to są przede wszystkim INTERFEJSY z deklaracjami metod definiujących kontrakt dostępu do danych dla logiki biznesowej, a nie implementacja używająca takiego czy innego ORMa, żeby udawać jakąś separację między aplikacją a bazą.

Czy Microsoft promuje antywzorce? W dużej mierze tak - wszystkie ich oficjalne tutoriale do ASP.NET MVC łamią zasady tego wzorca, mają trywialne błędy projwktowe w bazowych bibliotekach (np. DateTime.Now nie powinno być właściwością), do tego np. MembershipProvider łamie podstawowe zasady SOLID, a taki System.Web to kupa legacy code.

I jeszcze coś - to, że coś się kompiluje i działa, nie znaczy jeszcze, że jest dobrze zrobione. A to, że wszyscy coś robią, nie znaczy od razu, że tak jest dobrze. Często jest wręcz przeciwnie.

edytowany 1x, ostatnio: somekind
QO
  • Rejestracja:około 11 lat
  • Ostatnio:10 miesięcy
  • Postów:40
0

@somekind Czy oceniając czy coś jest dobrze zrobione, nie powinno brać się pod uwagę skali projektu? Dla większego systemu takie rozwiązania nie będą się nadawać i o tworzeniu takich systemów nie mam pojęcia, ale w przypadku małych, średnich projektów (czyli takich którymi zajmuje się wielu programistów) kosztem łamania części "dobrych" wzorców, które sprawdzają się w większych projektach czy wycieków abstrakcji (myślę, że te ew. zawsze się pojawią i można iść na kompromis, przyjmując kiedy są akceptowalne), zyskuje się prostotę i czas, mniej doświadczonym osobom też łatwiej wejść do takiego projektu.
PHP + MySQL zyskały popularność, bo były proste, dzisiaj mamy m.in. C#, node.js, tony framework'ów/bibliotek javascriptowych(które odgrywają coraz większą rolę z popularyzacją SPA), z których użyciem można pisać prosto i przyjemnie, bez konieczności posiadania dużej wiedzy o tworzeniu architektury.
Przeciętni programiści stanowią większość, jest więc i na to popyt.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
1

Ja jestem jak najbardziej za uproszczeniami i stosowaniem jak najprostszej architektury w stosunku do rozmiaru zadania. Ale jak ma nam w tym pomóc:

  1. nazywanie repozytorium czegoś, co z repozytorium nie ma nic wspólnego?
  2. tworzenie własnej abstrakcji w postaci generycznego repozytorium opakowującego kontekst EF, który sam w sobie jest przecież generycznym repozytorium?
  3. popełnianie elementarnych błędów, takich jak dopuszczenie do powstania n+1?

Zrobienie czegoś dobrze nie oznacza, że trzeba na to poświęcić więcej czasu. Często właśnie wręcz przeciwnie. Tylko trzeba przestać na siłę wciskać wszędzie antywzorce, do których jest się przyzwyczajonym.

0

Możesz napisać coś więcej o punkcie 2 i 3?

Jak powinna wyglądać dobrze zaprojektowana aplikacja?
Mam coś takiego: kontroler operuje na interfejsie, który reprezentuje operacje na konkretnej tabeli(klasie POCO) w bazie danych. Ten interfejs implementuje klasa, która operuje na interfejsie kontekstu. Z wykorzystaniem IoC.

Co jest złego w zwracaniu do kontrolera IQueryable<T>? Każda książka do ASP.NET MVC ma taki przykład z Lazy Loading.

Co do punktu 3. Problem N + 1 występuje gdy nie korzysta się z Lazy Loading i chce się pobrać listę obiektów połączonych relacją z inną tabelą. Wtedy dla każdego obiektu są pobierane w oddzielnym poleceniu obiekty połączone relacja.
W takim razie czy IQueryable<T> nie rozwiązuje tego problemu?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
3
Gorzec napisał(a):

Jak powinna wyglądać dobrze zaprojektowana aplikacja?

Powinna trzymać się zasad SOLID, a chociaż SRP. Czyli:

  1. Klasa, która opisuje format danych w bazie, nie powinna służyć do wyświetlania ich użytkownikowi. Chociażby dlatego, że często użytkownik potrzebuje widzieć mniej albo więcej danych, niż te zawarte w jednej tabeli. Dlatego w widokach wyświetla się viewmodele, a nie encje.
  2. Jeśli mamy warstwę dostępu do danych, to ona powinna zwracać dane pobrane z bazy, a nie wirtualne zapytanie. Dlatego kontrolery nie powinny pracować na IQueryable.
  3. Klasa służąca do obsługi żądań użytkowników, wołania modelu i przekierowania widoku, nie realizacji logiki biznesowej ani pobierania danych z bazy. Chodzi mi w tym momencie o kontrolery - i o tej ich odpowiedzialności wyraźnie mówi wzorzec MVC.

Mam coś takiego: kontroler operuje na interfejsie, który reprezentuje operacje na konkretnej tabeli(klasie POCO) w bazie danych. Ten interfejs implementuje klasa, która operuje na interfejsie kontekstu. Z wykorzystaniem IoC.

Jak chcesz, ale to nie jest na pewno MVC, i na pewno nie masz tam repozytoriów.

Co jest złego w zwracaniu do kontrolera IQueryable<T>? Każda książka do ASP.NET MVC ma taki przykład z Lazy Loading.

Kontroler powinien dostać gotowe dane do przekazania do widoku, a nie wyciągać je z bazy. I nie powinien nic wiedzieć o konkretnej technologii dostępu do danych. Ani nawet o tym, że gdzieś tam jest baza danych.
Przykłady w książkach do ASP.NET MVC to uproszczone przykłady jak działa ten framework, a nie jak należy pisać sensowne aplikacje.

Problem N + 1 występuje gdy nie korzysta się z Lazy Loading

Jesteś pewien?
Ten problem występuje, gdy nawigujemy po właściwościach obiektów z jakiejś listy. Jeśli są one leniwe, to dla każdego obiektu z listy zostanie wykonane zapytanie do bazy. Jeśli obiekty listy wczytamy zachłannie z ich właściwościami, to problem ten przecież nie wystąpi.

W takim razie czy IQueryable<T> nie rozwiązuje tego problemu?

Ani go nie powoduje, ani go nie rozwiązuje. To zupełnie inna rzecz.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)