抽象课的适当层次结构

发布于 2025-02-06 22:48:16 字数 2881 浏览 2 评论 0原文

我有下面定义的下一个代码。 该示例有2个架构问题:

  1. 具体类POST有警告,因为没有实现(这是不可能的)某些抽象方法
  2. 摘要类是混凝土类的继承者。

我知道一些解决方案,但它们都不是完美的:

  1. 完全删除抽象课程。
  2. 删除中间logicapost)类。
  3. 为最终课程做出多个继承(可能没有帮助,但显然会减少损害)
  4. 将此类分成大量的小班级。

为什么它们都不完美:

  1. 抽象的
  2. 需要 从6到〜(12-18,

常见的层次结构是:

基本抽象类Abstracta带有每个最终子类 - >

concrete class logica的继承者) Abstracta class)部分实现具有常见逻辑的方法,并且在

另一个Abstract类 中,>仅针对此类的特定抽象方法 - >

)的特定方法仅用于此类的特定抽象方法

finalabtractb (logica > FinallogicafinalAbsTracta的继承者

简而言之: 摘要 - > logica-> (finalAbstracta - > Finallogica + finalAbstractb - > Finallogicb)


class AbstractPost(ABC):
    """Abstract Intermediate class with common methods for all inheritors"""
    @abstractmethod  # Method that has every final inheritor but not an intermediate
    def read(self):
        raise NotImplementedError

    @classmethod  # A common method for all subclasses
    def post_from_callback(cls, current_user: classes.users.User, callback: CallbackQuery) -> Post | None:
        raise NotImplementedError


class Post(AbstractPost):  # Warning on this line that not all abstract methods defined.
    """
    Implementation of intermediate class with common methods for all inheritors
    This class not supposing to has an instances, only type hint
    "read" function can't be implemented here because `post` instanse not defined in DB doesn't has. 
    "read" function has a common signature but should be impleneted in concrete class because has different sql queries.
    """
    @classmethod
    def post_from_callback(cls, current_user: classes.users.User, callback: CallbackQuery) -> Post | None:
        post = cls.read(user=current_user, post_id=abs(int(callback.data.split()[-1])))
        if post is not None and post.validate(data=int(callback.data.split()[-2])):
            return post


class AbstractPublicPost(Post):
    """Abstract class with some methods which has only this class"""
    @abstractmethod
    def public_post_method_only(self):
        raise NotImplementedError


class PublicPost(AbstractPublicPost):
    """Implementation of abstract class with some  methods which has only this class"""
    def public_post_method_only(self):
        ...


class AbstractPersonalPost(Post):
    """Abstract class with some methods which has only this class"""
    @abstractmethod
    def personal_post_method_only(self):
        raise NotImplementedError


class PersonalPost(AbstractPersonalPost):
    """Implementation of abstract class with some  methods which has only this class"""
    def personal_post_method_only(self):
        ...

I have the next code defined below.
This sample has a 2 architcet problems:

  1. Concrete class Post has a warning because doesn't implement (it's impossible) some abstract methods
  2. Abstract class are inheritor of concrete class.

I know a few solutions but they all are not perfect:

  1. Remove abstract classes at all.
  2. Remove intermediate LogicA (Post) class at all.
  3. Make multiple inheritance for final classes (may not help but apparently will reduce damage)
  4. Split this classes in a huge amount of small classes.

