Singleton/Multiton w Javie

Singleton/Multiton w Javie
JerzyKol
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:30
0

Witam,
Mam do rozwiązania pewne zadanie, które sprawia mi sporo problemów, bo nie wiem jak je rozwiązać, aby było jak najbardziej poprawne i zgodne ze wzorcami projektowania. Na wstępie zaznaczę, że wiem co to Singleton/Multiton i potrafię się nimi posługiwać, ale jak widać po tym zadaniu poniżej, nie potrafię zastosować tej wiedzy w zadaniach praktycznych, a więc do rzeczy...

Treść zadania:

Baza danych (tablica znaków) umożliwia dostęp jedynie przez klasę implementującą typ interfejsowy IPolaczenie. Baza danych powinna być **Singletonem ** ale jej klientem nie będzie funkcja **main ** (nie można pobrać z niej bezpośrednio referencji do bazy) tylko obiekt konkretnego połączenia. Z kolei konkretne połączenia będą **Multitonami ** (istnieją tylko 3, udostępniane naprzemiennie - 1 2 3 1 2 3 ..., obiekty je klasy), których klientem będzie Baza, a dokładniej jej metoda getPolaczenie.

Klient (funkcja main) pobiera obiekty połączenia i za ich pomocą korzysta z bazy.

Uzupełnij poniższy kod , a w funkcji **main ** pobierz 4 połączenia i pokaż, że wszystkie korzystają z tej samej bazy. Wykaż też, że obiekty połączeń są współdzielone.

Kod, który muszę uzupełnić:

Kopiuj
interface IPolaczenie {
    char get(int indeks);
    void set(int indeks, char c);
    int length();
}
class Baza {
    private char[] tab = new char[100]; /* ... */
    public static IPolaczenie getPolaczenie() {
        return Polaczenie.getInstance();
    }
    private static class Polaczenie implements IPolaczenie {
        private Baza baza; /* ... */
        public static IPolaczenie getInstance() {
            /* ... */
        }
        public char get(int indeks) {
            return baza.tab[indeks];
        }
        public void set(int indeks, char c) {
            baza.tab[indeks] = c;
        }
        public int length() {
            return baza.tab.length;
        }
    }
}

A tutaj moje rozwiązanie, nie pełne:

Kopiuj
public interface IPolaczenie {
	char get(int indeks);
	void set(int indeks, char c);
	int length();
}


public class Baza {

	private char[] tab = new char[100];
	
	public static IPolaczenie getPolaczenie() {
		return Polaczenie.getInstance();
	}
	
	private static class Polaczenie implements IPolaczenie {
		private Baza baza;
		
		public String connectionName;
		
		private static Polaczenie[] polaczenia = { 
			new Polaczenie("1"), 
			new Polaczenie("2"), 
			new Polaczenie("3") 
		};
		
		private static int kolejnosc = 0;
		private Polaczenie() { }
		private Polaczenie(String str) { this.connectionName = str; }
		
		public static IPolaczenie getInstance() {
			kolejnosc = (kolejnosc + 1) % polaczenia.length;
			return polaczenia[kolejnosc];
		}
		
		public char get(int indeks) {
			return baza.tab[indeks];
		}
		
		public void set(int indeks, char c) {
			baza.tab[indeks] = c;
		}
		
		public int length() {
			return baza.tab.length;
		}		
	}
}


public class BazaTest {
	public static void main(String[] args) {
		Baza baza = new Baza();
		IPolaczenie polaczenie1 = Baza.getPolaczenie();
		IPolaczenie polaczenie2 = Baza.getPolaczenie();
		IPolaczenie polaczenie3 = Baza.getPolaczenie();
		IPolaczenie polaczenie4 = Baza.getPolaczenie();
	}

}

Co z referencją do obiektu baza ("private Baza baza;") ?

Robiąc nowe połączenie, robię cały czas nowe obiekty ze wspomnianą składową, która nie odnosi się do niczego.

Czy powinienem w tym miejscu zrobić funkcję getBaza(), która zwróci mi jeden-jedyny obiekt klasy Baza - zgodnie z treścią zadania ?!

