É má prática criar uma função que retorna uma classe?
Contexto completo
Essa é a minha primeira vez usando Flask para criar uma RESTful API. Estou usando Flask, Flask-RESTful, Marshmallow e SQLAlchemy. Decidi usar orientação a objetos no projeto por me sentir mais confortável com essa forma de organização em projetos grandes.No banco de dados, tenho 7 tabelas diferentes. Como o MVC é o único padrão arquitetural com o qual tenho familiaridade, tentei seguir algo que mais ou menos se encaixe nisso (percebi ao longo do desenvolvimento que não seria possível fazer tudo em MVC, então foram feitas algumas adaptações). Sendo assim:
- Tenho 7 classes
Model
para representar os dados do banco no código; - Para cada classe
Model
, há uma classeSchema
, que serve para serializar/desserializar os dados que a API recebe/envia. Essa classe é um padrão do Marshmallow pelo que entendi; - Para cada
Model
, há também uma classeService
, que, no momento, interage com o SQLAlchemy e processa regras de negócio; - Para cada
Service
, há umResource
, que lida com as requisições HTTP e chama os métodos daService
.
Isso significa que, para cada tabela, tenho 4 classes. O problema é que, estruturalmente, as classes Schema
e Resource
são sempre idênticas, apenas adaptando qual outra classe elas vão chamar. Exemplo: todas as classes Resource
possuem o método get
. Porém, a UserResource
chama a UserService
nesse método, enquanto a TeamResource
chama a TeamService
, e por aí vai.
As classes Service
possuem regras distintas, e as Model
têm campos diferentes, então não tem pra onde correr. Mas nos outros casos, me parece repetição de código desnecessária, o que traz todas aquelas questões de manutenibilidade, redundância e por aí vai.
TL;DR: Em uma API, tenho várias classes idênticas para cada tabela que ela pretende acessar. Os grupos mais redundantes de classes são Resource
e Schema
.
No caso da Resource
, usei herança e a situação ficou menos pior. Por outro lado, no caso da Schema
, estou pensando em fazer uma função que retorne uma classe Schema
de acordo com o Model
passado como parâmetro. Seria má prática, considerando que elas possuem estrutura idêntica, com exceção do model?
Segue a estrutura das Schema:
class UserSchema(SQLAlchemyAutoSchema):
class Meta:
model = UserModel
@post_load
def to_model(self, data: dict, **kwargs) -> UserModel:
return UserModel(**data)
O que pretendo fazer é:
def create_schema(model) -> type:
class ModelSchema(SQLAlchemyAutoSchema):
class Meta:
model = model
@post_load
def to_model(self, data: dict, **kwargs) -> model:
return model(**data)
return ModelSchema
Obs.: quanto ao padrão arquitetural, estou ciente que por enquanto parece uma grande mistura. Peço que foquem apenas na pergunta do título.