Ver Mensaje Individual
  #2
Antiguo 22 de febrero de 2017, 15:03
Kuk
Administrador
Última Actividad 19.09.2026 20:11
Posts Posts: 2.500
Likes enviados Enviados: 1037
Likes recibidos Recibidos: 1207
Predeterminado Continuación...
0 Inactivo Inactivo

The concrete factory

A concrete factory implements the abstract factory "create" methods. It will be the only point in the code that we need to update after add a new checkout system. This is a very specialized class which only responsibility is to create the proper parts. Our application has two concrete factories: FujitsuConcreteFactory and HPConcrete Factory. If you analyse the code carefully you maybe realize that we could implement only one factory

Código COBOL:
  1.  CLASS-ID. FujitsuConcreteFactory as "AFP.FujitsuConcreteFactory".
  2.      environment division.
  3.          configuration section.
  4.              repository.
  5.                  interface ICheckoutAbstractFactory       as "AFP.ICheckoutAbstractFactory"
  6.                  interface ICashDrawerAbstractProduct     as "AFP.ICashDrawerAbstractProduct"
  7.                  interface IReceiptPrinterAbstractProduct as "AFP.IReceiptPrinterAbstractProduct"
  8.                
  9.                  *>Cash drawers classes
  10.                   class     ClassTeamPos1054258002         as "AFP.Drivers.CashDrawers.TeamPoS105428002"
  11.                   class     ClassTeamPos10PB60014         as "AFP.Drivers.CashDrawers.TeamPoS0PB60014"
  12.                  
  13.                   *>Receipt printers classes
  14.                   class     ClassTeamPOSFD21               as "AFP.Drivers.ReceiptPrinters.TeamPOSFD21"
  15.                   class     ClassTeamPOSFD22               as "AFP.Drivers.ReceiptPrinters.TeamPOSFD22"
  16.                  
  17.                   class     ClassUtils                     as "AFP.Utils"
  18.                   class     CollectionHashTable           as "System.Collections.Hashtable"
  19.                   class   ?SystemString                   as "System.String"
  20.                   class  ?SystemObject                   as "System.Object".
  21.       object. implements ICheckoutAbstractFactory.              
  22.           data division.
  23.               working-storage section.
  24.                   01 checkoutHardware    usage object reference SystemString.
  25.                   01 receiptPrinterName  pic n(80) value spaces.
  26.                   01 cashDrawerName      pic n(80) value spaces.
  27.                   01 driver              usage object reference SystemObject.
  28.                   01 drivers          ?usage object reference CollectionHashTable.            
  29.                  
  30.           procedure division.
  31.               method-id. NEW.
  32.                   procedure division.
  33.                      *> Getting all drivers at once
  34.                       invoke ClassUtils "GetCheckoutDrivers" returning drivers.
  35.                      
  36.               end method NEW.
  37.              
  38.               method-id. CreateCashDrawer as "CreateCashDrawer".  
  39.                   data division.
  40.                       linkage section.
  41.                           01 cashDrawer usage object reference ICashDrawerAbstractProduct.
  42.              
  43.                   procedure division returning cashDrawer.
  44.                  
  45.                       *> Get cashDrawer and receipt drivers
  46.                      
  47.                       set   driver            to  drivers::"get_Item"("CashDrawer")
  48.                       set   cashDrawerName    to  driver as SystemString
  49.                      
  50.                       *> creating the cash drawer class defined in the configuration file
  51.                       evaluate cashDrawerName
  52.                                when n"TeamPos1054258002"
  53.                                     invoke ClassTeamPos1054258002 "NEW" returning cashDrawer
  54.                                when n"TeamPos10PB60014"
  55.                                     invoke ClassTeamPos10PB60014 "NEW" returning cashDrawer
  56.                       end-evaluate
  57.              
  58.               end method CreateCashDrawer.
  59.               method-id. CreateReceiptPrinter as "CreateReceiptPrinter".  
  60.                   data division.
  61.                       linkage section.
  62.                           01 receiptPrinter usage object reference IReceiptPrinterAbstractProduct.
  63.              
  64.                   procedure division returning receiptPrinter.
  65.                      *> Get cashDrawer and receipt drivers
  66.                      
  67.                       set   driver              to  drivers::"get_Item"("ReceiptPrinter")
  68.                       set   receiptPrinterName  to  driver as SystemString
  69.                      
  70.                       *> creating the receipt printer class defined in the configuration file
  71.                      
  72.                       evaluate receiptPrinterName
  73.                                when n"TeamPoSFD21"
  74.                                     invoke ClassTeamPoSFD21 "NEW" returning receiptPrinter
  75.                                when n"TeamPoSFD22"
  76.                                     invoke ClassTeamPoSFD22 "NEW" returning receiptPrinter
  77.                       end-evaluate
  78.              
  79.               end method CreateReceiptPrinter.
  80.       end object.                
  81.   END CLASS FujitsuConcreteFactory.

The abstract product

An abstract product is the interface that allow the concrete factory to load the proper product. Without that interface, the concrete factory would be useless (or much more complex than the necessary). Below the interface for Receipt Printers:

Código COBOL:
  1.  INTERFACE-ID. IReceiptPrinterAbstractProduct as "AFP.IReceiptPrinterAbstractProduct".
  2.      environment division.
  3.          configuration section.
  4.              repository.
  5.                  interface ICashDrawerAbstractProduct     as "AFP.ICashDrawerAbstractProduct"
  6.                  
  7.                  class SystemString   as "System.String"
  8.                  class ClassUser     as "AFP.User"      
  9.                  class ClassCompany   as "AFP.Company"
  10.                   class ClassProduct   as "AFP.Product".  
  11.                  
  12.       procedure division.
  13.           method-id. StartNewSale as "StartNewSale".
  14.               data division.
  15.                   linkage section.
  16.                       01 company  ?usage object reference ClassCompany.
  17.                       01 user        usage object reference ClassUser.        
  18.              
  19.               procedure division using by value company, by value user.
  20.              
  21.           end method StartNewSale.
  22.          
  23.           method-id. RegisterItem as "RegisterItem".  
  24.               data division.
  25.                   linkage section.
  26.                       01 product?usage object reference ClassProduct.
  27.                       01 quantity  usage binary-long signed.
  28.              
  29.               procedure division using by value product, by value quantity.
  30.              
  31.           end method RegisterItem.
  32.           method-id. PrintTotal as "PrintTotal".
  33.               data division.
  34.                   linkage section.
  35.                       01 cashDrawer  usage object reference ICashDrawerAbstractProduct.
  36.                      
  37.               procedure division using by value cashDrawer.
  38.              
  39.           end method PrintTotal.
  40.          
  41.           *> ... and any other interfaces that you may need to implement
  42.          *> (e.g. CancelItem, CancelTransaction, PrintDiscount etc
  43.          
  44.   END INTERFACE IReceiptPrinterAbstractProduct.

The concrete product

A concrete product in our checkout architecture take care of all communications with the hardware, so we are calling them drivers in this context. Here is the a concrete product for a Fujitsu Cash Drawer:

Código COBOL:
  1.  CLASS-ID. TeamPoS0PB60014 as "AFP.Drivers.CashDrawers.TeamPoS0PB60014".
  2.      environment division.
  3.          configuration section.
  4.              repository.
  5.                  interface ICashDrawerAbstractProduct as "AFP.ICashDrawerAbstractProduct".
  6.      object. implements ICashDrawerAbstractProduct.              
  7.                  
  8.          procedure division.
  9.          method-id. OpenDrawer as "OpenDrawer".  
  10.              
  11.               procedure division.
  12.              
  13.                   display "Fujitsu cash drawer TeamPoS0PB60014 opened..."
  14.                  
  15.               *> here would go specific cash drawer API calls...
  16.              
  17.           end method OpenDrawer.
  18.          
  19.       end object.                
  20.   END CLASS TeamPoS0PB60014.

Using our factory

So, here is our abstract factory in action. You will notice that we are no longer directly instantiating the driver´s classes. Actually, that code has no idea which driver has been choosen. This has been delegated to the concrete factory. One very insteresting aspect is that our checkout parts can talk each other (for instance, when closing a sale, the receipt printer would open the cash drawer automatically).

Código COBOL:
  1.  CLASS-ID. ProcessOrder AS "NowYouAreTalking.ProcessOrder".
  2.            *> ...
  3.  method-id. ProcessNewOrder as "ProcessNewOrder".
  4.            *> ...
  5.   procedure division.
  6.  
  7.             *> ...
  8.            *> Creating a concrete factory
  9.              invoke ClassFujitsuConcreteFactory "NEW" returning checkout
  10.  
  11.              *> Creating cash drawer and receipt printer classes
  12.              invoke checkout "CreateCashDrawer"returning cashDrawer
  13.              invoke checkout "CreateReceiptPrinter" returning receiptPrinter
  14.             *> ...
  15.  
  16.              *> Using receipt printer
  17.              invoke receiptPrinter "StartNewSale" using aCompany, aUser
  18.              invoke receiptPrinter "RegisterItem" using aProduct, 10
  19.  
  20.              *> close order and open the cashDrawer
  21.              invoke receiptPrinter "PrintTotal" using cashDrawer
  22.   end method ProcessNewOrder.
  23.  end object.
  24.  END CLASS ProcessOrder.

Abstract Factories are eveywhere

ATMs, RTS games, DB connections, web frameworks and many more applications uses that useful pattern. Some examples:

Spring.Net (Web Framework)
.Net ADO.Net
Microsoft COM (yes, even the COM implements that pattern)


Download the source

Cool things with OO Cobol - Source Code


Some references in the web

Abstract Factory .NET Design Pattern in C# and VB - dofactory.com
Abstract factory pattern - Wikipedia



NORMAS DEL FORO - para garantizar el buen funcionamiento del Foro.
¿Te han ayudado? NO TE OLVIDES de darle a
¿Quieres dirigirte a alguien en tu post? Notifícale haciendo clic en su Nick
Kuk is offline   Responder Con Cita