Kolejna moja wątpliwość to te zdanie z treści zadania "Wykaż też, że obiekty połączeń są współdzielone.", czyli że co w tym przypadku, bo nie mam pojęcia do czego to zdanie się odnosi ?

Inny problem to taki jak się dostać do prywatnej zmiennej tab ("private char[] tab = new char[100];") ? Bo aktualna wersja tj. metody get/set tego nie umożliwiają ? Zmienić na protected/public czy jest jakiś inny sposób dla wzorców ?

Na koniec chciałbym się jeszcze odnieść do tego zdania z treści zadania: "Uzupełnij poniższy kod , a w funkcji main pobierz 4 połączenia i pokaż, że wszystkie korzystają z tej samej bazy.". Czyli moja teza dot. zrobienia metody getBaza() w klasie Baza by się chyba sprawdziła i wtedy mógłbym zamienić "private Baza baza;" na "private Baza baza = Baza.getBaza();". Właśnie nie rozumiem po kiego są wstawione te komentarze, może po to żeby pokazać, że tam należy wprowadzić jakieś zmiany ?! :)

Proszę bardzo o pomoc,
Pozdrawiam JerzyKol

edytowany 2x, ostatnio: JerzyKol
Softnyx
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 12 lat
  • Postów:10
0
JerzyKol
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:30
0
Softnyx napisał(a):

Jedno powiem singletony to zuo

https://sites.google.com/site/steveyegge2/singleton-considered-stupid

Chyba sobie żartujesz kolego prostując taką odpowiedź, ja potrzebuję pomocy w rozwiązaniu zadania, a nie opinii innych na temat singletona. Aktualnie przerabiam ten materiał na uczelni i muszę opanować ten materiał, nie ważne czy chce czy nie.

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 13 godzin
1

Hmm, klasa Polaczenie chyba powinna przyjmować Baza jako parametr konstruktora.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
JerzyKol
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:30
0
Wibowit napisał(a):

Hmm, klasa Polaczenie chyba powinna przyjmować Baza jako parametr konstruktora.

Yhy, chyba dobry pomysł ;) Ja wpadłem na takie coś, żeby napisać:

Kopiuj
private Baza baza = Baza.getBaza();

Gdzie getBaza() jest funkcją statyczną w klasie Baza (singleton) i pilnuje aby był tylko 1 obiekt klasy baza.

Mój zmodyfikowany kod prezentuje się następująco:

Kopiuj
public interface IPolaczenie {
	char get(int indeks);
	void set(int indeks, char c);
	int length();
}


public class Baza {

	protected char[] tab = new char[100];
	
	public static IPolaczenie getPolaczenie() {
		return Polaczenie.getInstance();
	}
	
	private Baza() { }
	private static Baza bazaDanych;
	private static Baza getBaza() {
		if(bazaDanych == null)
			return new Baza();
		return bazaDanych;
	}
	
	private static class Polaczenie implements IPolaczenie {
		private Baza baza = Baza.getBaza();
		
		public String connectionName;
		
		private static Polaczenie[] polaczenia = { 
			new Polaczenie("1"), 
			new Polaczenie("2"), 
			new Polaczenie("3") 
		};
		
		private static int kolejnosc = 0;
		private Polaczenie() { }
		private Polaczenie(String str) { this.connectionName = str; }
		
		public static IPolaczenie getInstance() {
			kolejnosc = (kolejnosc + 1) % polaczenia.length;
			return polaczenia[kolejnosc];
		}
		
		public char get(int indeks) {
			return baza.tab[indeks];
		}
		
		public void set(int indeks, char c) {
			baza.tab[indeks] = c;
		}
		
		public int length() {
			return baza.tab.length;
		}		
	}
}


public class BazaTest {
	public static void main(String[] args) {
		IPolaczenie polaczenie1 = Baza.getPolaczenie();
		IPolaczenie polaczenie2 = Baza.getPolaczenie();
		IPolaczenie polaczenie3 = Baza.getPolaczenie();
		IPolaczenie polaczenie4 = Baza.getPolaczenie();
		
		polaczenie1.set(10, 'x');
		System.out.println(polaczenie1.get(10));
	}

}

Czyli wg. Twojego pomysłu powinienem zrobić, o tak:

