• Nie Znaleziono Wyników

prosta fabryka

N/A
N/A
Protected

Academic year: 2021

Share "prosta fabryka"

Copied!
30
0
0

Pełen tekst

(1)

Wzorce projektowe

Wzorce projektowe

Wybrane wzorce kreacyjne: Fabryka

Wybrane wzorce kreacyjne: Fabryka

Projektowanie i programowanie

Projektowanie i programowanie

obiektowe

obiektowe

Roman Simiński

roman.siminski@us.edu.pl roman@siminskionline.pl programowanie.siminskionline.pl

(2)

Fabryka prosta

Fabryka prosta

Simple Factory

(3)

Przykład

Przykład

PostgreSQL

MySQL

SQLServer

SQLite

Załóżmy, że piszemy program wykorzystujący relacyjną bazę danych.

W programie posługiwać się będziemy standardowymi poleceniami SQL,

obsługiwanymi przez większość serwerów baz danych.

Chcemy aby nasz program współpracował z większością popularnych baz

danych, w danym momencie z jedną.

System

(4)

Przykład

Przykład

Będziemy używać obiektów zapewniających dostęp do każdej z baz. Zatem dla

każdej bazy zdefiniujemy odpowiednią klasę.

Klasy te będą dziedziczyć z klasy abstrakcyjnej.

AbstractServer

+execSQL(String)

MySQLServer

+execSQL(String)

PostgreSQLServer

+execSQL(String)

SQLiteServer

+execSQL(String)

SQLServer

+execSQL(String)

(5)

Przykład

Przykład

. . .

AbstractServer base;

// Ustalenie bazy z którą współpracujemy, np. poprzez odczyt informacji

// z pliku konfiguracyjnego, utworzenie obiektu odpowiedniej bazy

. . .

base.execSQL( ”select * from produkty” );

. . .

. . .

AbstractServer base;

// Ustalenie bazy z którą współpracujemy, np. poprzez odczyt informacji

// z pliku konfiguracyjnego, utworzenie obiektu odpowiedniej bazy

. . .

base.execSQL( ”select * from produkty” );

. . .

Dzięki klasom abstrakcyjnym i/lub interfejsom możemy pisać elastyczny kod,

który wykorzystuje polimorfizm.

Taki kod może działać na dowolnym obiekcie z ustalonej hierarchii klas

wykorzystującej dziedziczenie.

Jak oprogramować identyfikację konkretnej bazy i utworzenie odpowiedniego

obiektu?

(6)

Przykład

Przykład

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : base = new MySQLServer();

break;

case "postgresgl": base = new PostgreSQLServer();

break;

case "sqlite" : base = new SQLiteServer();

break;

case "sqlserver" : base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" :

base = new MySQLServer();

break;

case "postgresgl":

base = new PostgreSQLServer();

break;

case "sqlite" :

base = new SQLiteServer();

break;

case "sqlserver" :

base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

(7)

Przykład

Przykład

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : base = new MySQLServer();

break;

case "postgresgl": base = new PostgreSQLServer();

break;

case "sqlite" : base = new SQLiteServer();

break;

case "sqlserver" : base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" :

base = new MySQLServer();

break;

case "postgresgl":

base = new PostgreSQLServer();

break;

case "sqlite" :

base = new SQLiteServer();

break;

case "sqlserver" :

base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

Tutaj tracimy elastyczność, każda modyfikacja hierarchii

klas powoduje konieczność modyfikacji tego kodu.

Kod staje się zależny od klas podrzędnych, konkretnych,

niższego poziomu.

Tutaj tracimy elastyczność, każda modyfikacja hierarchii

klas powoduje konieczność modyfikacji tego kodu.

Kod staje się zależny od klas podrzędnych, konkretnych,

(8)

Przykład

Przykład

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : base = new MySQLServer();

break;

case "postgresgl": base = new PostgreSQLServer();

break;

case "sqlite" : base = new SQLiteServer();

break;

case "sqlserver" : base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" :

base = new MySQLServer();

break;

case "postgresgl":

base = new PostgreSQLServer();

break;

case "sqlite" :

base = new SQLiteServer();

break;

case "sqlserver" :

base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

To rozwiązanie łamie zasady SOLID:

Zasadę Open/Close

