【发布时间】:2021-11-14 03:56:53
【问题描述】:
我一直试图弄清楚何时何地在 Python 中使用不同的模式。我偶然发现了这个文件:https://python-patterns.guide/gang-of-four/abstract-factory/
现在这让我想知道如何按照他在我的代码中所说的去做。这是我的实现是一个抽象工厂。不确定是否正确。
from abc import abstractmethod, ABC
from sqlalchemy.orm import Session
from managers.database_manager import DatabaseManager
from managers.log_manager import LogManager
from managers.sqlalchemy_manager import get_db
from models.bal.post import Post
from models.dal.models import Post as ORMPost
class PostsManager(ABC):
def __init__(self):
pass
@abstractmethod
def get_posts(self):
pass
@abstractmethod
def get_post(self, post_id):
pass
@abstractmethod
def create_post(self, post: Post):
pass
@abstractmethod
def delete_post(self, post_id):
pass
@abstractmethod
def update_post(self, post_id, post: Post):
pass
class PostsManagerFactory:
@staticmethod
def get_posts_manager(use_orm=True) -> PostsManager:
if use_orm:
return PostsManagerWithORM()
else:
return PostsManagerWithoutORM()
class PostsManagerWithORM(PostsManager):
def get_posts(self):
db: Session = get_db()
posts = db.query(ORMPost).all()
return posts
def get_post(self, post_id):
pass
def create_post(self, post: Post):
pass
def delete_post(self, post_id):
pass
def update_post(self, post_id, post: Post):
pass
class PostsManagerWithoutORM(PostsManager):
def __init__(self):
super().__init__()
self.db_manager = DatabaseManager()
def get_posts(self):
posts = self.db_manager.execute_query("select * from posts")
return posts
def get_post(self, post_id):
post = self.db_manager.execute_query("SELECT * FROM posts WHERE id='%s'", (post_id,), single_record_flag=True)
return post
def create_post(self, post: Post):
post = self.db_manager.execute_query("INSERT INTO posts (title, content) VALUES (%s, %s) RETURNING *",
(post.title, post.content), single_record_flag=True)
return post
def delete_post(self, post_id):
post = self.db_manager.execute_query("DELETE FROM posts WHERE id = %s RETURNING *", (post_id,),
single_record_flag=True)
return post
def update_post(self, post_id, post: Post):
post = self.db_manager.execute_query(
"UPDATE posts SET title = %s, content = %s, published = %s WHERE id= %s RETURNING *",
(post.title, post.content, post.published, post_id),
single_record_flag=True)
return post
我是这样调用这些方法的:
posts_manager = PostsManagerFactory.get_posts_manager()
posts = posts_manager.get_posts()
我的第一个问题,使用抽象工厂模式是否正确?如果不是,请告诉我,我可能会问一个新问题。无论如何,如果是,为什么该文档说使用可调用对象比使用抽象工厂模式更好,在这种情况下我该怎么做?
【问题讨论】:
-
据我了解,您这里并没有使用抽象工厂模式,它只是一个抽象类/接口。工厂构建并返回一个对象。在您的示例中,该类的方法不构建任何东西,它们与某些东西交互,发布、检索、更新和删除帖子。
-
你是对的,对不起。现在添加了工厂类。现在是不是用抽象工厂模式了?
-
是的,您现在使用的是工厂模式,但不是抽象工厂模式,因为您的
PostsFactory类不是从抽象类派生的。无论如何,您可以通过提取get_posts_factory()方法并使其成为函数来使用可调用对象而不是类。 -
这就是说,您的方法名称
get_posts_factory()可能会或可能不会成为函数,具体取决于您选择的内容是不正确的。该工厂不返回PostFactory,而是返回PostManager子类之一的实例。然后应将其重命名为get_posts_manager()。如果您决定保留类PostsFactory,那么您也应该将其重命名为PostsManagerFactory,但在我看来,没有必要使用类,因为它只包含一个静态方法。 -
好的,谢谢,我现在已经进行了这些命名更改。我现在明白这不是使用抽象工厂模式。如果你可以使用抽象工厂模式重写这段代码,你会怎么做?另外我不明白你在哪里说我可以通过提取方法并使其成为函数来使用可调用对象。如果你可以同时做这两个并写一个答案,我会接受它作为答案。非常感谢。
标签: python design-patterns abstract-factory