Дизайн паттерндер. 2-сабақ. Құру паттерндері (Creational patterns)

Блог аты abzalkalimbetov
Аты: Abstract Factory (Абстрактілі зауыт)
Проблема: Егер программалық жабдық әр түрлі платформада құрастырмалы (portable) болу керек болса, онда платформа байланыстарын сол кодта инкапсуляция (жасыру) жасау керек болады. «Платформалар» ретінде: терезе (window) жүйесі, операциялық жүйе, дерекқор (база), т.б бола алады. Егер программисттер бұл инкапсуляцияны қарастырмаса, программада көптеген жерлерде #ifdef, if, case сияқты операторларын көретін боламыз: платформалар мен ондағы опциялардың көбеюіне байланысты ол операторлар қояндар сияқты темппен кодта көбейіп кетеді. :)
Шешім: Бір-бірімен байланысқан не ұқсас объектілер тобына олардың нақты класын көрстепей интерфейс жасау. «Factory» объектісі белгілі бір платформаның бүкіл мүшелерін құруға арналған сервисті беруге міндетті.
Клиенттер платформа объектілерін (өнімдерді) ешқашан тікелей құрмайды, олар “Factory”-дан (зауыттан) сол өнімдерді құруды сұрайды.



AbstractFactory барлық зауыттарға интерфейс анықтайды, барлық зауыттар өнім шығару үшін сол интерфейстің реализациясын жасау керек: ConcreteFactoryA және ConcreteFactoryB сол интерфейстің реализациясын жасаған нақты кластар. AbstractProductA және AbstractProductB 2 түрлі өнімге интерфейстер. Әр зауыт осы AbstractProducts өнімдердің бірін құратын болады.
Клиент тек AbstractFactory, AbstractProductA және AbstractProduct-пен жұмыс жасайды. Олар реализация жайлы еш нәрсе білмейді. Клиент қолданатын AbstractFactory-дың реализациясы Runtime (орындалу уақытында) шешіледі.

Мысалы, бізде айталық 2 өнім: текстбокс және кнопка (button) бар.
1. Өнімге абстракт интерфейс құрамыз:

        public interface TextBox
	{    
    		public void setTitle(String text);

    		public void repaint();
	}
	public interface Button
	{
    		public void setTitle(String text);

    		public void repaint();
	}

2.Енді нақты өнімдер құрайық:
2.1. Windows платформасына:

        public class MSTextBox implements TextBox
	{
  		 public void setTitle()
  		{
   		  //MS Windows sai areketter
 		 }

  		 public void repaint()
  		{
     		//MS Windows sai areketter
  		}
	}

	public class MSButton implements Button
	{
  		 public void setTitle()
  		{
   		  //MS Windows sai areketter
 		 }

  		 public void repaint()
  		{
     		//MS Windows sai areketter
  		}
	}


2.2 Linux Gnome GUI-ге өнімдер:


    public class GnomeTextBox implements TextBox
	{
   		public void setTitle()
  		{
     		//Linux sai areketter 
  		}

   		public void repaint()
 		 {	
     		//Linux sai areketter
		}
	}

	public class GnomeButton implements Button
	{
   		public void setTitle()
  		{
     		//Linux sai areketter 
  		}

   		public void repaint()
 		 {	
     		//Linux sai areketter
		}
	}
    

3. Зауытқа интерфейс құрамыз

    //AbstractFactory
	public interface AbstractWidgetFactory
	{
   		public TextBox createTextBox();
		public Button createButton();
	}


4. Енді, нақты зауыттар құрамыз


        public class MsWindowsWidgetFactory implements AbstractWidgetFactory
	{
  		 public TextBox createTextBox()
   		{
      			MSTextBox t = new MSTextBox();   
      			return t;
   		}
		public Button createButton()
   		{
      			MSButton b = new MSButton();   
      			return b;
   		}
	}

	public class GnomeWidgetFactory implements AbstractWidgetFactory
	{
  		 public TextBox createTextBox()
   		{
      			GnomeTextBox t = new GnomeTextBox();   
      			return t;
   		}
		public Button createButton()
   		{
      			GnomeButton b = new GnomeButton();   
      			return b;
   		}
	}


5. Енді осыларды қолданатын Клиент құрайық:


        public class GUIBuilder
	{
   		public void buildWindow(AbstractWidgetFactory widgetFactory)
   		{
      		Button button = widgetFactory.createButton();   
      		button.setTitle("Button");
		TextBox textBox = widgetFactory.createTextBox();
		textBox.setTitle("Textbox");
   		}
	}


Осымен кластарымыз дайын. Енді кластарды қолдану ғана қалды. Біздін программа тек Windows пен Linux-қа жасайды. Енді MacOS -та жасау үшін не істеу керек? Ойланып көріңіз


        public class Main{
   		public static void main(String[] args)   
   		{
    		 	GUIBuilder builder = new GUIBuilder();
     			AbstractWidgetFactory widgetFactory = null;
     			//қандай платформа?
     			if(Platform.currentPlatform()=="Linux GNOME")
     			{
        		widgetFactory  = new GnomeWidgetFactory();
    			}
     			else
     			{
           		widgetFactory  = new MsWindowsWidgetFactory();
     			}
     			builder.buildWindow(widgetFactory); 
    			}
		}

Нәтиже: Бұл механизм өнімдер топтарын ауыстыруды жеңілдетеді, себебі “Faсtory” объектісі ПЖ-да бір жерде ғана, яғни құрылған сәтте ғана кездесетін болады. ПЖ абстрактілі зауыттың нақты класын құрып, белгілі-бір өнімдер тобын оңай ауыстыра алады.

9 пікір

avatar
қолданыңыз…
avatar
қолданыңыз…???
avatar
<cut>
avatar
?
avatar
Сіздің мына текст қысқаша көріну керек… Жалғасы мұнда деп
<cut>
деген тэгті тіркесеңіз сол жерден көрінбей қалады…
<cut>
Используется для больших текстов, скрывает под кат часть текста, следующую за тегом (будет написано «Читать дальше»).
<cut name="Жалғасын оқу">
Так можно превратить надпись «Читать дальше» в любой текст.
avatar
ааа) рахмет
avatar
<cut name="Жалғасын">
осылай қойсаңыз болды
avatar
Керемет! Автор, келер сабактарда алдымен алдынгы сабактын пикирлеринде айтылып кеткен ен коп колданлыатын паттерндер жайлы болса калай карайсыз?
Тек қана тіркелген және авторизациядан өткен қолданушылар пікір қалдыра алады.