elusion has asked for the wisdom of the Perl Monks concerning the following question:
I'm trying to design a news reader. Yes, I know there are plenty out there, but I'm looking to write one in Objective-C for OS X. I'm asking about it here because I'm looking for design help, not code help.
Basically, my confusion lies with keeping track of different groups. I want to create an object for each group and keep additional information for ones that the user subscribes too. By itself, this isn't a problem. The problem is how to handle refreshing the group list.
I have a hash or array that holds all the groups. Some groups just have skeleton information, while others have detailed information about messages. And groups can be added or deleted.
Ideally, when the list is refreshed, I would just create a new object for each group and store them in my collection. But that would mean that I would lose the information for each group. I could hunt down all the groups that have additional information and copy that information over, but I think that would be a lot of work.
Else I could try to modify my collection by dropping the groups that have been removed and adding the groups the have been added. Is there a better way? Are there other times a problem like this comes up? How should I work this? Thanks.
Re: Refreshing Objects
by pg (Canon) on Nov 23, 2003 at 20:59 UTC
"Ideally, when the list is refreshed, I would just create a new object for each group and store them in my collection. But that would mean that I would lose the information for each group."
elusion, you have to analyze the information you stored in your group list. There are two types of information:
- One type of information you can get from the network, the news group itself, those information can be flushed and updated each time when you refresh from the network.
- Another type of information is clinet specific, for example the last article number you downloaded in each group. Those ones you have to persist them in a way, and make sure they don't get lost, when you refresh the first type of info.
From a OO design point of view, it is not "ideal" to drop the entire list, and recreate it. Why should you drop the entire list, just because a new element joins the list, or an old element gets deleted? Why should you drop the object, when you can simply modify some of its attributes? You have to clearly differentiate the concepts of object and its attributes. You have to clearly differetiate the object and the collection it is in.
Your OO code similates the real world, and in the real world,
- You don't drop all existing news groups and recreat them, when a new group get added or an old group get deleted. They just stay the same, they are independent objects, which has no tight relationship with the one gets added/droped.
- You don't drop the group when new articles added to the news group, some of the attributes of the news group changed, but the news group is still the same as before.
In your OO design, you need to create a new object to represent a new newsgroup when it gets created. You might delete an existing object, when the news group it represents got deleted. (Actually, you even probably should not delete it, instead just mark it as inactive, or dead, as you don't want to lose the history. This depends on the nature of your application.) But other news group should not be affected.
"I could hunt down all the groups that have additional information and copy that information over, but I think that would be a lot of work."
This is the right way to go. Go the right way, not the way seems to be easier.
(Update: gave a second thought, I think I probably have misunderstood your idea. I thought you meant to search and modify particular elements, but you probably actually meant to copy the entire collection. Also, I sense that you might stored multiple copies of the same entity. If that's the case, it would be a better idea, to have just one object to represent the entity, and have all places need it to reference it, not to copy it.)
On the other hand, if the collection data structure you used to store your groups is right, I don't see a reason why it would be difficult for you to allocate a certain group (an element of the collection).
"Else I could try to modify my collection by dropping the groups that have been removed and adding the groups the have been added. Is there a better way? "
There are different options, but this is definitely one of the best ways. And I don't see any big problem with it.
I have the feeling that you are avoiding to write a search method for your collection object. This is either because you are lazy ;-) or your data structure is wrong, thus made such a search algorithm not that easy. If it is the second one, look at your collection structure again.
On the other hand, as you are doing OO design, your search method would be something that you only need to implement once, and can be used forever, why should you avoid it?
From a OO design point of view, it is not "ideal" to drop the list and create a new list. Your OO code similates the real world. In the real world, when new articles added to a news group, some of the attributes of the news group changed, but the news group is still the same entity as it was. In your OO design, why should you drop and create new objects? all what you want is to update some arributes.
I think maybe I didn't explain myself very well. I'm not talking about dropping the list of articles. I'm talking about dropping the list of newsgroups. The list of groups is somewhat harder since groups can be removed.
At the root of my hierarchy is a list of servers. Each server has a list of different newsgroups that you can subscribe to. This list of groups can change, either because groups or added or because they are removed. Each group the user subscribes to then contains a list of messages in that group.
When I refresh the list of groups from each server, I need to find a way to keep the list of messages in the groups the user has subscribed to.
Also, you tell me not to create a new list of objects, but then you tell me that copying message lists (and other properties) from the old list to the new list is a good solution. Which is it?
I just want to find the best solution for this type of problem. If writing a search method is the best way to do it, I'll write a search method. But if there's a simpler way, why would I want to?
"When I refresh the list of groups from each server, I need to find a way to keep the list of messages in the groups the user has subscribed to.
This is not a problem. As I mentioned in my previous reply, there is no need for you to physically delete the object, instead
- You can either mark it as inactive,
- or move it to another collection, which contains all news groups that the user once subscribed, but no longer exists.
Either way, you would still be able to preserve the messages in that group.
"Also, you tell me not to create a new list of objects, but then you tell me that copying message lists (and other properties) from the old list to the new list is a good solution. Which is it?"
Hm... That does not sound like what I suggested. But it could well be my fault, as I probably didn't explain myself well, or I probably didn't understand your entire situation well.
But is it not true, that the list of articles under an object can be re-hooked to a different object, without copying the entire list? If it is not, you have to look at this again.
Also, is it not true that, in a tree structure, when you reposition a node, you could choose to keep the entire subtree under it untouched (follows it to where it goes)? If that sounds like something you need, you may want to think about it.
Well, I may still not understand your entire situation well, but take my suggestions, if they fit in your situation, otherwise discard them or save them for next time. If we can discuss this face to face, it would surely be much easier for us to understand each other better, well...
Re: Refreshing Objects
by CountZero (Bishop) on Nov 23, 2003 at 21:04 UTC
Just a try: when going sequentially through the refreshed list of groups, check your objects for each group you go through, updating the info on existing objects or adding new objects for new groups; "tag" every group added or updated so you know you have visited it for this refresh.
When you reach the end of the refresh list, now go through all your objects and drop those which have no "visited" tag (meaning they are no longer in the refreshed list and presumably were removed). At the same time "reset" the visited tag for next time around.
You thus go once through the refreshed list and once through your object list: seems not too "expensive" to me.
"If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law