Why they all are not perfect:

  1. I need abstract classes because this methods as alias use another classes (dependency injection)
  2. Will force me to repeat a code in every final concrete class, violates DRY
  3. Multiple inheritance are evil
  4. Will easily increase number of classes X2, from 6 to ~(12-18

The common hierarchy is:

Base abstract class AbstractA with methods which has every FINAL subclass ->

Concrete class LogicA (inheritor of AbstractA class) that partially implements methods which has a common logic and exactly the same code inside ->

Another abstract class FinalAbstractA (inheritor of LogicA) with some specific abstract methods only for this class ->

Another abstract class FinalAbstractB (inheritor of LogicA) with some specific abstract methods only for this class ->

Final concrete class FinalLogicA (inheritor of FinalAbstractA).

Final concrete class FinalLogicB (inheritor of FinalAbstractB).

In short:
AbstractA -> LogicA -> (FinalAbstractA -> FinalLogicA + FinalAbstractB -> FinalLogicB)


class AbstractPost(ABC):
    """Abstract Intermediate class with common methods for all inheritors"""
    @abstractmethod  # Method that has every final inheritor but not an intermediate
    def read(self):
        raise NotImplementedError

    @classmethod  # A common method for all subclasses
    def post_from_callback(cls, current_user: classes.users.User, callback: CallbackQuery) -> Post | None:
        raise NotImplementedError


class Post(AbstractPost):  # Warning on this line that not all abstract methods defined.
    """
    Implementation of intermediate class with common methods for all inheritors
    This class not supposing to has an instances, only type hint
    "read" function can't be implemented here because `post` instanse not defined in DB doesn't has. 
    "read" function has a common signature but should be impleneted in concrete class because has different sql queries.
    """
    @classmethod
    def post_from_callback(cls, current_user: classes.users.User, callback: CallbackQuery) -> Post | None:
        post = cls.read(user=current_user, post_id=abs(int(callback.data.split()[-1])))
        if post is not None and post.validate(data=int(callback.data.split()[-2])):
            return post


class AbstractPublicPost(Post):
    """Abstract class with some methods which has only this class"""
    @abstractmethod
    def public_post_method_only(self):
        raise NotImplementedError


class PublicPost(AbstractPublicPost):
    """Implementation of abstract class with some  methods which has only this class"""
    def public_post_method_only(self):
        ...


class AbstractPersonalPost(Post):
    """Abstract class with some methods which has only this class"""
    @abstractmethod
    def personal_post_method_only(self):
        raise NotImplementedError


class PersonalPost(AbstractPersonalPost):
    """Implementation of abstract class with some  methods which has only this class"""
    def personal_post_method_only(self):
        ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不是你的备胎 2025-02-13 22:48:16

看来您已经使这复杂化了。仅仅因为类是基类,并不意味着您无法实现一种方法,然后由其他类继承。

您可以将post_from_callback发布 abractivepost没有任何问题,并且完全消除了post

class AbstractPost(ABC):
    """Abstract Intermediate class with common methods for all inheritors"""
    @abstractmethod
    def read(self):
        pass

    @classmethod
    def post_from_callback(cls, current_user: classes.users.User, callback: CallbackQuery):
        post = cls().read(user=current_user, post_id=abs(int(callback.data.split()[-1])))
        if post is not None and post.validate(data=int(callback.data.split()[-2])):
            return post


class AbstractPublicPost(AbstractPost):
    """Abstract subclass for public posts"""
    @abstractmethod
    def public_post_method_only(self):
        raise NotImplementedError


class PublicPost(AbstractPublicPost):
    def public_post_method_only(self):
        ...


class AbstractPersonalPost(AbstractPost):
    """Abstract subclass for personal posts."""
    @abstractmethod
    def personal_post_method_only(self):
        pass


class PersonalPost(AbstractPersonalPost):
    def personal_post_method_only(self):
        ...

It looks like you are over complicating this. Just because a class is a base class, does not mean you cannot implement a method, which is then inherited by other classes.

You could move post_from_callback from Post to AbstractPost with no issues and eliminate Post altogether.

class AbstractPost(ABC):
    """Abstract Intermediate class with common methods for all inheritors"""
    @abstractmethod
    def read(self):
        pass

    @classmethod
    def post_from_callback(cls, current_user: classes.users.User, callback: CallbackQuery):
        post = cls().read(user=current_user, post_id=abs(int(callback.data.split()[-1])))
        if post is not None and post.validate(data=int(callback.data.split()[-2])):
            return post


class AbstractPublicPost(AbstractPost):
    """Abstract subclass for public posts"""
    @abstractmethod
    def public_post_method_only(self):
        raise NotImplementedError


class PublicPost(AbstractPublicPost):
    def public_post_method_only(self):
        ...


class AbstractPersonalPost(AbstractPost):
    """Abstract subclass for personal posts."""
    @abstractmethod
    def personal_post_method_only(self):
        pass


class PersonalPost(AbstractPersonalPost):
    def personal_post_method_only(self):
        ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文