You have already mentioned this, but it is fundamental in the design. Moreover, I would say that you shouldn't provide a default implementation of this. A common way to solve this problem is to pass an array of integers representing unique IDs in the database.
Do not enforce this with typechecking if you want your Item and Items to share the same interface. An Item would take just one id, while Items would take an array. PHP is awful with overloading, so I wouldn't enforce array to make it easier on you.
How will saving work? The way it looks, every node will have to be tightly coupled with the database to know how to save. That can be good and bad, but either way you need to think about it.
I'd probably recommend decoupling that a bit more (separating them). I'd use interfaces AND abstractions. More detail on this below the code.
In addition to having sort, I would add a default way to compare items. I'd define compareTo() in your Item class. I'd also define an equals() method while you are at it.
XmlSerialize should be a separate interface. I've honestly wished PHP had such an interface natively.It has a lot of use on its own. Implementing Countable lets you use PHP native count().
This is the PHP way to get the size of something. Easily done, may as well throw it in. Overall, you've done really well, but I have some suggestions.
The code below is not perfect nor complete, because it does not fix some of the questions I've posed above. However, it does offer some more functionality than what you've given. Also note that I've renamed things to be ActiveNode rather than a CollectionItem or the like.
It made more sense to me. Notes: Define abstract classes that implement the interfaces to provide some default behavior. Having the interface separate from the abstraction has been useful to me in some cases.
If this is every open-sourced, it would be come increasingly important. Throwing exceptions is really nice compared to returning booleans. It seems like you probably understand this, but it's worth noting.
Notice that I've used exceptions to also denote resource unavailability.It's useful to have a defined behavior when things go wrong. I throw InvalidArgumentExceptions on anything that takes an IActiveNode as a parameter. This allows you to extend IActiveNodes and the extension will only work with certain types.
Very useful. My solution is approaching something very Java like. I would say that depending on how far you want to take this, I would recommend using a different language (though not necessarily Java).
I often implement ArrayAccess as well if you want your list to be able to be syntactically treated like an array. Honestly, I wouldn't mind talking to you about this more. Don't hesitate to contact me.
Breaking out XML serializer is a great idea: added. I already had Countable in there, and have considered ArrayAccess. I also already had comparison/sorting/filtering functionality very similar to what you suggested.My biggest concern is persistence.
Everything I have works great if the entire collection is always loaded, but that leads to inefficiencies with collection-level operations that manipulate a small number of items. I think I'll just move all persistence bits into the concrete collection classes, and use the item classes strictly to store item properties. Seem like a good idea?
– mr. w Nov 10 at 20:31 @mr.w I'm not sure I followed you. What inefficiencies are you worried about? Also, how do you magically have everything in the collection already?
That seems very odd and inefficient to me. – Levi Morrison Nov 10 at 20:44 Items are loaded in the implementations of CollectionItemAbs by the constructor. Basically, it grabs a list of the IDs in the collection from the database, then instantiates an item for each and tells it to load by ID.
This works great for collection-wide operations, but sucks for item-specific operations. For example, to retrieve a list of items that match certain criteria, the entire collection must be loaded and filtered, versus just loading only those items that match in the first place. Thus, I think it'll be good to move persistence out of the item - just not sure of the best way yet.
– mr. w Nov 10 at 21:33 @mr.w How much filtering is going on here? You may as well invest in a database abstraction layer or something of the likes if it is complex filtering. One that I really like but is still young and active (IE, bad for business applications) is Hydrogen: webdevrefinery.
Com/forums/topic/1440-hydrogen-overview . Hydrogen has a lot of other things it does too, so you may want to look at it anyway. Or, if you need a more mature library, see stackoverflow.
Com/questions/108699/good-php-orm-library – Levi Morrison Nov 10 at 21:53.
Tl;dr but public function AddItem(newItem: CollectionItemAbs); instead of that, you have a lot of functionality already defined if you instead base collections off of ArrayObject: class CollectionAbs extends ArrayObject { public function offsetSet($index, $value) { if(!$value instanceof CollectionItemAbs) { throw new InvalidArgumentException(__CLASS__. " only contains instances of CollectionItemAbs"); } return parent::offsetSet($index, $value); } } There are more, pretty nice examples in the SPL for you to use.
I often don't want other people treating my code as ArrayObjects, but that's a personal preference. It does cut down a lot of potential code. – Levi Morrison Nov 9 at 22:34 What is the downside of treating object collections as arrayobjects, in your opinion?
Personally I don't think they are used by themself, ever, since they do the less things than the standard array. – chelmertz Nov 10 at 6:38 Honestly, ArrayObjects are really confused about what they are. Sometimes you can use object notation on them, sometimes you can't.
They can be finicky, sometimes. Also, ArrayObject is not commonly seen in PHP. Ding away things in an unfamiliar abstraction can be harmful.
Composition and implementation are far more clear than inheritance in this instance. – Levi Morrison Nov 10 at 18:32 I disagree, I guess. Haven't had any problems with using this approach for collections and probably saved a lot of time while doing it too.
Regarding the inheritance, I don't really get anything I mind having but I do gain pretty much (as seen in the code sample). – chelmertz Nov 11 at 11:35.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.