Is UML Class Diagram of Zend_Log correct? - zend-framework

Background of question
Analysis of Zend_Log reveals following Class Diagram
Zend_Log:
uses ReflectionClass & Zend_Log_Exception
maintains reference to array of Zend_Log_Writer_Abstract
maintains references to array of Zend_Log_Filter_Interface
Zend_Log_Writer_Abstract
maintains reference to array of Zend_Log_Filter_Interface
maintains reference to Zend_Log_Formatter_Interface
Questions
Zend_Log_Filter_Interface relates with Zend_Log_Filter_Suppress, Zend_Log_Filter_Message & Zend_Log_Filter_Priority as depicted, is this correctly laid out in Class Diagram?
Is it okay to say that, the Zend_Log contains reference to array of Zend_Log_Filter_Interface and this is composition relationship (similarly for Zend_Log_Writer_Abstract)?
As it is obvious that Zend_Log_Filter_Interface is contained by both Zend_Log & Zend_Log_Writer_Abstract, while Zend_Log contains Zend_Log_Writer_Abstract, that makes Zend_Log_Filter referenced by both container (Zend_Log) and contained (Zend_Log_Writer_Abstract); is that some "Design Pattern", if yes what is the name?
Regards!

Zend_Log_Filter_Suppress, Zend_Log_Filter_Message, and Zend_Log_Filter_Priority all implement the Zend_Log_Filter_Interface interface. This is denoted using the empty arrow and dotted lines between them. The same is true for Zend_Log_Formatter_Interface and the three classes depicted below it.
Yes, that's correct. Whether to use an association (-->) or composition here could be debated since two Zend_Log instances could share a single Zend_Log_Writer_Db instance. As the writers and filters determine the overall behavior of the log, composition makes sense to me.
Each log instance can write to multiple writers. Messages are first filtered by the log itself, and any message that passes goes to every writer. Each writer filters the incoming messages as well. This allows you to ignore all messages below the WARN priority (at the log level) which get written to a file and further limit database logging to those at the FATAL level. You could accomplish the same effect by dropping the log-level filter array, but it would require duplicating the filtering in each writer.

Related

How can I represent relationships between instances of the same class in a concurrent system

I made a concurrent system which has a critical section which involves read and write access to a TXT file.
First, an Auctioneer class creates a TXT file and writes the number 50 to it. The Auctioneer then allows the next node, one of three instances of the Bidder class, to open the file and change the current bid. The bidder class then allows the next node, another bidder to bid, then another bidder, and then that bidder allows the Auctioneer to look at the file.
I allowed the nodes to take turns using server sockets. Each node waits for access using the ServerSocket.accept() method, and allows the next node to enter its critical section by creating a Socket object with the socket that ne next nde is listening on.
Each of these nodes run independantly in seperate java environments and only communicate with server sockets.
Each node of the ring relies on the previous node because in order for that node to access the resource, the previous node needs to pass the current node the token. I'm unsure on how I would represent that kind of relationship in a UML compliant way.
It is of my understanding that class diagrams should not include several instances of the same class such as the example below with 3 bidders.
Is this the correct way to represent the relationship which I have described? If not, which way would be better/UML compliant?
Class diagrams, as the name suggest represent classes of objects and not individual objects, i.e. instances of these classes. Moreover, a class diagram is structural: it does not tell how objects interact or wait one for another, but how classes relate.
In tour case the class diagram would therefore represent one bidder class. To represent a concrete example with instances and how they relate, you could consider an object diagram. There you could very well represent different instances of the same class.
However, if you’re interested in the interactions between classes (e.g. the tokens they exchange), you’d better consider an interaction diagram such as the sequence diagram.

What are the disadvantages of using records instead of classes?

C# 9 introduces record reference types. A record provides some synthesized methods like copy constructor, clone operation, hash codes calculation and comparison/equality operations. It seems to me convenient to use records instead of classes in general. Are there reasons no to do so?
It seems to me that currently Visual Studio as an editor does not support records as well as classes but this will probably change in the future.
Firstly, be aware that if it's possible for a class to contain circular references (which is true for most mutable classes) then many of the auto generated record members can StackOverflow. So that's a pretty good reason to not use records for everything.
So when should you use a record?
Use a record when an instance of a class is entirely defined by the public data it contains, and has no unique identity of it's own.
This means that the record is basically just an immutable bag of data. I don't really care about that particular instance of the record at all, other than that it provides a convenient way of grouping related bits of data together.
Why?
Consider the members a record generates:
Value Equality
Two instances of a record are considered equal if they have the same data (by default: if all fields are the same).
This is appropriate for classes with no behavior, which are just used as immutable bags of data. However this is rarely the case for classes which are mutable, or have behavior.
For example if a class is mutable, then two instances which happen to contain the same data shouldn't be considered equal, as that would imply that updating one would update the other, which is obviously false. Instead you should use reference equality for such objects.
Meanwhile if a class is an abstraction providing a service you have to think more carefully about what equality means, or if it's even relevant to your class. For example imagine a Crawler class which can crawl websites and return a list of pages. What would equality mean for such a class? You'd rarely have two instances of a Crawler, and if you did, why would you compare them?
with blocks
with blocks provides a convenient way to copy an object and update specific fields. However this is always safe if the object has no identity, as copying it doesn't lose any information. Copying a mutable class loses the identity of the original object, as updating the copy won't update the original. As such you have to consider whether this really makes sense for your class.
ToString
The generated ToString prints out the values of all public properties. If your class is entirely defined by the properties it contains, then this makes a lot of sense. However if your class is not, then that's not necessarily the information you are interested in. A Crawler for example may have no public fields at all, but the private fields are likely to be highly relevant to its behavior. You'll probably want to define ToString yourself for such classes.
All properties of a record are per default public
All properties of a record are per default immutable
By default, I mean when using the simple record definition syntax.
Also, records can only derive from records and you cannot derive a regular class from a record.