Kopiuj
private Polaczenie {
baza = Baza.getBaza();
}

Tak ?

Czy powyżej wklejony kod jest poprawny ? Czy poprawnie zaimplementowałem singletona/multitona ?

edytowany 1x, ostatnio: JerzyKol
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 13 godzin
1

Kojarzę cię z poprzednich postów :p i w poprzednich postach wystarczało, gdy zastępowało się pola /* ... */ kodem, nie modyfikując żadnych innych linii. Ty chcesz zmieniać kod, a więc pewnie nie o to chodzi wykładowcy.

W Polaczenie.getInstance możesz zrobić coś w ten deseń (kod wymyślony na szybko):

Kopiuj
if (polaczenia == null) {
  Baza baza = new Baza();
  polaczenia = new Polaczenie[] { new Polaczenie(baza), new Polaczenie(baza), new Polaczenie(baza) };
}
kolejnosc = (kolejnosc + 1) % polaczenia.length;
return polaczenia[kolejnosc];

Plus do tego synchronizacja (jeśli chodzi o singletony w Javie to jestem zwolennikiem rozwiązania Billa Pugha http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh ).


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
JerzyKol
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:30
0
Wibowit napisał(a):

Kojarzę cię z poprzednich postów :p i w poprzednich postach wystarczało, gdy zastępowało się pola /* ... */ kodem, nie modyfikując żadnych innych linii. Ty chcesz zmieniać kod, a więc pewnie nie o to chodzi wykładowcy.

W Polaczenie.getInstance możesz zrobić coś w ten deseń (kod wymyślony na szybko):

Kopiuj
if (polaczenia == null) {
  Baza baza = new Baza();
  polaczenia = new Polaczenie[] { new Polaczenie(baza), new Polaczenie(baza), new Polaczenie(baza) };
}
kolejnosc = (kolejnosc + 1) % polaczenia.length;
return polaczenia[kolejnosc];

Plus do tego synchronizacja (jeśli chodzi o singletony w Javie to jestem zwolennikiem rozwiązania Billa Pugha http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh ).

Ale zmienna baza nie jest statyczna...

Mimo wszystko w ten sposób zastąpione jest tylko 1 z 3 pól oznaczonych

Kopiuj
/* ... */

, a co z dwoma pozostałymi ?

Baza danych ma być singletonem, a więc moim zdaniem bez dodania prywatywnego konstruktora się tutaj nie obejdzie, czy mylę się ?

Kolejna wątpliwość to pole oznaczone w ten sposób:

Kopiuj
private char[] tab = new char[100]; /* ... */

Bo niby na co miałbym je zamienić ?

Bardzo bym prosił o kontynuowanie pomocy, bo chyba nikomu więcej się nie chce ;)

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 13 godzin
1

Wiem, że nie jest statyczna. W konstruktorze trzeba wziąć parametr typu Baza i przypisać go do tej zmiennej.

Spróbuj coś takiego:

  • pierwsze /* ... */ zamień na:
Kopiuj
private Baza() {}
  • drugie /* ... */ zamień na:
Kopiuj
private Polaczenie(Baza baza) { this.baza = baza; }
  • trzecie /* ... */ zamień na to co ci podałem we wcześniejszym poście,

Jak pokazać, że mamy do czynienia z pulą połączeń o sztywnym rozmiarze? Myślę, że można by np 100 razy wywołać getPolaczenie(), wyniki włożyć do IdentityHashMap, a potem wywołać metodę size() na tej mapie i pokazać, że jest równe 3.

Jak pokazać, że baza jest współdzielona. Wyciągnąć dwa połączenia, zmieniać bazę w jednym połączeniu, a w drugim odczytywać wartości na tych samych indeksach i pokazać, że są odpowiednio zmieniane.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
JerzyKol
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:30
0
Wibowit napisał(a):

Wiem, że nie jest statyczna. W konstruktorze trzeba wziąć parametr typu Baza i przypisać go do tej zmiennej.

Spróbuj coś takiego:

  • pierwsze /* ... */ zamień na:
Kopiuj
private Baza() {}
  • drugie /* ... */ zamień na:
Kopiuj
private Polaczenie(Baza baza) { this.baza = baza; }
  • trzecie /* ... */ zamień na to co ci podałem we wcześniejszym poście,

