I have some theoretical questions about COM aggregation:
Is it possible to delete the outer component but retain the Inner Component? (I suppose not, but I am not 100% sure.)
Is it possible that an Inner Component is aggregated by two different Outer Components (directly)?
If the answer to the other two question is no, then is it correct that 'COM aggregation' is rather composition in UML terms than aggregation?
When you create an aggregated COM object, you are providing an outer interface at instantiation time, and it cannot be changed later. This is eventually a "no" to the first two questions.
To answer 1, no. The inner object increments the outer object's reference count when its IUnknown::QueryInterface runs successfully for a non-IUnknown IID. Essentially, if the inner object is alive, so is the outer object, even if no external entity holds a reference to the outer object. This must be so, because any QueryInterface, AddRef and Release performed on the inner object's non-IUnknown interface pointers must delegate to the outer object.
To answer 2, no. The inner object has no way to know from which object it is being invoked from, and even if there was, it would make identity break. For instance, in COM the only reliable object identity check is if two IUnknown interface pointers are the same or not, but everyone assumes that if any two, possibly non-IUnknown, interface pointers are the same, they're from the same object (there's no guarantee the other way around, two non-IUnknown interface pointers, even of the same type, might be different and refer to the same object).
To answer 3, COM aggregation is a special case of composition, where instead of implementing the intercepted interfaces with redirecting or wrapping methods, we return direct interface pointers from the inner object. This optimization is more relevant when you have many composed objects. It should not be the first approach to composition, as you lose control and some restrictions apply, e.g. you can't wrap objects provided to or returned by the inner objects, no pre- and post-processing, the outer object and the inner object should not overlap in functionality (e.g. if the outer object has a parent object according to some definition of parent, the inner object should not have a different parent under the same definition, or it should be completely ignorant of such a parent object; same for child objects), etc.
Related
I tried to do a lot of research but I'm more of a db guy - so even the explanation in the MSDN doesn't make any sense to me. Can anyone please explain, and provide some examples on what Include() statement does in the term of SQL query?
Let's say for instance you want to get a list of all your customers:
var customers = context.Customers.ToList();
And let's assume that each Customer object has a reference to its set of Orders, and that each Order has references to LineItems which may also reference a Product.
As you can see, selecting a top-level object with many related entities could result in a query that needs to pull in data from many sources. As a performance measure, Include() allows you to indicate which related entities should be read from the database as part of the same query.
Using the same example, this might bring in all of the related order headers, but none of the other records:
var customersWithOrderDetail = context.Customers.Include("Orders").ToList();
As a final point since you asked for SQL, the first statement without Include() could generate a simple statement:
SELECT * FROM Customers;
The final statement which calls Include("Orders") may look like this:
SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;
I just wanted to add that "Include" is part of eager loading. It is described in Entity Framework 6 tutorial by Microsoft. Here is the link:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application
Excerpt from the linked page:
Here are several ways that the Entity Framework can load related data into the navigation properties of an entity:
Lazy loading. When the entity is first read, related data isn't retrieved. However, the first time you attempt to access a navigation property, the data required for that navigation property is automatically retrieved. This results in multiple queries sent to the database — one for the entity itself and one each time that related data for the entity must be retrieved. The DbContext class enables lazy loading by default.
Eager loading. When the entity is read, related data is retrieved along with it. This typically results in a single join query that retrieves all of the data that's needed. You specify eager loading by using the Include method.
Explicit loading. This is similar to lazy loading, except that you explicitly retrieve the related data in code; it doesn't happen automatically when you access a navigation property. You load related data manually by getting the object state manager entry for an entity and calling the Collection.Load method for collections or the Reference.Load method for properties that hold a single entity. (In the following example, if you wanted to load the Administrator navigation property, you'd replace Collection(x => x.Courses) with Reference(x => x.Administrator).) Typically you'd use explicit loading only when you've turned lazy loading off.
Because they don't immediately retrieve the property values, lazy loading and explicit loading are also both known as deferred loading.
Think of it as enforcing Eager-Loading in a scenario where your sub-items would otherwise be lazy-loading.
The Query EF is sending to the database will yield a larger result at first, but on access no follow-up queries will be made when accessing the included items.
On the other hand, without it, EF would execute separte queries later, when you first access the sub-items.
include() method just to include the related entities.
but what happened on sql is based on the relationship between those entities which you are going to include what the data you going to fetch.
your LINQ query decides what type of joins have to use, there could be left outer joins there could be inner join there could be right joins etc...
#Corey Adler
Remember that you should use .Include() and .ThenInclude() only when returning the object (NOT THE QUERYABLE) with the "other table property".
As a result, it should only be used when returning APIs' objects, not in your intra-application.
I have a class A and it has data members of class B and class C which are composition relationships. As I am going to draw a composition relationship line from B to A and C to A, does this mean I cannot also include the data members within the class A "box" because the relationship is inferred from the composition relationship lines?
I ask because the data member variable names seem a good way to help understand the context and this cannot be represented if you omit the data members from the class A "box"??
I am not sure if there is a cast-iron rule in UML or whether I am free to choose. This is not for auto-generation of code- just human reading.
At least, in UML you can show a name of each property like a figure below.
According to UML specification, both representations of data members, visually depicted association/composition between two classes or in-class data member display) are equivalent. Here is an example (a little bit modified your case, to make it clearer):
Note that association end also show the scope and collection type (besides the name of course). col_B is defined ase private {ordered} collection (like array).
So, getting back to the formal side of UML spec... a, x, aa, col_b and m_c are all co called A's structural features (or properties). They can all be visually depicted using relationsips between the classes or inside the class itself. You can even show "int" data type as a class and link it using a composition!
Which way you will use is up to you, kind of matter of personal taste.
I always apply a simple rule - basic data types (int, boolean, date, string, etc) and their arrays are showed in the class itself, while the class and enumeration based properties are depicted by a relationship (example on the top).
As simple data types are clear and well known and does not have their own properties, I find it clear enough to show them in-class (diagram is simpler and smaller).
The complex data types (classes and enumerations) however typically have their own properties (data members, associations), even inheritances, and I want to make the class structure stand out on my diagarm.
You can use your own logic though.
In a class diagram you cannot model the same composition both showing the association and the attribute, because in the UML semantic that would mean your class has two composition :-)
If in your diagram you already have classes B and C, I suggest you opt for the association ("relationship lines") solution.
To better understand the context, you can put the roles on the association: this is equivalent to the name of your attributes.
I understand the difference between aggregation and composition but I am struggling a bit with association. My current understanding is that an association exists between classes when ‘they use each other’, for example, one object is passed to the other during a method call. See also:
http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit
Both objects exist independently and, in contrast to aggregation, no object is a container class of the other. Does this mean that both objects MUST have a copy of the other(s) (e.g. 1:m relationship) or how else is the association ‘stored’. Any feedback would be very much appreciated.
From the UML Superstructure 2.4.1:
An association declares that there can be links between instances of the associated types. A link is a tuple with one value for each end of the association, where each value is an instance of the type of the end. (UML Superstructure, Page 37)
Nothing more, nothing less. and very vague. Because of this, it is also very hard to understand. What I defined (In a course I teach) is a hierarchy of links from dependency to composition where:
Dependency from A to B means that A uses B but indirectly (say by receiving instances of it and forwarding them to other objects).
Association from A to B means that A uses B directly, (for example by calling methods)
Aggregation from A to B means that B is part of A (semantically) but B can be shared and if A is deleted, B is not deleted. Note that this says nothing about how the "is part" is implemented.
Composition from A to B is like Aggregation, where B cannot be shared and if A is deleted, all of its aggregates (Bs) are deleted also.
Aggregation is an Association relationship where the Association can be considered the containing class 'Owning' the contained class, and the lifetime of that relationship is not defined.
Association is an 'Has-A' relationship.
Example:-
public class Person
{
private final Name name;
private Address currentAddress;
//...
}
In this case, the Person Has-A name and Has-A Address, so there is an Association between Person and Name, and Person and Address.
An association describes a relationship between instances of one or more classes. In the words of the UML Reference Manual, "Associations are the glue that holds together a system."
Aggregation is a form of association in which there is a "whole-part" relationship. You may say that if a class Airplane has a class Engine then this forms a "whole-part" relationship.
Aggregation
Let's set the terms. The Aggregation is a metaterm in the UML standard, and means BOTH composition and shared aggregation, simply named shared. Too often it is named incorrectly "aggregation". It is BAD, for composition is an aggregation, too. As I understand, you meant you understand "shared aggregation and composition".
From UML standard:
Precise semantics of shared aggregation varies by application area and
modeler.
I haven't found a word about that aggregation supposed multiplicity, for example.
Association.
A definition from UML 3.4.1 standard:
An association describes a set of tuples whose values refer to typed
instances. An instance of an association is called a link. A link is a
tuple with one value for each end of the association, where each value
is an instance of the type of the end.
Aggregated relationship is a subclass of Association.
Association is based on relationship. IT is the glue for models.
But your feelings didn't lie - as the shared aggregation is not strictly defined, there is also NO any strictly defined boundary between Association and Aggregated association. Authors of tools and modellers have to set it themselves.
Association
It represents a relationship between two or more objects where all objects have their own lifecycle and there is no owner. The name of an association specifies the nature of relationship between objects. This is represented by a solid line.
Let’s take an example of relationship between Teacher and Student. Multiple students can associate with a single teacher and a single student can associate with multiple teachers. But there is no ownership between the objects and both have their own lifecycle. Both can be created and deleted independently.
Aggregation
It is a specialized form of Association where all object have their own lifecycle but there is ownership. This represents “whole-part or a-part-of” relationship. This is represented by a hollow diamond followed by a line.
Let’s take an example of relationship between Department and Teacher. A Teacher may belongs to multiple departments. Hence Teacher is a part of multiple departments. But if we delete a Department, Teacher Object will not destroy.
It depends on the context.
Association: A man drives a car, focus on the caller and callee relationship.
Aggregation: A man has a car, focus on the owner and member relationship.
Composition: A man has a mouth, focus on the owner & member but the owner consists of members, it means that they shared the same life cycle.
Feels like I'm speaking Chinglish.
Association
Association is a relationship where all objects have their own life-cycle and there is no owner. Let’s take the example of Teacher and Student. Multiple students can associate with a single teacher and a single student can associate with multiple teachers but there is no ownership between the objects and both have their own life-cycle. Both can create and delete independently.
Aggregation
the objects in Aggregation have their own life-cycle but there is ownership. Child object can not belong to another parent object. Let’s take an example of Department and teacher. A single teacher can not belongs to multiple departments, but if we delete the department teacher object will not destroy. We can think about the “has-a” relationship.
Composition
It is a strong type of Aggregation. Child object does not have their life-cycle and if parent object deletes all child object will also be deleted. Let’s take again an example of the relationship between House and rooms. House can contain multiple rooms there is no independent life of room and any room can not belongs to two different houses if we delete the house room will automatically delete.
An association between object types classifies relationships between objects of those types. For instance, the association Committee-has-ClubMember-as-chair, which is visualized as a connection line in the class diagram shown below, may classify the relationships FinanceCommittee-has-PeterMiller-as-chair, RecruitmentCommittee-has-SusanSmith-as-chair and AdvisoryCommittee-has-SarahAnderson-as-chair, where the objects PeterMiller, SusanSmith and SarahAnderson are of type ClubMember, and the objects FinanceCommittee, RecruitmentCommittee and AdvisoryCommittee are of type Committee.
See also my alternative CodeProject article.
I have a question about the modelling of classes and the underlying database design.
Simply put, the situation is as follows: at the moment we have Positions and Accounts objects and tables and the relationship between them is that a Position 'has an' Account (an Account can have multiple Positions). This is simple aggregation and is handled in the DB by the Position table holding an Account ID as a foreign key.
We now need to extend this 'downwards' with Trades and Portfolios. One or more Trades make up a Position (but a Trade is not a Position in itself) and one or more Portfolios make up an Account (but a Portfolio is not an Account in itself). Trades are associated with Portfolios just like Positions are associated with Accounts ('has a'). Note that it is still possible to have a Position without Trades and an Account without Portfolios (i.e. it is not mandatory to have all the existing objects broken down in subcomponents).
My first idea was to go simply for the following (the first two classes already exist):
class Account;
class Position {
Account account;
}
class Portfolio {
Account account;
}
class Trade {
Position position;
Portfolio portfolio;
}
I think the (potential) problem is clear: starting from Trade, you might end up in different Accounts depending if you take the Position route or the Portfolio route. Of course this is never supposed to happen and the code that creates and stores the objects should never be able create such an inconsistency. I wonder though whether the fact that it is theoretically possible to have an inconsistent database implies a flawed design?
Looking forward to your feedback.
The design is not flawed just because there are two ways to get from class A to class D, one way over B and one over C. Such "squares" will appear often in OOP class models, sometimes not so obvious, especially if more classes lie in the paths. But as Dan mentioned, always the business semantics determine if such a square must commute or not (in the mathematic sense).
Personally I draw a = sign inside such a square in the UML diagram to indicate that it must commute. Also I note the precise formula in an UML comment, in my example it would be
For every object a of class A: a.B.D = a.C.D
If such a predicate holds, then you have basically two options:
Trust all programmers to not break the rule in any code, since it is very well documented
Implement some error handling (like Dan and algirdas mentioned) or, if you don't want to have such code in your model, create a Checker controller, which checks all conditions in a given model instance.
I would like to know a best way to design a deletion of an object, with triggers deletion of many dependent objects.
Here is an example. There is an Employer class. When an employer is deleted, all its jobs, invoices are deleted. When a job is deleted its category selection is deleted as well. And so on. So as you can see deletion of Employer triggers deletion on many more objects. The problem is that I have to pass many arguments required for deletion of dependent objects to the delete method in the Employer class.
Here is a simplified example. Imagine a class Main. When a Main object is deleted, objects Dep1, Dep2 have to be deleted as well. When Dep1 is deleted, Dep11 has to be deleted as well. If delete methods look like this: Dep1.delete(arg1), Dep2.delete(arg2), Dep11.delete(arg3), then the delete method on Main has to look like this: Main.delete(arg1, arg2, arg3). You see? The more objects depend on the Main - more arguments will be needed for deletion.
I must also point out that I am interested in deletion from the database, i.e. deletion in its "business logic" sense. I do not even unset "deleted" objects in the delete method.
What options I have considered:
grouping arguments required for deletion into a separate object. I just do not see how all these arguments can be grouped. They simply do no belong together. For example if an Invoice_searcher and Job_searcher are needed - why would they go together in one object? And what object could that be?
moving deletion of dependent objects out of the delete method in the Employer class. In this case not calling delete methods on children explicitly would leave the system in an inconsistent state. I would like to avoid that.
If you are passing parameters to deletion functions, you are making a mistake.
Each object on which you call your deletion function should be able to identify the other objects which it is the parent of.
I emphasise object because it sounds like you are coming at this from a relational perspective.
Try to use the Composition in such a way that once u make the employee reference less other will become automatically reference less....
Other way is to take the help of nested class , if the top most encapsulating class will get
unreferenced other will also be automatically get unreferenced..(but make sure u are not pulling out the reference of nested class(say your inner class) out in some other class.)
In my line of work I don't have to write much code to delete, so take my advice with a grain of salt. It might help to look at how these objects/records are created, and handle the deletion in the same way. For example, if the create logic is like this:
Create Employer
Create Invoice
Associate Invoice with Employer
than maybe the delete logic should look like this:
Remove Associations of Invoice(s) with Employer
Delete Invoice(s)
Delete Employer
As long as the entities are created in a consistant way, deleting them in the reverse order should also prove to be consistant.