De nombreuses applications financières doivent persister des données après leurs traitements algorithmiques. Par exemple, la gestion des portefeuilles demande d’enregistrer localement les résultats des ordres venant de différentes sources externes après le nettoyage des données dans les systèmes de stockage très variés : le système de gestion de base de données relationnelles (SGBDR), le système de gestion de base de données orienté objet (OODBMS), les documents XML, les fichiers Excel, le service Web, LDAP, etc. L’utilisateur pourrait appeler une méthode dans un module commun, qui contient tous les types d’enregistrement, en choisissant une manière de stockage désirée au gré du besoin. Néanmoins, si elle comprend tous ces types d’implémentations concrètes dont chacune propose une interface spécifique, elle ne sera pas facile à être maintenue ni étendue aux nouvelles fonctionnalités de persistance chez le client ultérieurement. Car cela viole le principe de responsabilité unique dans SOLID [1], qui stipule qu'un module, une classe ou même une méthode doit avoir une responsabilité unique et bien définie. Il ne devrait faire qu'une seule chose et n'avoir qu'une seule raison de changer. Sinon, quoi qu’elle soit dérisoire ou importante, une mise à jour sur une seule façon de stockage pourrait introduire la modification de toute la classe, voire tout le module, en risquant d’introduire les erreurs désastreuses.
Du coup en face de tel défi, le patron de conception dans la famille créatrice [2] « l’usine » : la fabrique (factory method en anglais) joue un rôle majeur et efficace en construisant tous les types d’objet qui s’occupe d’une persistance particulière à la sortie de résultat. Du fait, il y a une super classe abstraite de persistance avec plusieurs sous-classes concrètes et en fonction de l'argument d’entrée, la méthode de création de la classe factory va déterminer et retourner l'une des sous-classes. Cette conception retire la responsabilité de l'instanciation du programme chez le client aux sous-classes dans la fabrique. Sinon, au gré des contextes, elle pourrait renvoyer plusieurs fois la même instance [3, 4], ou renvoyer une sous-classe plutôt qu'un objet de ce type exact.
Conception
Le diagramme ULM illustre deux composants principaux dans le patron de conception Fabrique en Python 3, dont le 1e est un point d’accès de classe Factory qui décide et retourne l’objet final et le 2e comprend plusieurs classes concrètes dérivant d’une même interface, qui s’occupent d’instancier les objets.