Zasadę Dependency inversion

To rozwiązanie łamie zasady SOLID:

Zasadę Open/Close

(9)

Przykład

Przykład

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : base = new MySQLServer();

break;

case "postgresgl": base = new PostgreSQLServer();

break;

case "sqlite" : base = new SQLiteServer();

break;

case "sqlserver" : base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

. . .

AbstractServer base;

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" :

base = new MySQLServer();

break;

case "postgresgl":

base = new PostgreSQLServer();

break;

case "sqlite" :

base = new SQLiteServer();

break;

case "sqlserver" :

base = new SQLServer();

break;

}

. . .

base.execSQL( ”select * from produkty” );

. . .

Jak zamknąć ten fragment kodu na modyfikację otwierając jednocześnie na

rozszerzenia?

Jak uczynić ten fragment kodu niezależnym od klas podrzędnych — jak

odwrócić zależność?

Jak zamknąć ten fragment kodu na modyfikację otwierając jednocześnie na

rozszerzenia?

Jak uczynić ten fragment kodu niezależnym od klas podrzędnych — jak

odwrócić zależność?

(10)

Wprowadzamy klasę konstruującą odpowiedni obiekt

Wprowadzamy klasę konstruującą odpowiedni obiekt

class SQLServerFactory

{

public AbstractServer createServer( ConfigFile config )

{

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : return new MySQLServer();

case "postgresgl": return new PostgreSQLServer();

case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer();

}

return null;

}

}

. . .

SQLServerFactory serverFactory = new SQLServerFactory();

AbstractServer base = serverFactory.createServer( config );

base.execSQL( ”select * from produkty” );

class SQLServerFactory

{

public

AbstractServer

createServer( ConfigFile config )

{

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : return

new MySQLServer();

case "postgresgl": return

new PostgreSQLServer();

case "sqlite" : return

new SQLiteServer();

case "sqlserver" : return

new SQLServer();

}

return null;

}

}

. . .

SQLServerFactory

serverFactory = new SQLServerFactory();

AbstractServer base =

serverFactory.createServer( config );

base.execSQL( ”select * from produkty” );

(11)

Przeniesienie konstruowania obiektu do prostej fabryki

Przeniesienie konstruowania obiektu do prostej fabryki

Prosta fabryka przejmuje obowiązek utworzenia obiektu odpowiedniej klasy.

Konkretnie utworzenie obiektu realizuje wyodrębniona funkcja kreująca. Jej

rezultatem jest utworzony obiekt.

Aby to wszystko działało, tworzone obiekty powinny być egzemplarzami klas

pochodnych pewnej klasy abstrakcyjnej lub powinny implementować wspólny

interfejs.

Fabryka otrzymuje zwykle jakąś informacje o kontekście działania programu –

jest to najczęściej parametr funkcji kreującej, na podstawie którego ustalana jest

odpowiednia wersja tworzonego obiektu.

Sprawa wydaje się zagmatwana – aby utworzyć odpowiedni obiekt trzeba utworzyć

obiekt prostej fabryki tylko po to, aby wywołać jego funkcję składową.

Uprościć sprawę może fabryka statyczna.

Sprawa wydaje się zagmatwana – aby utworzyć odpowiedni obiekt trzeba utworzyć

obiekt prostej fabryki tylko po to, aby wywołać jego funkcję składową.

(12)

Statyczna klasa fabryki

Statyczna klasa fabryki

static class SQLServerFactory

{

public static AbstractServer createServer( ConfigFile config )

{

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : return new MySQLServer();

case "postgresgl": return new PostgreSQLServer();

case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer();

}

return null;

}

}

. . .

AbstractServer base = SQLServerFactory.createServer( config );

base.execSQL( ”select * from produkty” );

. . .

static

class SQLServerFactory

{

public

static

AbstractServer

createServer( ConfigFile config )

{

String dbType = config.getDataBaseType();

switch( dbType )

{

case "mysgl" : return

new MySQLServer();

case "postgresgl": return

new PostgreSQLServer();

case "sqlite" : return

new SQLiteServer();

case "sqlserver" : return

new SQLServer();

}

return null;

}

}

. . .

AbstractServer base =

SQLServerFactory.createServer( config );

base.execSQL( ”select * from produkty” );