Jak pokazać, że mamy do czynienia z pulą połączeń o sztywnym rozmiarze? Myślę, że można by np 100 razy wywołać getPolaczenie(), wyniki włożyć do IdentityHashMap, a potem wywołać metodę size() na tej mapie i pokazać, że jest równe 3.

Jak pokazać, że baza jest współdzielona. Wyciągnąć dwa połączenia, zmieniać bazę w jednym połączeniu, a w drugim odczytywać wartości na tych samych indeksach i pokazać, że są odpowiednio zmieniane.

Dodałem jeszcze te dwie linijki kodu:

Kopiuj
private static int kolejnosc = 0;
private static Polaczenie[] polaczenia;

i kod prezentuje się teraz następująco:

Kopiuj
public interface IPolaczenie {
	char get(int indeks);
	void set(int indeks, char c);
	int length();
}

class Baza {
    private char[] tab = new char[100]; 
    /* ... */
    private Baza() {}
    public static IPolaczenie getPolaczenie() {
        return Polaczenie.getInstance();
    }
    private static class Polaczenie implements IPolaczenie {
        private Baza baza; 
        /* ... */
        private Polaczenie(Baza baza) {
        	this.baza = baza;
        }
        private static int kolejnosc = 0;
        private static Polaczenie[] polaczenia;
        public static IPolaczenie getInstance() {
            if(polaczenia == null) {
            	Baza baza = new Baza();
            	polaczenia = new Polaczenie[] { new Polaczenie(baza), new Polaczenie(baza), new Polaczenie(baza) };
            }
            kolejnosc = (kolejnosc + 1) % polaczenia.length;
            return polaczenia[kolejnosc];
        }
        public char get(int indeks) {
            return baza.tab[indeks];
        }
        public void set(int indeks, char c) {
            baza.tab[indeks] = c;
        }
        public int length() {
            return baza.tab.length;
        }
    }
}


public class BazaTest {
	public static void main(String[] args) {
		IPolaczenie polaczenie1 = Baza.getPolaczenie();
		IPolaczenie polaczenie2 = Baza.getPolaczenie();
		IPolaczenie polaczenie3 = Baza.getPolaczenie();
		IPolaczenie polaczenie4 = Baza.getPolaczenie();
		
		polaczenie1.set(10, 'x');
		System.out.println(polaczenie1.get(10));
	}

}

Teraz wszystko zgodnie ze wzorcami jest ?

Czy zaproponowana przeze mnie powyżej wersja tego zadania też jest poprawna ze wzorcami ? ( Pomińmy tutaj fakt, że Twoja jest bardziej poprawna :) )

Dzięki za pomoc!!

edytowany 1x, ostatnio: JerzyKol
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 13 godzin
1

Wydaje się zgodna z treścią zadania, a o to chodzi :]
No może oprócz tego, że synchronizacja by się przydała, ale może akurat się wykładowca nie przyczepi.

Wzorce to ogólnie coś abstrakcyjnego, ogólnego i niezbyt dobrze zdefiniowanego - tak wynika przynajmniej z mojego doświadczenia. Ja traktuję wzorce jako swego rodzaju inspirację. Przydają się także do opisów rozwiązań, np zamiast mówić "tu stworzę klasę z jedną instancją statyczną, którą będę pobierał przez statycznego gettera" powiem "tu stworzę singleton" i wszystko jasne.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit
JerzyKol
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:30
0
Wibowit napisał(a):

Wydaje się zgodna z treścią zadania, a o to chodzi :]
No może oprócz tego, że synchronizacja by się przydała, ale może akurat się wykładowca nie przyczepi.

Wzorce to ogólnie coś abstrakcyjnego, ogólnego i niezbyt dobrze zdefiniowanego - tak wynika przynajmniej z mojego doświadczenia. Ja traktuję wzorce jako swego rodzaju inspirację. Przydają się także do opisów rozwiązań, np zamiast mówić "tu stworzę klasę z jedną instancją statyczną, którą będę pobierał przez statycznego gettera" powiem "tu stworzę singleton" i wszystko jasne.

Dzięki za pomoc!

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)