composition and aggregation in python

前端 未结 3 1946
南旧
南旧 2020-12-23 17:52

I want to know how to implement composition and aggregation in UML terms in python.

If I understood:

  1. Aggregation:

相关标签:
3条回答
  • 2020-12-23 18:36

    Composition and aggregation are specialised form of Association. Whereas Association is a relationship between two classes without any rules.

    Composition

    In composition, one of the classes is composed of one or more instance of other classes. In other words, one class is container and other class is content and if you delete the container object then all of its contents objects are also deleted.

    Now let's see an example of composition in Python 3.5. Class Employee is container and class Salary is content.

    class Salary:
        def __init__(self,pay):
            self.pay=pay
    
        def get_total(self):
           return (self.pay*12)
    
    class Employee:
        def __init__(self,pay,bonus):
            self.pay=pay
            self.bonus=bonus
            self.obj_salary=Salary(self.pay)
    
        def annual_salary(self):
            return "Total: "  +  str(self.obj_salary.get_total()+self.bonus)
    
    
    obj_emp=Employee(100,10)
    print (obj_emp.annual_salary())
    

    Aggregation

    Aggregation is a weak form of composition. If you delete the container object contents objects can live without container object.

    Now let's see an example of aggregation in Python 3.5. Again Class Employee is container and class Salary is content.

    class Salary:
        def __init__(self,pay):
            self.pay=pay
    
        def get_total(self):
           return (self.pay*12)
    
    class Employee:
        def __init__(self,pay,bonus):
            self.pay=pay
            self.bonus=bonus
    
        def annual_salary(self):
            return "Total: "  +  str(self.pay.get_total()+self.bonus)
    
    
    obj_sal=Salary(100)
    obj_emp=Employee(obj_sal,10)
    print (obj_emp.annual_salary())
    
    0 讨论(0)
  • 2020-12-23 18:50

    If I understand correctly, aggregation vs composition is about the responsibilities of an object to its members (e.g. if you delete an instance, do you also delete its members?).

    Mainly, it will depend a lot on the implementation. For example, to create a class A which receives an instance of class B (aggregation), you could write the following:

    class B(object): pass
    
    class A(object):
        def __init__(self, b):
            self.b = b
    
    b = B()
    a = A(b)
    

    But as a point of caution, there is nothing built-in to Python that will prevent you from passing in something else, for example:

    a = A("string") # still valid
    

    If you would like to create the instance of B inside the constructor of A (composition), you could write the following:

    class A(object):
        def __init__(self):
            self.b = B()
    

    Or, you could inject the class into the constructor, and then create an instance, like so:

    class A(object):
        def __init__(self, B):
            self.b = B()
    

    As an aside, in at least your first example and possibly the second, you are setting B to the class definition of B, not to an instance of it:

    class A(object):
        def __init__(self, B):
            self.B = B
    
    >>> a = A()
    >>> a.B # class definition
    <class __main__.B at 0x028586C0>
    >>> a.B() # which you can make instances of
    <__main__.B instance at 0x02860990>
    

    So, you end up with an instance of A pointing to the class definition of B, which I'm fairly sure is not what you're after. Although, that is generally much harder to do in other languages, so I understand if that was one of the points of confusion.

    0 讨论(0)
  • 2020-12-23 18:55
    # Aggregation is NOT exclusive
    class BaseChapter:
        '''
        We can use this BaseChapter in any book, like in OpenBook.
        '''
    
        def __init__(self, name):
            self.name = name
            self.subject = None
            self.content = None
            return
    
    class OpenBook:
    
        def __init__(self, isbn):
            self.isbn = isbn
            self.chapters = list()
    
        def add_chapter(self, obj):
    
            # This constrain dont have correlation with composition/aggregation
            if isinstance(obj, BaseChapter):
                self.chapters.append(obj)
            else:
                raise TypeError('ChapterError')
    
    # .. but Composition is Exclusive
    # Example:
    class MyBook:
    
        class MyChapter:
            '''
            This MyChapter can be used only by MyBook
            '''
            def __init__(self, name, subject):
                self.name = name
                self.subject = subject
                self.title = None
                self.content = None
                self.techincal_refs = list()
                return
    
        def __init__(self, isbn):
            self.isbn = isbn
            self.chapters = list()
    
        def add_chapter(self, obj):
            # This constrain dont have correlation with composition/aggregation
            # what is important here is MyChapter can be used only by MyBook
            # a outside object cant create a instance of MyChapter
            if isinstance(obj, self.MyChapter):
                self.chapters.append(obj)
            else:
                raise TypeError('ChapterError')
    

    .. and yes we can do better like

    class MyBook:
    
        class MyChapter(BaseChapter):
            '''
            This MyChapter can be used only by MyBook,
            but now is based in BaseChapter.
            But you knhow, python dont create problems if you still want
            create a instance of MyChapter in other 'Books'.
    
            But when you see this code you will think, This class is exclusive
            to MyBook.
            '''
            def __init__(self, name):
                super().__init__(name)
                self.subject = None
                self.title = None
                self.content = None
                self.techincal_refs = list()
                return
    
        def __init__(self, nib):
            self.nib = nib
            self.chapters = list()
    
        def add_chapter(self, obj):
            # This constrain dont have correlation with composition/agregation
            # what is important here is MyChapter can be used only by MyBook
            if isinstance(obj, self.MyChapter):
                self.chapters.append(obj)
            else:
                raise TypeError('ChapterError')
    
    0 讨论(0)
提交回复
热议问题