Le client qui cherche à créer un objet accède à la classe Factory, dans laquelle la méthode statique make est appelée avec le nom de l’objet désiré. Cette méthode statique connaît tous les types d’instance des classes dérivant de l’interface en commun. Dès son analyse du besoin du client, la méthode renvoie directement la référence de l’objet demandé, lorsque cet objet est construit par la méthode de classe create implémentée dans une sous-classe concrète de l’interface abstraite.
Par conséquent, le principe de responsabilité unique est bien satisfait en faveur de la conception.
Développement
En Python 3 afin de distinguer clairement les types d’objet lors des appels dans le code, on met en place une classe énumérée PersistType qui donne tous les noms de persistance. Par exemple, dans cette application rudimentaire on a trois types de persistance dont les libraires en Python sont disponibles pour les ordres : XML [5], SGBDR [6], OODBMS [7].
Afin de simplifier la démonstration, on garde simplement les attributs basiques dans la classe Order pour les instances d’ordres. Du fait, à part les identifiants uniques pour chacun, on définit la date d’exécution, le montant d’exécution et la devise chez l’ordre. En plus, dans cet exemple le portefeuille ne contient que dix ordres exécutés il y a un jour. Les montants des ordres à la source sont générés de la façon aléatoire à la distribution uniforme [8] entre -100000,0 et 100000,0, lorsque leurs devises sont toujours en euro. Sinon, comme OODBMS demande un héritage de persistance dans sa librairie pour les ordres, on conçoit la classe OrderZo pour s’adapter à son objet d’enregistrement.
Dans un premier temps, on développe le 1e composant dans le schéma de la conception. En tant qu’un point d’accès, la classe PersistanceFactory est mise au point pour fournir les objets de persistance dont on a besoin. En sachant le nom du type de persistance, on y appelle la méthode statique make qui vérifie les conditions. Grâce à cette méthode, on peut trouver la classe de persistance pertinente à poursuivre l’instanciation concrète chez le 2e composant de la conception.
En effet, toutes ces classes de persistance ayant une méthode de classe create pour créer ses propres objets sont concrètement implémentées à partir de la interface abstraite IPersistance. Sinon, on y met en œuvre une méthode persist qui est responsable d’enregistrer les données des ordres pendant nos tests. Dès qu’une persistance instanciée sera été retournée par la méthode make chez la classe PersistanceFactory, la mise en persistance des données s’apprête à avoir lieu si la méthode persist est appelée.
resistance_factory.py
from abc import ABC, abstractmethod
from datetime import datetime, timedelta
from random import uniform
from xml.dom import minidom
from xml.etree import ElementTree as ET
from ZODB import FileStorage
import BTrees.OOBTree
import enum
import persistent.list
import pprint
import sqlite3
import transaction
import ZODB
pp = pprint.PrettyPrinter(indent=4)
class PersistType(enum.Enum):
""" An Enumerate Class to distinguish persistence """
XML = 1
SGBDR = 2
OODBMS = 3
class IPersistence(ABC):
""" An Abstract Class Interface (Persistence) """
name = None
@classmethod
@abstractmethod
def create(cls):
""" An abstract interface method to create persistence """
pass
@abstractmethod
def persist(self, orders: list):
"""
An abstract interface method to persist orders
Attributes
----------
orders : list
The orders to stock.
"""
pass
class Order(object):
def __init__(self):
self._order_id = None
self._pricing_date = None
self._amount = None
self._currency = None
@property
def order_id(self):
return self._order_id
@property
def pricing_date(self):
return self._pricing_date
@property
def amount(self):
return self._amount
@property
def currency(self):
return self._currency
@order_id.setter
def order_id(self, value):
self._order_id = value
@pricing_date.setter
def pricing_date(self, value):
self._pricing_date = value
@amount.setter
def amount(self, value):
self._amount = value
@currency.setter
def currency(self, value):
self._currency = value
def __repr__(self):
message = f"<{type(self).__name__}: "
message += "; ".join(f"{k}, {v}" for k, v in vars(self).items())
message += '>'
return message
class OrderZo(Order, persistent.Persistent):
def __init__(self, odr: Order):
"""
:param odr: Order
to adapt the ZODB persistent object
"""
super().__init__()
self._order_id = odr.order_id
self._pricing_date = odr.pricing_date
self._amount = odr.amount
self._currency = odr.currency
class PersistenceOfXML(IPersistence):
""" A Concrete XML Class that implements the IPersistence interface """
name = PersistType.XML
def __init__(self):
self._engine = 'XML Engine'
self.root = ET.Element('orders')
def persist(self, orders: list):
for order in orders:
order_et = ET.SubElement(self.root, 'order')
o_id = ET.SubElement(order_et, 'order_id')
o_id.text = str(order.order_id)
pricing_date = ET.SubElement(order_et, 'pricing_date')
pricing_date.text = order.pricing_date.strftime(
'%Y/%m/%d %H:%M:%S.%f')
amount = ET.SubElement(order_et, 'amount')
amount.text = str(order.amount)
currency = ET.SubElement(order_et, 'currency')
currency.text = order.currency
xml_str = minidom.parseString(
ET.tostring(self.root)).toprettyxml(
indent=" "
)
with open("XML.xml", "w") as f:
f.write(xml_str)
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('XML persistence will be ready...')
return cls()
class PersistenceOfSGBDR(IPersistence):
""" A Concrete SGBDR Class that implements the IPersistence interface """
name = PersistType.SGBDR
def __init__(self):
self._engine = 'SGBDR Engine'
self.conn = None
try:
self.conn = sqlite3.connect('SGBDR.db')
except Exception as e:
print(e)
cur = self.conn.cursor()
# Drop any existing table with the same name
try:
drop_table = "DROP TABLE ORDERS"
cur.execute(drop_table)
except Exception as e:
print(e)
# Create a table in the disk file based database
create_table = (f"CREATE TABLE IF NOT EXISTS ORDERS("
f"ORDER_ID INTEGER PRIMARY KEY, "
f"PRICING_DATE DATETIME NOT NULL, "
f"AMOUNT NUMERIC(10,8), "
f"CURRENCY CHARACTER(3))")
cur.execute(create_table)
# commit the table to db
self.conn.commit()
def persist(self, orders: list):
cur = self.conn.cursor()
for order in orders:
sql = '''
INSERT INTO ORDERS(ORDER_ID, PRICING_DATE, AMOUNT, CURRENCY)
VALUES(?,?,?,?)
'''
cur.execute(sql, (order.order_id,
order.pricing_date,
order.amount,
order.currency))
self.conn.commit()
self.conn.close()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine} ending in {cur.lastrowid}...")
@classmethod
def create(cls) -> IPersistence:
print('SGBDR persistence will be ready...')
return cls()
class PersistenceOfOODBMS(IPersistence):
""" A Concrete OODBMS Class that implements the IPersistence interface """
name = PersistType.OODBMS
def __init__(self):
self._engine = 'OODBMS Engine'
storage = FileStorage.FileStorage('OODBMS.fs')
db = ZODB.DB(storage)
connection = db.open()
self.root = connection.root
def persist(self, orders: list):
self.root.orders = BTrees.OOBTree.BTree()
self.root.orders = [OrderZo(z) for z in orders]
transaction.commit()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('OODBMS persistence will be ready...')
return cls()
class PersistenceFactory(object):
""" The Persistence Factory Class """
@staticmethod
def make(name) -> IPersistence:
""" A static method to get a concrete product """
if name == PersistType.XML:
return PersistenceOfXML.create()
if name == PersistType.SGBDR:
return PersistenceOfSGBDR.create()
if name == PersistType.OODBMS:
return PersistenceOfOODBMS.create()
if __name__ == '__main__
resistance_factory.py
from abc import ABC, abstractmethod
from datetime import datetime, timedelta
from random import uniform
from xml.dom import minidom
from xml.etree import ElementTree as ET
from ZODB import FileStorage
import BTrees.OOBTree
import enum
import persistent.list
import pprint
import sqlite3
import transaction
import ZODB
pp = pprint.PrettyPrinter(indent=4)
class PersistType(enum.Enum):
""" An Enumerate Class to distinguish persistence """
XML = 1
SGBDR = 2
OODBMS = 3
class IPersistence(ABC):
""" An Abstract Class Interface (Persistence) """
name = None
@classmethod
@abstractmethod
def create(cls):
""" An abstract interface method to create persistence """
pass
@abstractmethod
def persist(self, orders: list):
"""
An abstract interface method to persist orders
Attributes
----------
orders : list
The orders to stock.
"""
pass
class Order(object):
def __init__(self):
self._order_id = None
self._pricing_date = None
self._amount = None
self._currency = None
@property
def order_id(self):
return self._order_id
@property
def pricing_date(self):
return self._pricing_date
@property
def amount(self):
return self._amount
@property
def currency(self):
return self._currency
@order_id.setter
def order_id(self, value):
self._order_id = value
@pricing_date.setter
def pricing_date(self, value):
self._pricing_date = value
@amount.setter
def amount(self, value):
self._amount = value
@currency.setter
def currency(self, value):
self._currency = value
def __repr__(self):
message = f"<{type(self).__name__}: "
message += "; ".join(f"{k}, {v}" for k, v in vars(self).items())
message += '>'
return message
class OrderZo(Order, persistent.Persistent):
def __init__(self, odr: Order):
"""
:param odr: Order
to adapt the ZODB persistent object
"""
super().__init__()
self._order_id = odr.order_id
self._pricing_date = odr.pricing_date
self._amount = odr.amount
self._currency = odr.currency
class PersistenceOfXML(IPersistence):
""" A Concrete XML Class that implements the IPersistence interface """
name = PersistType.XML
def __init__(self):
self._engine = 'XML Engine'
self.root = ET.Element('orders')
def persist(self, orders: list):
for order in orders:
order_et = ET.SubElement(self.root, 'order')
o_id = ET.SubElement(order_et, 'order_id')
o_id.text = str(order.order_id)
pricing_date = ET.SubElement(order_et, 'pricing_date')
pricing_date.text = order.pricing_date.strftime(
'%Y/%m/%d %H:%M:%S.%f')
amount = ET.SubElement(order_et, 'amount')
amount.text = str(order.amount)
currency = ET.SubElement(order_et, 'currency')
currency.text = order.currency
xml_str = minidom.parseString(
ET.tostring(self.root)).toprettyxml(
indent=" "
)
with open("XML.xml", "w") as f:
f.write(xml_str)
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('XML persistence will be ready...')
return cls()
class PersistenceOfSGBDR(IPersistence):
""" A Concrete SGBDR Class that implements the IPersistence interface """
name = PersistType.SGBDR
def __init__(self):
self._engine = 'SGBDR Engine'
self.conn = None
try:
self.conn = sqlite3.connect('SGBDR.db')
except Exception as e:
print(e)
cur = self.conn.cursor()
# Drop any existing table with the same name
try:
drop_table = "DROP TABLE ORDERS"
cur.execute(drop_table)
except Exception as e:
print(e)
# Create a table in the disk file based database
create_table = (f"CREATE TABLE IF NOT EXISTS ORDERS("
f"ORDER_ID INTEGER PRIMARY KEY, "
f"PRICING_DATE DATETIME NOT NULL, "
f"AMOUNT NUMERIC(10,8), "
f"CURRENCY CHARACTER(3))")
cur.execute(create_table)
# commit the table to db
self.conn.commit()
def persist(self, orders: list):
cur = self.conn.cursor()
for order in orders:
sql = '''
INSERT INTO ORDERS(ORDER_ID, PRICING_DATE, AMOUNT, CURRENCY)
VALUES(?,?,?,?)
'''
cur.execute(sql, (order.order_id,
order.pricing_date,
order.amount,
order.currency))
self.conn.commit()
self.conn.close()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine} ending in {cur.lastrowid}...")
@classmethod
def create(cls) -> IPersistence:
print('SGBDR persistence will be ready...')
return cls()
class PersistenceOfOODBMS(IPersistence):
""" A Concrete OODBMS Class that implements the IPersistence interface """
name = PersistType.OODBMS
def __init__(self):
self._engine = 'OODBMS Engine'
storage = FileStorage.FileStorage('OODBMS.fs')
db = ZODB.DB(storage)
connection = db.open()
self.root = connection.root
def persist(self, orders: list):
self.root.orders = BTrees.OOBTree.BTree()
self.root.orders = [OrderZo(z) for z in orders]
transaction.commit()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('OODBMS persistence will be ready...')
return cls()
class PersistenceFactory(object):
""" The Persistence Factory Class """
@staticmethod
def make(name) -> IPersistence:
""" A static method to get a concrete product """
if name == PersistType.XML:
return PersistenceOfXML.create()
if name == PersistType.SGBDR:
return PersistenceOfSGBDR.create()
if name == PersistType.OODBMS:
return PersistenceOfOODBMS.create()
if __name__ == '__main__
resistance_factory.py
from abc import ABC, abstractmethod
from datetime import datetime, timedelta
from random import uniform
from xml.dom import minidom
from xml.etree import ElementTree as ET
from ZODB import FileStorage
import BTrees.OOBTree
import enum
import persistent.list
import pprint
import sqlite3
import transaction
import ZODB
pp = pprint.PrettyPrinter(indent=4)
class PersistType(enum.Enum):
""" An Enumerate Class to distinguish persistence """
XML = 1
SGBDR = 2
OODBMS = 3
class IPersistence(ABC):
""" An Abstract Class Interface (Persistence) """
name = None
@classmethod
@abstractmethod
def create(cls):
""" An abstract interface method to create persistence """
pass
@abstractmethod
def persist(self, orders: list):
"""
An abstract interface method to persist orders
Attributes
----------
orders : list
The orders to stock.
"""
pass
class Order(object):
def __init__(self):
self._order_id = None
self._pricing_date = None
self._amount = None
self._currency = None
@property
def order_id(self):
return self._order_id
@property
def pricing_date(self):
return self._pricing_date
@property
def amount(self):
return self._amount
@property
def currency(self):
return self._currency
@order_id.setter
def order_id(self, value):
self._order_id = value
@pricing_date.setter
def pricing_date(self, value):
self._pricing_date = value
@amount.setter
def amount(self, value):
self._amount = value
@currency.setter
def currency(self, value):
self._currency = value
def __repr__(self):
message = f"<{type(self).__name__}: "
message += "; ".join(f"{k}, {v}" for k, v in vars(self).items())
message += '>'
return message
class OrderZo(Order, persistent.Persistent):
def __init__(self, odr: Order):
"""
:param odr: Order
to adapt the ZODB persistent object
"""
super().__init__()
self._order_id = odr.order_id
self._pricing_date = odr.pricing_date
self._amount = odr.amount
self._currency = odr.currency
class PersistenceOfXML(IPersistence):
""" A Concrete XML Class that implements the IPersistence interface """
name = PersistType.XML
def __init__(self):
self._engine = 'XML Engine'
self.root = ET.Element('orders')
def persist(self, orders: list):
for order in orders:
order_et = ET.SubElement(self.root, 'order')
o_id = ET.SubElement(order_et, 'order_id')
o_id.text = str(order.order_id)
pricing_date = ET.SubElement(order_et, 'pricing_date')
pricing_date.text = order.pricing_date.strftime(
'%Y/%m/%d %H:%M:%S.%f')
amount = ET.SubElement(order_et, 'amount')
amount.text = str(order.amount)
currency = ET.SubElement(order_et, 'currency')
currency.text = order.currency
xml_str = minidom.parseString(
ET.tostring(self.root)).toprettyxml(
indent=" "
)
with open("XML.xml", "w") as f:
f.write(xml_str)
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('XML persistence will be ready...')
return cls()
class PersistenceOfSGBDR(IPersistence):
""" A Concrete SGBDR Class that implements the IPersistence interface """
name = PersistType.SGBDR
def __init__(self):
self._engine = 'SGBDR Engine'
self.conn = None
try:
self.conn = sqlite3.connect('SGBDR.db')
except Exception as e:
print(e)
cur = self.conn.cursor()
# Drop any existing table with the same name
try:
drop_table = "DROP TABLE ORDERS"
cur.execute(drop_table)
except Exception as e:
print(e)
# Create a table in the disk file based database
create_table = (f"CREATE TABLE IF NOT EXISTS ORDERS("
f"ORDER_ID INTEGER PRIMARY KEY, "
f"PRICING_DATE DATETIME NOT NULL, "
f"AMOUNT NUMERIC(10,8), "
f"CURRENCY CHARACTER(3))")
cur.execute(create_table)
# commit the table to db
self.conn.commit()
def persist(self, orders: list):
cur = self.conn.cursor()
for order in orders:
sql = '''
INSERT INTO ORDERS(ORDER_ID, PRICING_DATE, AMOUNT, CURRENCY)
VALUES(?,?,?,?)
'''
cur.execute(sql, (order.order_id,
order.pricing_date,
order.amount,
order.currency))
self.conn.commit()
self.conn.close()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine} ending in {cur.lastrowid}...")
@classmethod
def create(cls) -> IPersistence:
print('SGBDR persistence will be ready...')
return cls()
class PersistenceOfOODBMS(IPersistence):
""" A Concrete OODBMS Class that implements the IPersistence interface """
name = PersistType.OODBMS
def __init__(self):
self._engine = 'OODBMS Engine'
storage = FileStorage.FileStorage('OODBMS.fs')
db = ZODB.DB(storage)
connection = db.open()
self.root = connection.root
def persist(self, orders: list):
self.root.orders = BTrees.OOBTree.BTree()
self.root.orders = [OrderZo(z) for z in orders]
transaction.commit()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('OODBMS persistence will be ready...')
return cls()
class PersistenceFactory(object):
""" The Persistence Factory Class """
@staticmethod
def make(name) -> IPersistence:
""" A static method to get a concrete product """
if name == PersistType.XML:
return PersistenceOfXML.create()
if name == PersistType.SGBDR:
return PersistenceOfSGBDR.create()
if name == PersistType.OODBMS:
return PersistenceOfOODBMS.create()
if __name__ == '__main__
resistance_factory.py
from abc import ABC, abstractmethod
from datetime import datetime, timedelta
from random import uniform
from xml.dom import minidom
from xml.etree import ElementTree as ET
from ZODB import FileStorage
import BTrees.OOBTree
import enum
import persistent.list
import pprint
import sqlite3
import transaction
import ZODB
pp = pprint.PrettyPrinter(indent=4)
class PersistType(enum.Enum):
""" An Enumerate Class to distinguish persistence """
XML = 1
SGBDR = 2
OODBMS = 3
class IPersistence(ABC):
""" An Abstract Class Interface (Persistence) """
name = None
@classmethod
@abstractmethod
def create(cls):
""" An abstract interface method to create persistence """
pass
@abstractmethod
def persist(self, orders: list):
"""
An abstract interface method to persist orders
Attributes
----------
orders : list
The orders to stock.
"""
pass
class Order(object):
def __init__(self):
self._order_id = None
self._pricing_date = None
self._amount = None
self._currency = None
@property
def order_id(self):
return self._order_id
@property
def pricing_date(self):
return self._pricing_date
@property
def amount(self):
return self._amount
@property
def currency(self):
return self._currency
@order_id.setter
def order_id(self, value):
self._order_id = value
@pricing_date.setter
def pricing_date(self, value):
self._pricing_date = value
@amount.setter
def amount(self, value):
self._amount = value
@currency.setter
def currency(self, value):
self._currency = value
def __repr__(self):
message = f"<{type(self).__name__}: "
message += "; ".join(f"{k}, {v}" for k, v in vars(self).items())
message += '>'
return message
class OrderZo(Order, persistent.Persistent):
def __init__(self, odr: Order):
"""
:param odr: Order
to adapt the ZODB persistent object
"""
super().__init__()
self._order_id = odr.order_id
self._pricing_date = odr.pricing_date
self._amount = odr.amount
self._currency = odr.currency
class PersistenceOfXML(IPersistence):
""" A Concrete XML Class that implements the IPersistence interface """
name = PersistType.XML
def __init__(self):
self._engine = 'XML Engine'
self.root = ET.Element('orders')
def persist(self, orders: list):
for order in orders:
order_et = ET.SubElement(self.root, 'order')
o_id = ET.SubElement(order_et, 'order_id')
o_id.text = str(order.order_id)
pricing_date = ET.SubElement(order_et, 'pricing_date')
pricing_date.text = order.pricing_date.strftime(
'%Y/%m/%d %H:%M:%S.%f')
amount = ET.SubElement(order_et, 'amount')
amount.text = str(order.amount)
currency = ET.SubElement(order_et, 'currency')
currency.text = order.currency
xml_str = minidom.parseString(
ET.tostring(self.root)).toprettyxml(
indent=" "
)
with open("XML.xml", "w") as f:
f.write(xml_str)
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('XML persistence will be ready...')
return cls()
class PersistenceOfSGBDR(IPersistence):
""" A Concrete SGBDR Class that implements the IPersistence interface """
name = PersistType.SGBDR
def __init__(self):
self._engine = 'SGBDR Engine'
self.conn = None
try:
self.conn = sqlite3.connect('SGBDR.db')
except Exception as e:
print(e)
cur = self.conn.cursor()
# Drop any existing table with the same name
try:
drop_table = "DROP TABLE ORDERS"
cur.execute(drop_table)
except Exception as e:
print(e)
# Create a table in the disk file based database
create_table = (f"CREATE TABLE IF NOT EXISTS ORDERS("
f"ORDER_ID INTEGER PRIMARY KEY, "
f"PRICING_DATE DATETIME NOT NULL, "
f"AMOUNT NUMERIC(10,8), "
f"CURRENCY CHARACTER(3))")
cur.execute(create_table)
# commit the table to db
self.conn.commit()
def persist(self, orders: list):
cur = self.conn.cursor()
for order in orders:
sql = '''
INSERT INTO ORDERS(ORDER_ID, PRICING_DATE, AMOUNT, CURRENCY)
VALUES(?,?,?,?)
'''
cur.execute(sql, (order.order_id,
order.pricing_date,
order.amount,
order.currency))
self.conn.commit()
self.conn.close()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine} ending in {cur.lastrowid}...")
@classmethod
def create(cls) -> IPersistence:
print('SGBDR persistence will be ready...')
return cls()
class PersistenceOfOODBMS(IPersistence):
""" A Concrete OODBMS Class that implements the IPersistence interface """
name = PersistType.OODBMS
def __init__(self):
self._engine = 'OODBMS Engine'
storage = FileStorage.FileStorage('OODBMS.fs')
db = ZODB.DB(storage)
connection = db.open()
self.root = connection.root
def persist(self, orders: list):
self.root.orders = BTrees.OOBTree.BTree()
self.root.orders = [OrderZo(z) for z in orders]
transaction.commit()
pp.pprint(f"populating")
pp.pprint(orders)
pp.pprint(f"by {self._engine}...")
@classmethod
def create(cls) -> IPersistence:
print('OODBMS persistence will be ready...')
return cls()
class PersistenceFactory(object):
""" The Persistence Factory Class """
@staticmethod
def make(name) -> IPersistence:
""" A static method to get a concrete product """
if name == PersistType.XML:
return PersistenceOfXML.create()
if name == PersistType.SGBDR:
return PersistenceOfSGBDR.create()
if name == PersistType.OODBMS:
return PersistenceOfOODBMS.create()
if __name__ == '__main__
Les tests unitaires se valident par les types des objets créés au gré du besoin, tandis que les affichages des différentes phases de persistance pour dix ordres sont mis en lumière en-dessous :
In Phase 0: XML persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.577233; _amount, 8682.064027577868; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.577271; _amount, 1178.6677560764638; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.577280; _amount, 877.1820266699797; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.577285; _amount, 3557.339177963937; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.577290; _amount, -8528.180149274358; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.577294; _amount, -4527.9443459321665; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.577299; _amount, -6062.7853847754905; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.577303; _amount, 1449.8770822999832; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.577308; _amount, -1708.4810066747305; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.577317; _amount, 5091.879830019116; _currency, EUR>] 'by XML Engine...' In Phase 1: SGBDR persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.588848; _amount, 8990.32508880787; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.588875; _amount, -7029.962047408302; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.588884; _amount, -6521.53303624182; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.588891; _amount, 8693.092444597798; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.588897; _amount, 9584.87989883318; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.588903; _amount, -8554.88392848472; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.588908; _amount, 3109.2992332277263; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.588914; _amount, -7536.156871450268; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.588919; _amount, 8377.004299016604; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.588925; _amount, 4520.661799666674; _currency, EUR>] 'by SGBDR Engine ending in 9...' In Phase 2: OODBMS persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.595025; _amount, 4467.882449831253; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.595049; _amount, 5956.087440158884; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.595058; _amount, 7233.788601777396; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.595065; _amount, 8032.730099866159; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.595072; _amount, 118.40014380573666; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.595079; _amount, 2196.295149587426; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.595087; _amount, 580.9771003834958; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.595093; _amount, 9547.969637860293; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.595100; _amount, 3679.870172622952; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.595108; _amount, -4532.329828675801; _currency, EUR>]
In Phase 0: XML persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.577233; _amount, 8682.064027577868; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.577271; _amount, 1178.6677560764638; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.577280; _amount, 877.1820266699797; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.577285; _amount, 3557.339177963937; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.577290; _amount, -8528.180149274358; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.577294; _amount, -4527.9443459321665; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.577299; _amount, -6062.7853847754905; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.577303; _amount, 1449.8770822999832; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.577308; _amount, -1708.4810066747305; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.577317; _amount, 5091.879830019116; _currency, EUR>] 'by XML Engine...' In Phase 1: SGBDR persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.588848; _amount, 8990.32508880787; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.588875; _amount, -7029.962047408302; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.588884; _amount, -6521.53303624182; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.588891; _amount, 8693.092444597798; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.588897; _amount, 9584.87989883318; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.588903; _amount, -8554.88392848472; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.588908; _amount, 3109.2992332277263; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.588914; _amount, -7536.156871450268; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.588919; _amount, 8377.004299016604; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.588925; _amount, 4520.661799666674; _currency, EUR>] 'by SGBDR Engine ending in 9...' In Phase 2: OODBMS persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.595025; _amount, 4467.882449831253; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.595049; _amount, 5956.087440158884; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.595058; _amount, 7233.788601777396; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.595065; _amount, 8032.730099866159; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.595072; _amount, 118.40014380573666; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.595079; _amount, 2196.295149587426; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.595087; _amount, 580.9771003834958; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.595093; _amount, 9547.969637860293; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.595100; _amount, 3679.870172622952; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.595108; _amount, -4532.329828675801; _currency, EUR>]
In Phase 0: XML persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.577233; _amount, 8682.064027577868; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.577271; _amount, 1178.6677560764638; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.577280; _amount, 877.1820266699797; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.577285; _amount, 3557.339177963937; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.577290; _amount, -8528.180149274358; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.577294; _amount, -4527.9443459321665; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.577299; _amount, -6062.7853847754905; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.577303; _amount, 1449.8770822999832; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.577308; _amount, -1708.4810066747305; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.577317; _amount, 5091.879830019116; _currency, EUR>] 'by XML Engine...' In Phase 1: SGBDR persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.588848; _amount, 8990.32508880787; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.588875; _amount, -7029.962047408302; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.588884; _amount, -6521.53303624182; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.588891; _amount, 8693.092444597798; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.588897; _amount, 9584.87989883318; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.588903; _amount, -8554.88392848472; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.588908; _amount, 3109.2992332277263; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.588914; _amount, -7536.156871450268; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.588919; _amount, 8377.004299016604; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.588925; _amount, 4520.661799666674; _currency, EUR>] 'by SGBDR Engine ending in 9...' In Phase 2: OODBMS persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.595025; _amount, 4467.882449831253; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.595049; _amount, 5956.087440158884; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.595058; _amount, 7233.788601777396; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.595065; _amount, 8032.730099866159; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.595072; _amount, 118.40014380573666; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.595079; _amount, 2196.295149587426; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.595087; _amount, 580.9771003834958; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.595093; _amount, 9547.969637860293; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.595100; _amount, 3679.870172622952; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.595108; _amount, -4532.329828675801; _currency, EUR>]
In Phase 0: XML persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.577233; _amount, 8682.064027577868; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.577271; _amount, 1178.6677560764638; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.577280; _amount, 877.1820266699797; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.577285; _amount, 3557.339177963937; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.577290; _amount, -8528.180149274358; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.577294; _amount, -4527.9443459321665; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.577299; _amount, -6062.7853847754905; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.577303; _amount, 1449.8770822999832; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.577308; _amount, -1708.4810066747305; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.577317; _amount, 5091.879830019116; _currency, EUR>] 'by XML Engine...' In Phase 1: SGBDR persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.588848; _amount, 8990.32508880787; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.588875; _amount, -7029.962047408302; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.588884; _amount, -6521.53303624182; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.588891; _amount, 8693.092444597798; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.588897; _amount, 9584.87989883318; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.588903; _amount, -8554.88392848472; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.588908; _amount, 3109.2992332277263; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.588914; _amount, -7536.156871450268; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.588919; _amount, 8377.004299016604; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.588925; _amount, 4520.661799666674; _currency, EUR>] 'by SGBDR Engine ending in 9...' In Phase 2: OODBMS persistence will be ready... 'populating' [ <Order: _order_id, 0; _pricing_date, 2022-03-12 22:57:18.595025; _amount, 4467.882449831253; _currency, EUR>, <Order: _order_id, 1; _pricing_date, 2022-03-12 22:57:18.595049; _amount, 5956.087440158884; _currency, EUR>, <Order: _order_id, 2; _pricing_date, 2022-03-12 22:57:18.595058; _amount, 7233.788601777396; _currency, EUR>, <Order: _order_id, 3; _pricing_date, 2022-03-12 22:57:18.595065; _amount, 8032.730099866159; _currency, EUR>, <Order: _order_id, 4; _pricing_date, 2022-03-12 22:57:18.595072; _amount, 118.40014380573666; _currency, EUR>, <Order: _order_id, 5; _pricing_date, 2022-03-12 22:57:18.595079; _amount, 2196.295149587426; _currency, EUR>, <Order: _order_id, 6; _pricing_date, 2022-03-12 22:57:18.595087; _amount, 580.9771003834958; _currency, EUR>, <Order: _order_id, 7; _pricing_date, 2022-03-12 22:57:18.595093; _amount, 9547.969637860293; _currency, EUR>, <Order: _order_id, 8; _pricing_date, 2022-03-12 22:57:18.595100; _amount, 3679.870172622952; _currency, EUR>, <Order: _order_id, 9; _pricing_date, 2022-03-12 22:57:18.595108; _amount, -4532.329828675801; _currency, EUR>]
Comme tous les types de persistance sont testés par trois itérations dans le programme, les objets de persistance XML, SGBDR et OODBMS sont instanciés l’un après l’autre avant leurs enregistrements de données des ordres.
Le ficher XML.xml stocke les ordres ainsi :
<?xml version="1.0" ?> <orders> <order> <order_id>0</order_id> <pricing_date>2022/03/12 22:57:18.577233</pricing_date> <amount>8682.064027577868</amount> <currency>EUR</currency> </order> <order> <order_id>1</order_id> <pricing_date>2022/03/12 22:57:18.577271</pricing_date> <amount>1178.6677560764638</amount> <currency>EUR</currency> </order> <order> <order_id>2</order_id> <pricing_date>2022/03/12 22:57:18.577280</pricing_date> <amount>877.1820266699797</amount> <currency>EUR</currency> </order> <order> <order_id>3</order_id> <pricing_date>2022/03/12 22:57:18.577285</pricing_date> <amount>3557.339177963937</amount> <currency>EUR</currency> </order> <order> <order_id>4</order_id> <pricing_date>2022/03/12 22:57:18.577290</pricing_date> <amount>-8528.180149274358</amount> <currency>EUR</currency> </order> <order> <order_id>5</order_id> <pricing_date>2022/03/12 22:57:18.577294</pricing_date> <amount>-4527.9443459321665</amount> <currency>EUR</currency> </order> <order> <order_id>6</order_id> <pricing_date>2022/03/12 22:57:18.577299</pricing_date> <amount>-6062.7853847754905</amount> <currency>EUR</currency> </order> <order> <order_id>7</order_id> <pricing_date>2022/03/12 22:57:18.577303</pricing_date> <amount>1449.8770822999832</amount> <currency>EUR</currency> </order> <order> <order_id>8</order_id> <pricing_date>2022/03/12 22:57:18.577308</pricing_date> <amount>-1708.4810066747305</amount> <currency>EUR</currency> </order> <order> <order_id>9</order_id> <pricing_date>2022/03/12 22:57:18.577317</pricing_date> <amount>5091.879830019116</amount> <currency>EUR</currency> </order> </orders>
<?xml version="1.0" ?> <orders> <order> <order_id>0</order_id> <pricing_date>2022/03/12 22:57:18.577233</pricing_date> <amount>8682.064027577868</amount> <currency>EUR</currency> </order> <order> <order_id>1</order_id> <pricing_date>2022/03/12 22:57:18.577271</pricing_date> <amount>1178.6677560764638</amount> <currency>EUR</currency> </order> <order> <order_id>2</order_id> <pricing_date>2022/03/12 22:57:18.577280</pricing_date> <amount>877.1820266699797</amount> <currency>EUR</currency> </order> <order> <order_id>3</order_id> <pricing_date>2022/03/12 22:57:18.577285</pricing_date> <amount>3557.339177963937</amount> <currency>EUR</currency> </order> <order> <order_id>4</order_id> <pricing_date>2022/03/12 22:57:18.577290</pricing_date> <amount>-8528.180149274358</amount> <currency>EUR</currency> </order> <order> <order_id>5</order_id> <pricing_date>2022/03/12 22:57:18.577294</pricing_date> <amount>-4527.9443459321665</amount> <currency>EUR</currency> </order> <order> <order_id>6</order_id> <pricing_date>2022/03/12 22:57:18.577299</pricing_date> <amount>-6062.7853847754905</amount> <currency>EUR</currency> </order> <order> <order_id>7</order_id> <pricing_date>2022/03/12 22:57:18.577303</pricing_date> <amount>1449.8770822999832</amount> <currency>EUR</currency> </order> <order> <order_id>8</order_id> <pricing_date>2022/03/12 22:57:18.577308</pricing_date> <amount>-1708.4810066747305</amount> <currency>EUR</currency> </order> <order> <order_id>9</order_id> <pricing_date>2022/03/12 22:57:18.577317</pricing_date> <amount>5091.879830019116</amount> <currency>EUR</currency> </order> </orders>
<?xml version="1.0" ?> <orders> <order> <order_id>0</order_id> <pricing_date>2022/03/12 22:57:18.577233</pricing_date> <amount>8682.064027577868</amount> <currency>EUR</currency> </order> <order> <order_id>1</order_id> <pricing_date>2022/03/12 22:57:18.577271</pricing_date> <amount>1178.6677560764638</amount> <currency>EUR</currency> </order> <order> <order_id>2</order_id> <pricing_date>2022/03/12 22:57:18.577280</pricing_date> <amount>877.1820266699797</amount> <currency>EUR</currency> </order> <order> <order_id>3</order_id> <pricing_date>2022/03/12 22:57:18.577285</pricing_date> <amount>3557.339177963937</amount> <currency>EUR</currency> </order> <order> <order_id>4</order_id> <pricing_date>2022/03/12 22:57:18.577290</pricing_date> <amount>-8528.180149274358</amount> <currency>EUR</currency> </order> <order> <order_id>5</order_id> <pricing_date>2022/03/12 22:57:18.577294</pricing_date> <amount>-4527.9443459321665</amount> <currency>EUR</currency> </order> <order> <order_id>6</order_id> <pricing_date>2022/03/12 22:57:18.577299</pricing_date> <amount>-6062.7853847754905</amount> <currency>EUR</currency> </order> <order> <order_id>7</order_id> <pricing_date>2022/03/12 22:57:18.577303</pricing_date> <amount>1449.8770822999832</amount> <currency>EUR</currency> </order> <order> <order_id>8</order_id> <pricing_date>2022/03/12 22:57:18.577308</pricing_date> <amount>-1708.4810066747305</amount> <currency>EUR</currency> </order> <order> <order_id>9</order_id> <pricing_date>2022/03/12 22:57:18.577317</pricing_date> <amount>5091.879830019116</amount> <currency>EUR</currency> </order> </orders>
<?xml version="1.0" ?> <orders> <order> <order_id>0</order_id> <pricing_date>2022/03/12 22:57:18.577233</pricing_date> <amount>8682.064027577868</amount> <currency>EUR</currency> </order> <order> <order_id>1</order_id> <pricing_date>2022/03/12 22:57:18.577271</pricing_date> <amount>1178.6677560764638</amount> <currency>EUR</currency> </order> <order> <order_id>2</order_id> <pricing_date>2022/03/12 22:57:18.577280</pricing_date> <amount>877.1820266699797</amount> <currency>EUR</currency> </order> <order> <order_id>3</order_id> <pricing_date>2022/03/12 22:57:18.577285</pricing_date> <amount>3557.339177963937</amount> <currency>EUR</currency> </order> <order> <order_id>4</order_id> <pricing_date>2022/03/12 22:57:18.577290</pricing_date> <amount>-8528.180149274358</amount> <currency>EUR</currency> </order> <order> <order_id>5</order_id> <pricing_date>2022/03/12 22:57:18.577294</pricing_date> <amount>-4527.9443459321665</amount> <currency>EUR</currency> </order> <order> <order_id>6</order_id> <pricing_date>2022/03/12 22:57:18.577299</pricing_date> <amount>-6062.7853847754905</amount> <currency>EUR</currency> </order> <order> <order_id>7</order_id> <pricing_date>2022/03/12 22:57:18.577303</pricing_date> <amount>1449.8770822999832</amount> <currency>EUR</currency> </order> <order> <order_id>8</order_id> <pricing_date>2022/03/12 22:57:18.577308</pricing_date> <amount>-1708.4810066747305</amount> <currency>EUR</currency> </order> <order> <order_id>9</order_id> <pricing_date>2022/03/12 22:57:18.577317</pricing_date> <amount>5091.879830019116</amount> <currency>EUR</currency> </order> </orders>
Dans la base de Sqlite3, nous pouvons saisir toutes les données dans la table ORDERS :
Les résultats gérés chez OODBMS peuvent être décodés ainsi :
De cette façon, on réussit à réaliser les deux composants principaux dans le patron de conception Fabrique en Python 3, qui surmonte la violation du principe de responsabilité unique pour la persistance des ordres chez l’utilisateur montrée au début de l’article. Désormais on pourrait enrichir à l’aise autant de types d’objet que l’on veut aux contextes plus compliqués, tout en ne rajoutant les conditions de justification et les classes dérivées que dans les deux composants respectivement, lorsque les anciennes fonctionnalités opérationnelles ne risquent pas d’être impactées dans les applications.
Conclusion
Dans cet article, on met en évidence la nécessité du patron de conception Fabrique contre l’issue de persistance dans notre contexte en question. Son diagramme ULM comprend deux principaux composants qui respectent le principe de responsabilité unique. Ce patron de conception créateur est implémenté et testé en Python 3 pour une application rudimentaire, lorsque l’enrichissement des nouvelles créations pourrait passer à l’échelle dans le code en sécurité.
Références
[1] https://www.invivoo.com/blog/lart-clean-code-environnement-java/
[2] https://www.invivoo.com/blog/design-patterns-patrons-conception/
[3] https://www.invivoo.com/blog/singleton-design-patterns-part1/
[4] https://www.invivoo.com/blog/singletons-design-patterns-partie-2/
[5] https://www.tutorialspoint.com/python/python_xml_processing.htm
[6] https://docs.python.org/3/library/sqlite3.html
[7] https://zodb.org/en/latest/
[8] https://docs.python.org/fr/3/library/random.html






