python - 如何在 Python 中使用可调用对象而不是抽象工厂模式?
问题描述
我一直在试图弄清楚何时何地在 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()
我的第一个问题,它是使用抽象工厂模式的正确方法吗?如果不是,请告诉我,我可能会问一个新问题。无论如何,如果是这样,为什么该文档说使用可调用对象比使用抽象工厂模式更好,在这种情况下我该怎么做?
解决方案
关注你最后的评论。
对于这个用例,我不会使用抽象工厂模式。请问你为什么要使用它?
PostsManagerFactory
当我建议通过提取到函数来删除类get_posts_manager
时,我的意思是替换这个代码片段
class PostsManagerFactory:
@staticmethod
def get_posts_manager(use_orm=True) -> PostsManager:
if use_orm:
return PostsManagerWithORM()
else:
return PostsManagerWithoutORM()
有了这个
def get_posts_manager(use_orm=True) -> PostsManager:
if use_orm:
return PostsManagerWithORM()
else:
return PostsManagerWithoutORM()
你可能想用这种方式缩短
def get_posts_manager(use_orm=True) -> PostsManager:
return PostsManagerWithORM() if use_orm else PostsManagerWithoutORM()
然后,您只需调用函数即可在代码中使用它
posts_manager = get_posts_manager() # <----
posts = posts_manager.get_posts()
推荐阅读
- r - 如何在 r 的数据框列中替换非浮点类原子?
- scala - 集群上的 Spark:读取大量小型 avro 文件需要很长时间才能列出
- c++ - glBuffer 使用一种数据风格,但不能使用另一种风格的数据,为什么?
- c# - 设置为默认页面/主页后直接访问操作
- angular - 如何将插值传递给子组件?
- python - 如何打印 txt 文件中每一行的第一个单词?
- migration - 如何在 ecto 迁移中执行 SQL SELECT 查询
- python - 尝试在第一个 python 代码中调试错误
- ruby - 从 fastlane 快速文件返回值
- javascript - 无法访问该数组的内容在 Console.Log 中可见的数组