Problem with boundry for different aggregates

I have a problem with the boundaries of aggregates. I was trying to read about aggregates, aggregate roots, and boundaries, looking for some code examples but I still struggle with it.
The app that I'm working on is an app to manage architecture projects.
Among the screens in the app there will be a screen with all details for the selected project, and one with all jobs for the selected constructor.
I have one AggregateRoot - ArchitectureProject.It has an Architect, Stages, etc. and it has a list of ConstructorJobs (as it has to be on the screen with project details). ConstructorJob has its name, some value, and a Constructor. A Constructor can have some ConstructorType. As for me, Constructor is another AggregateRoot. I have a problem with ConstructorJob. Where should I place it? What should be responsible for managing it?
I was trying to thing what cannot exist with what, and ConstructorJob cannot exists without Project, but on the other hand it has to have Constructor as well...
I can't imagine that Constructor would belong to Project Aggregate, as ConstructorType would be 4th level child to id, so searching for all constructors of that type would be painful, wouldn't be?
I would appreciate any explanation, how to handle such cases.
I think you are missing an important rule which usually makes your life a lot easier:
Rule: Reference Other Aggregates by Identity
See also Vaughn Vernon's Book Implementing Domain-Driven Design, chapter 10 - Aggregates.
It is important to note that Aggregates in the sense of domain-driven design are not so much focused on if the existence of one aggregate makes sense without the other. It is more about transactional boundaries. So an aggregate should create a boundary around elements that should only change together within the same transaction - to adhere to consistency.
So I guess, that you will change your Project in different use cases you would change the Constructor - which I guess can be referenced in different projects.
This means you should reference other aggregates within aggregates only by id which avoids modelling huge aggregates with deep hierarchies. It also means that if your aggregates tend to grow bigger over time that you might have missed some new aggregate which you initially modelled as entity and should be an aggregate on its own.
As for me, Constructor is another AggregateRoot. I have a problem with ConstructorJob. Where should I place it? What should be responsible for managing it?
In your case I would model it the following way:
The ConstructorJob is a Value Object which holds some data (name, etc.) and also a reference to a Constructor aggregate. But this reference is not a reference in terms of object reference like you would do it with a child entity of an aggregate root. The constructor aggregate is referenced by an identifier (UUID, integer or whatever you are using as id type) in the ConstructorJob.
The ConstructorJob value object would be part of the Project aggregate. The project aggregate could of course directly hold the id of the constructor aggregate but I guess in your case the value object might fit quite well.

AddItemToSet vs StoreRelatedEntities

I am trying to understand when someone would use AddItemToSet vs StoreRelatedEntities.
It seems the former is a way to associate a set label with a string-based item handle.
The latter is a way to associate two entities, which seems like a more generalized operation.
What is it that AddItemToSet does that StoreRelatedEntities can't do?
Thanks
The AddItemToSet API in ServiceStack.Redis is a 1:1 mapping that calls Redis' Server SADD Operation, i.e. adds an item to a Redis SET.
The StoreRelatedEntities is a higher-level operation that also maintains an index containing relationship between the entities described in detail in this Storing Related Entities in Redis answer.

What is the difference in ECore between containment and reference?

When creating references between ECore entities there is the possibility to mark a reference as "containment".
Can somebody explain me in easy words what's the difference between a plain reference and a containment? The definitions and explainations I found so far didn't do the trick for me.
Reference: A reference is a plain "A knows B" relation. Separate references do not influence each other. A can know B and B can know C. Hence, if you have A, you can go to C over B. If you remove the reference, A, B and C will still exist, they just don't know each other any more.
Containment: A containment is the "A has B" kind of relation. Usually used for lists, e.g. "A has multiple B". ECore/EMF can then perform atomic commands on such collections, such as move all objects from one containment to another. It can also enforce constraints, such as a minimum amount of contained objects or a maximum amount of contained objects, or ensuring that the contained object is not contained in any other containment.
Example:
Assume you have an object called ShoppingCart with a reference called Customer and a containment called OrderedProducts. The OrderedProducts has a reference to a Product.
What does this model tell you?
You can assign a Customer to the ShoppingCart. If you remove the Customer from the ShoppingCart, the Customer object itself will still exist (e.g. in the database)
The OrderedProduct objects need a ShoppingCart to exist. If you remove one from the ShoppingCart, it will cease to exist.
Each OrderedProduct has a reference to an existing Product in the database. If you remove one of the OrderedProducts from the ShoppingCart, the Product in the database will still be there - just the order of that product for that specific customer is gone
Reference : can be like association in UML
Containment : is the composition relation from UML
Also this can be seen in the EMF diagram, if you set the containment to true, then the line will have a filled side, showing the containment/composition. This is what I have observed.