(13)

Przykładowa implementacja

Przykładowa implementacja

prostej fabryki w języku Java

(14)

Klasa pomocnicza i klasa bazowa dla kreowanych obiektów

Klasa pomocnicza i klasa bazowa dla kreowanych obiektów

class ConfigFile

{

public String getDataBaseType() {

// Funkcja „zaślepka”, tu powinno być odczytanie z pliku // konfiguracyjnego informacji o aktualnym typie serwera

return "sqlite";

} }

abstract class AbstractServer

{

public abstract void execSQL( String query ); }

class ConfigFile

{

public String getDataBaseType() {

// Funkcja „zaślepka”, tu powinno być odczytanie z pliku // konfiguracyjnego informacji o aktualnym typie serwera

return "sqlite";

} }

abstract class AbstractServer

{

public abstract void execSQL( String query ); }

(15)

Klasy dla obiektów konkretnych

Klasy dla obiektów konkretnych

class MySQLServer extends AbstractServer

{

@Override

public void execSQL( String query ) {

System.out.println( "MySQLServer: " + query ); }

}

class PostgreSQLServer extends AbstractServer

{

@Override

public void execSQL( String query ) {

System.out.println( "PostrgreSQLServer: " + query ); }

}

class MySQLServer extends AbstractServer {

@Override

public void execSQL( String query ) {

System.out.println( "MySQLServer: " + query ); }

}

class PostgreSQLServer extends AbstractServer {

@Override

public void execSQL( String query ) {

System.out.println( "PostrgreSQLServer: " + query ); }

(16)

Klasy dla obiektów konkretnych

Klasy dla obiektów konkretnych

class SQLiteServer extends AbstractServer

{

@Override

public void execSQL( String query ) {

System.out.println( "SQLiteServer: " + query ); }

}

class SQLServer extends AbstractServer

{

@Override

public void execSQL( String query )

{

System.out.println( "SQLServer: " + query ); }

}

class SQLiteServer extends AbstractServer

{

@Override

public void execSQL( String query ) {

System.out.println( "SQLiteServer: " + query ); }

}

class SQLServer extends AbstractServer

{

@Override

public void execSQL( String query )

{

System.out.println( "SQLServer: " + query ); }

(17)

Klasa prostej fabryki

Klasa prostej fabryki

class SQLServerFactory

{

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); } return null; } } class SQLServerFactory {

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null;

} }

(18)

Klasa klienta omawianego wzorca i jej wykorzystanie

Klasa klienta omawianego wzorca i jej wykorzystanie

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

SQLServerFactory factory = new SQLServerFactory();

AbstractServer base = factory.createServer( cnfFile ); base.execSQL( "select * from produkty" );

} }

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

SQLServerFactory factory = new SQLServerFactory();

AbstractServer base = factory.createServer( cnfFile ); base.execSQL( "select * from produkty" );

} }

public class FabrykaDemo

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); client.createAndUseServer();

} }

public class FabrykaDemo

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); client.createAndUseServer();

} }

(19)

Fabryka statyczna raz jeszcze

Fabryka statyczna raz jeszcze

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

SQLServerFactory factory = new SQLServerFactory();

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

SQLServerFactory factory = new SQLServerFactory();

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

AbstractServer base = StaticSQLServerFactory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

AbstractServer base = StaticSQLServerFactory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

W tym przypadku można zastosować

fabrykę statyczną

W tym przypadku można zastosować

fabrykę statyczną

(20)

Wady prezentowanego podejścia

Wady prezentowanego podejścia

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

SQLServerFactory factory = new SQLServerFactory();

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

SQLServerFactory factory = new SQLServerFactory();

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

AbstractServer base = StaticSQLServerFactory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer() {

AbstractServer base = StaticSQLServerFactory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

W obu przypadkach kod nie jest

zgodny z zasadą Open/Close

W obu przypadkach kod nie jest

(21)

Fabryka może być przekazywana na zasadzie DI

Fabryka może być przekazywana na zasadzie DI

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer( SQLServerFactory factory ) {

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer( SQLServerFactory factory ) {

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

public class FabrykaDemo01

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); client.createAndUseServer( new SQLServerFactory() ); }

}

public class FabrykaDemo01

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); client.createAndUseServer( new SQLServerFactory() ); }

}

