I have two classes. Parent and Child in a OneToMany relationship. Parent has an array called $children where it stores Child instances. Child has a private $name property with public getter/setter methods. I want children with unique names.
The way I went about solving this is that I pass to the Child's constructor method the Parent instance, I store it in $_my_parent, and on the Child's setName($name) method I ask the Parent instance to loop all children and check if $name can be used.
Pretty straight forward.
Q1: This obviously creates infinite recursion. Is that a problem? When serializing?
Q2: Is there another way of doing this?
While 100% guaranteed data integrity this way may be nice in theory, in practice it's not attainable anyway. You could always set properties on your objects which make them not unique, for example using the Reflection API.
I'd keep it simple:
your child objects are dumb data objects, they do not know anything about their parent and are self contained
the parent just holds child objects, it does not inject itself into them
either in the parent object or yet another external class, have a validation method which checks whether the parent-child combination is valid by iterating the children and ensuring their uniqueness
Simply call this validation method explicitly whenever necessary, don't trigger it automatically whenever you modify a child. It gets rid of a lot of complexity and problems with very few downsides.
Related
I have recently taken on a simple php project to get to know OOP a little better.
Basically the project consists of a single table where multiple items of different types (food, furniture, electronics, etc.) can be inserted.
I have an abstract class Items() that constructs the connection to the database and defines an abstract function save_item(). I also have a class for each item type that extend Items() i.e. class FurnitureItem extends Items()
An ItemsFactory() class just generates the correct object.
This is done due to the fact that each item type has slightly different properties and the input data should be handled differently.
However, I also have functions such as fetch_items() (just outputs all items from the table) and delete_items() (bulk deletes items not caring about their type). These functions function irrelevant of item type.
My question is, where should I put fetch_items() and delete_items()?
Clearly, they are not relevant to a specific item type (therefore should not be defined in child classes), however defining them in the parent class Items() seems illogical as the child classes would inherit these functions as well. But they shouldn't, for the reason above.
Should I make a new class for just these functions? Then in essence I would be making a class that contains just the generic functions of the project.
Any help would be appreciated!
Clearly, they are not relevant to a specific item type (therefore should not be defined in child classes), however defining them in the parent class Items() seems illogical as the child classes would inherit these functions as well. But they shouldn't, for the reason above.
But you DO want to define these functions for each of the subtypes. You want the FurnitureItem class to have a delete_items() function (because you will be calling this function for this class later). Since that function is common to other subtypes, it makes sense to include this in parent Items class, because that's the base implementation for deleting any 'Items'. Base classes are usually always used to contain logic common to all child classes.
Also, if you want a custom implementation of delete_items() later for a particular sub-class, you can override the function in that class
If i need to make the object knoW about its state change, i make all properties private and add setters and getters for them.
What about if object's property is another object.
I can get it by link with get method, change it, and parent object won't know about it.
I suppose it is a regular problem and it should have a traditional solution. What pattern should I read about?
Actually the child object has another object to, and i want to notify the main parent. Recursively
The simplest solution to this problem is to only allow children mutations through the root entity, which means you ideally wouldn't expose accessors to retrieve children and if you do, you'd return copies to preserve encapsulation. This approach usually aligns very well with a behavior-rich domain model.
However, if you are modeling large graph-like structures then the above-mentioned approach may not be very practical. In that case you could rely on an implementation of the Observer Pattern or any of it's variants.
Please note that modeling very large root entities is often a code smell that might lead to performance issues & concurrency conflicts. The root entity should only be as large as it needs to be to protect business invariants.
I am writing a Data Mapper in PHP and am trying to work out how to implement an Identity Map when my domain objects follow Class Table Inheritance.
The problem, as I see it, is that an Identity Map cannot guarantee that data is manifested only once in the in-memory model because hierarchical objects are relying on hierarchical data.
For example, in my database I have a Parent table and a Child table. In my domain model I have a Parent class, and extending from that, a Child class. I can instantiate both a Parent object and a Child object, and record their identities in an Identity Map, no problems. If client code requests the same Parent or Child, I can return it from my cache, rather that the database, no problems.
But what happens if the Parent and the Child both relate to the same parent record? i.e. the same data in the Parent table? I now have that data represented twice in-memory, and if it's modified in one (or both instances) I risk overwriting the changes.
It seems to me that somehow the Identity Map needs to follow a hierarchy similar to the Domain Objects and Mappers themselves, however it gets a bit complex at that point. Also, I have lots of Dependent Mappings to take into account too.
Any ideas/advice much appreciated!
If you find you have lots of repeated/duplicate data, the design is wrong...
I.e. if you're parent has say an address which is shared by a child, you should have an address table, and each of those records will point to the single entry in the address table etc.
Then it's a case in you're app to have the relevant rules, i.e. if address is changed in child account... what do you do? update (which means parent will also have new address) or insert a new one.
I defined an interface, iQueueable, and only objects which implement this interface may be queued to have their changes written to the database.
Child objects have the full complement of object properties, so they implement iQueueable. Parent objects can not be queued.
This still allows parent and child object to fall out of synchronisation, but now there is only one source of database changes.
You have a class, that perfectly fits to be an abstract, but this class cannot work normally without data supplied from derived class. It's not convenient to pass all data to constructor because not all of it may be needed, and many of them can be dynamic (result from child function).
What are the best practices to compose such structure?
Or is it a bad design in the first place?
Declare abstract functions, that child must implement?
Declare normal functions, that are overriden in child class?
If there is a reasonable default behaviour of the function that can be relied on in a majority of children, it can be implemented as a normal one. Otherwise (no default behaviour and/or most children have to override it), it's better to declare it as abstract. The side effect is that you never forget to define it in a child class because failure to do so will be immediately reported.
The other opportunity is the use of containers (for example, arrays) for the data that are specific to the child classes, but still are subject for general checks or other processing that can be done in the common ancestor. This way you define a variable that holds the data, but the data itself is filled in the children. The code in the parent class can iterate over this container and do some routine work on all the elements.
My question is more like a theoretical.
Say you have an object, that represents the list of something (articles, pages, accounts etc.)
class ObjCollection
You have a class, that represents a specific item in collection:
class objItem
I have a problem thinking of a basic responsibilities of each object.
Which class is responsible for creating a new objItem?
Which class is responsible for deleting a objItem? Should it delete itself as a method?
Update 1:
Techpriester: Is it ok to use object's constructor as a function to create new item?
I think of that like:
class objItem {
public function __construct($id = 0) {
if ($id > 0) {
// load item data...
} else {
// make new item...
}
}
}
But what if something goes wrong in the code, and instead of passing an $id > 0, it passes 0? In this case a more expected behavior would be an empty object, and not the new one, or am I wrong?
A way of thinking about this:
objItem usually have a class constructor so this class might be responsible for creating objects of type objItem.
When an objItem is inserted in a list/collection let's say objCollection it can be objCollection responsability to delete it from the collection.
objItem usually have a class
constructor so this class is
responsible for creating objects of
type objItem.
Constructor has nothing to do with responsibility (usually). Thinking this way, every object would be only responsible for itself.
Responsiblity is a concept not directly binded with class hierarchy.
If:
ObjCollection = Nest objItem = Egg. And there is third object Bird, Then Bird takes responsibility for creating egs (even if nest contains egg). It is not about programming it is about common sense... :)
There is not such thing like "empty object". Objects have "state". You can create an object and then you have it, or you may not to create it and there is no object then.
All you have to worry about is if your constructor will work fine in both cases, with new object created and without it.
Usually it is better to inject object as a constructor parameter (instead of $id) not to create it inside another object.
I know this doesn't answer your question, but since you tagged this as PHP I'm going to assume that it will almost certainly be applied with some sort of database model.
In that case, it's probably a better idea to do away with 'collections' altogether since if you made each class represent only one object, if you wanted to view 10 blog posts, for example, you would be calling 10 separate SELECT queries each retrieving only an individual database record, because you decided to have the 'BlogPost' class encapsulate its retrieval method.
The alternative is to let the class represent either one or more records, that way, you only need to run one SELECT query whether you're retrieving 5000 records or only one. Pretty much every object-relational-mapper does this.
When doing object-oriented programming, it's better to think in terms of behavior or responsibility than whether or not the object is a tangible 'thing'. That's the problem with theoretical discussion of OOP. It's very tempting to use analogies like animals and fruits which have very little relevance to real-world programming.
Since an object cannot delete itself, that has to be the responsibility of the collection.
Wether you let the collection create it's objects like $collection->makeNewItem(); (which then calls the items constructor) or use $item = new Item(); directly and then some $collection->addItem($item);method is entirely up to you and the needs of your application.
I'd recommend using regular instantiation if the items themselves are also used outside of the collection.