Utworzenie obiektu klienta

Utworzenie obiektu klienta

(22)

Fabryka może być przekazywana na zasadzie DI

Fabryka może być przekazywana na zasadzie DI

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer( SQLServerFactory factory ) {

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void createAndUseServer( SQLServerFactory factory ) {

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

public class FabrykaDemo01

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); client.createAndUseServer( new SQLServerFactory() ); }

}

public class FabrykaDemo01

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); client.createAndUseServer( new SQLServerFactory() ); }

}

Utworzenie fabryki i przekazanie do

metody obiektu klienta

Utworzenie fabryki i przekazanie do

metody obiektu klienta

(23)

Fabryka może być przekazywana na zasadzie DI

Fabryka może być przekazywana na zasadzie DI

class SQLFactoryClient

{

ConfigFile cnfFile = new ConfigFile();

public void factoryExample( SQLServerFactory factory ) {

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLFactoryClient {

ConfigFile cnfFile = new ConfigFile();

public void factoryExample( SQLServerFactory factory ) {

AbstractServer base = factory.createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

public class FabrykaDemo

{

public static void main(String[] args) {

SQLFactoryClient c = new SQLFactoryClient(); c.factoryExample( new SQLServerFactory() ); }

}

public class FabrykaDemo

{

public static void main(String[] args) {

SQLFactoryClient c = new SQLFactoryClient(); c.factoryExample( new SQLServerFactory() ); }

}

Metod klienta wykorzystuje

wstrzyknięty obiekt fabryki

Metod klienta wykorzystuje

wstrzyknięty obiekt fabryki

Wstrzyknięcie obiektu fabryki

Wstrzyknięcie obiektu fabryki

(24)

Wstrzykiwać można specjalizowane fabryki

Wstrzykiwać można specjalizowane fabryki

class LocalSQLServerFactory extends SQLServerFactory {

public AbstractServer createServer( ConfigFile config ) { // Utworzenie serwera w konfiguracji lokalnej

} }

class RemoteSQLServerFactory extends SQLServerFactory {

public AbstractServer createServer( ConfigFile config ) { // Utworzenie serwera w konfiguracji zdalnej

} }

class LocalSQLServerFactory extends SQLServerFactory {

public AbstractServer createServer( ConfigFile config ) { // Utworzenie serwera w konfiguracji lokalnej

} }

class RemoteSQLServerFactory extends SQLServerFactory {

public AbstractServer createServer( ConfigFile config ) { // Utworzenie serwera w konfiguracji zdalnej

} }

public class FabrykaDemo

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); if( localServerRequired() )

client.createAndUseServer( new LocalSQLServerFactory() ); else

client.createAndUseServer( new RemoteSQLServerFactory() ); }

}

public class FabrykaDemo

{

public static void main(String[] args) {

SQLFactoryClient client = new SQLFactoryClient(); if( localServerRequired() )

client.createAndUseServer( new LocalSQLServerFactory() ); else

client.createAndUseServer( new RemoteSQLServerFactory() ); }

}

Wstrzyknięcie różnych fabryk

Wstrzyknięcie różnych fabryk

(25)

Metod fabrykująca

Metod fabrykująca

Factory method

(26)

„Bezobiektowe” podejście do tworzenia obiektów

Bezobiektowe” podejście do tworzenia obiektów

Zastosowanie prostej fabryki wymaga utworzenie osobnej klasy dla fabryki

i wykorzystania zawartej w niej metody tworzącej konkretne obiekty.

Wykorzystanie fabryki statycznej pozwala na uproszczenie operacji (nie trzeba

tworzyć obiektu) kosztem utraty elastyczności.

Wzorzec metoda fabrykująca pozwala na rezygnację z klasy fabryki.

Odbywa się to poprzez umieszczenie metody tworzącej obiekty w klasie klienta

wzorca.

(27)

Metoda fabrykująca, przykład

Metoda fabrykująca, przykład

class SQLServerClient

{

ConfigFile cnfFile = new ConfigFile();

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null; }

public void createAndUseServer() {

// Utworzenie obiektu serwera z wykorzystaniem metody fabrykującej. AbstractServer base = createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLServerClient

{

ConfigFile cnfFile = new ConfigFile();

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null; }

public void createAndUseServer() {

// Utworzenie obiektu serwera z wykorzystaniem metody fabrykującej.

AbstractServer base = createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

(28)

Metoda fabrykująca, przykład

Metoda fabrykująca, przykład

class SQLServerClient

{

ConfigFile cnfFile = new ConfigFile();

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null; }

public void createAndUseServer() {

// Utworzenie obiektu serwera z wykorzystaniem metody fabrykującej. AbstractServer base = createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

class SQLServerClient

{

ConfigFile cnfFile = new ConfigFile();

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null; }

public void createAndUseServer() {

// Utworzenie obiektu serwera z wykorzystaniem metody fabrykującej.

AbstractServer base = createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

Ponownie kod nie jest zgodny

z zasadą Open/Close

Ponownie kod nie jest zgodny

z zasadą Open/Close

(29)

Abstrakcyjna metoda fabrykująca, przykład

Abstrakcyjna metoda fabrykująca, przykład

abstract class AbstractSQLServerClient

{

ConfigFile cnfFile = new ConfigFile();

public abstract AbstractServer createServer( ConfigFile config );

public void createAndUseServer() {

// Utworzenie obiektu serwera z wykorzystaniem metody fabrykującej. AbstractServer base = createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

}

abstract class AbstractSQLServerClient

{

ConfigFile cnfFile = new ConfigFile();

public abstract AbstractServer createServer( ConfigFile config );

public void createAndUseServer() {

// Utworzenie obiektu serwera z wykorzystaniem metody fabrykującej.

AbstractServer base = createServer( cnfFile );

base.execSQL( "select * from produkty" ); }

(30)

Abstrakcyjna metoda fabrykująca, przykład

Abstrakcyjna metoda fabrykująca, przykład

class SQLServerClient extends AbstractSQLServerClient

{

// Konkretna implementacja metody fabrykującej @Override

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null; }

}

AbstractSQLServerClient client = new SQLServerClient(); client.createAndUseServer();

class SQLServerClient extends AbstractSQLServerClient

{

// Konkretna implementacja metody fabrykującej

@Override

public AbstractServer createServer( ConfigFile config ) {

String dbType = config.getDataBaseType(); switch( dbType )

{

case "mysql" : return new MySQLServer();

case "postgresql" : return new PostgreSQLServer(); case "sqlite" : return new SQLiteServer();

case "sqlserver" : return new SQLServer(); }

return null; }

}

AbstractSQLServerClient client = new SQLServerClient();

client.createAndUseServer();

Utworzenie i wykorzystanie obiektu klienta wzorca.

Utworzenie i wykorzystanie obiektu klienta wzorca.

Cytaty

Powiązane dokumenty

Funkcja powinna sprawdzać, czy podana macierz jest kwadratowa i wykonywać obliczenia tylko w takim przypadku (wykorzystać instrukcję size()). Sumowanie elementów pod

Odtworzyć pełny backup c:\backup\demoLS.bak z opcją norecovery tak aby utworzyła się baza demoLS_Second, której pliki będą w katalogu d:\baza.. Polecenie restore musi

Proszę utworzyć tabelę, w której będą umieszone wartości logiczne ko- niunkcji, alternatywy, implikacji i równoważności3. Proszę utworzyć

jeden z uczniów przygotowuje pytania do ankiety, drugi uczeń opracowuje formularz ankiety, trzeci uczeń przygotowuje się do prowadzania ankiety. Należy zwrócić szczególną uwagę

Najpierw musisz zastanowić się jak będzie się nazywać twoje konto, przygotować sobie obrazek (plik graficzny) mające pełnić rolę efektownego nagłówka, przygotować kilka słów

void write(char[] cbuf, int off, int len) – metoda, która czyta z tablicy cbuf od indeksu off liczbę len znaków i zapisuje do pliku 5) Część łańcucha można zapisać

· Zdefiniowanie klasy dziedziczącej po klasie JFrame z pakietu Swing (lub JWindow) public class Prosta_Aplikacja2 extends JFrame}. {

2) Należy utworzyć obiekt, aby wywołać metodę niestatyczną klasy tego obiektu. 3) Atrybut statyczny należy do klasy i dlatego jest wspólny dla wszystkich.. obiektów. Dlatego