The Artima Developer Community
Sponsored Link

Weblogs Forum
The Price Of Two

27 replies on 2 pages. Most recent reply: Feb 26, 2005 7:16 AM by Thomas Eyde

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 27 replies on 2 pages [ « | 1 2 ]
Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: The Price Of Two Posted: Jan 5, 2005 5:36 PM
Reply to this message Reply
Advertisement
> > Re why it is important that the model know that it a
> > single view registered for the events.. To me, it is
> just
> > cleaner to see that all of the events are being
> received
> > by the same object. If we make that explicit in the
> code
> > by using an interface, it can make the design clearer.
>
> One could argue that it's not the model's place to know
> who is going to listen to what combination of its events.
>
> (Personally, I sympathize with your interface-based
> approach, since I like to have the compiler know as much
> as possible. But I know some talented programmers who
> would vigorously argue the other side.)

It's situational, but I do really things to be explicit, for the sake of clarity. To me, there has to be some larger payoff to forsake clarity.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: The Price Of Two Posted: Jan 5, 2005 5:53 PM
Reply to this message Reply
> > I agree. Those are all important, but in this case I
> > think that the programmers could've avoided a bit of
> > trouble if they picked their abstractions more
> carefully.
>
> One thing that has become more apparent to me as I
> practice object-oriented programming more is that it is
> important to pick the right abstractions. Rarely are the
> types built in to a language good abstractions for a
> business problem domain. However, I have never learned to
> pick the right abstraction in advance very well, so I do a
> lot of refactoring. But who was it that said, "you're a
> lot smarter than me, so we'll try it your way."?

I should've said constructs above rather than abstractions. Sorry.

Here's the thing.. I assume all abstractions are going to change. Sometimes I'm surprised and they don't, but on balance many do. Knowing that, there's a bit of a payoff in avoiding overly specific constructs.

Sure, it is easy to use a std::pair in C++, but you have to watch it. If you use it in too many places, the price gets higher when you want to add the third item. std::pair doesn't handle third items very well. But, a class like this:

class Whatever
{
string user;
Subscription sub;
};

It scales beautifully. It handles a third item well. All you have to do is add it. This isn't to say that pair doesn't have valid uses, but it's great to avoid putting up roadblocks unless we have a very good reason.

charles medcoff

Posts: 3
Nickname: cmedcoff2
Registered: Jan, 2005

Re: The Price Of Two Posted: Jan 5, 2005 6:53 PM
Reply to this message Reply
You guys should have a look at Robert Martin's design principles and JDepend.

Have a look at http://www.objectmentor.com/resources/articles/granularity.pdf and http://www.objectmentor.com/resources/articles/stability.pdf. Then Goggle JDepend. It can be incorporated into Ant build scripts. I can help you decide how to partiction logical packages (java namespaces) into physcial packages (java jar files).

charles medcoff

Posts: 3
Nickname: cmedcoff2
Registered: Jan, 2005

Re: The Price Of Two Posted: Jan 5, 2005 6:56 PM
Reply to this message Reply
Opps wrong thread. Please ignore.

Owen Rogers

Posts: 2
Nickname: exortech
Registered: Feb, 2004

Re: The Price Of Two Posted: Jan 5, 2005 9:56 PM
Reply to this message Reply
with regards to the second example: just to make it explicit so that dumb old me can understand, you have a situation that looks like:

class View {
  public View(Model model) {
    model.Event1 += new EventHandler(Handle1);
    model.Event2 += new EventHandler(Handle2);
    model.Event3 += new EventHandler(Handle3);
  }
}


and you would prefer something like:

class View {
  public View(Model model) {
    model.RegisterForEvents(new EventHandler(Handle1),
       new EventHandler(Handle2), 
       new EventHandler(Handle3));
  }
}


or ideally something a bit more concise. is this right? or am i missing something?

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: The Price Of Two Posted: Jan 6, 2005 5:33 AM
Reply to this message Reply
Actually, something even more concise:


class View : ModelListener {
public View(Model model) {
model.registerView(this);
}
}


But, let's leave aside for a sec whether having View implement an interface is better. Opinions vary. The interesting thing is that once you choose to use an event and a delegate, it is easier to keep adding more events and delegates than it is to move to something like what I have above. Event/delegates don't move in that direction easily. It can be a little roadblock, and if you want to move to interfaces, you have to back up and redo it.

It's interesting how some constructs handle many directions of design evolution pretty well and others don't, they direct you down a particular path. To switch paths you have to replace them and hope that the dependencies are such that it isn't too hard.

Carl Manaster

Posts: 24
Nickname: cmanaster
Registered: Jun, 2003

Re: The Price Of Two Posted: Jan 6, 2005 8:30 AM
Reply to this message Reply
> Re why it is important that the model know that it a
> single view registered for the events.. To me, it is just
> cleaner to see that all of the events are being received
> by the same object. If we make that explicit in the code
> by using an interface, it can make the design clearer.

I can imagine a situation where not all listeners wanted all events - a "HighWaterMark" View, for instance, which wouldn't need to know when items were deleted. As I understand MVC (probably not well enough), the Model isn't supposed to know anything about its Views. Separate events for each kind of change helps with that, it seems to me. So I'm not convinced this was a bad design choice.

Chris Smith

Posts: 3
Nickname: smitty1e
Registered: Jan, 2005

Re: The Price Of Two Posted: Jan 6, 2005 9:27 AM
Reply to this message Reply
> I agree, but let's get a little more specific. In both
> those scenarios, it seems that it was easier to do it the
> wrong way when it was time to change. Why?

Your examples are both instances of a generalized decision problem in life: tactics vs. strategy.
Relationships, politics, programming; it's all the same: the courage to focus on the long-term, strategic goals is constantly in conflict with the near-term, tactical temptations.
Mellencamp is paraphrasable here: "...code goes on, long after the thrill of coding is gone..."

indranil banerjee

Posts: 38
Nickname: indranil
Registered: Nov, 2004

Re: The Price Of Two Posted: Jan 6, 2005 1:22 PM
Reply to this message Reply
> Sure, it is easy to use a std::pair in C++, but you have
> to watch it. If you use it in too many places, the price
> gets higher when you want to add the third item.
> std::pair doesn't handle third items very well. But, a
> a class like this:
>

> class Whatever
> {
> string user;
> Subscription sub;
> };
>


Another option in C++ (and Python) is tuples.

typedef tuple<User, Subscription, TimeLimit>
typedef map<ID, MyTuple> MyMap;

It's easy and extensible. And your not forced create a class for members that dont really belong together.

Girts Kalnins

Posts: 23
Nickname: smejmoon
Registered: May, 2003

Re: The Price Of Two Posted: Jan 7, 2005 1:54 PM
Reply to this message Reply
Could you tell how team was controlling the code?
Automated tests, other tests, source control, experience in domain, management imposed restrictions, e.t.c.

How comfortable did they felt while editing this code?

I see that there are thing wich you can know from your experience fairly well and things that you can not. But most of time you can refactor when you know.

Owen Rogers

Posts: 2
Nickname: exortech
Registered: Feb, 2004

Re: The Price Of Two Posted: Jan 8, 2005 3:49 PM
Reply to this message Reply
conversely, it is just as hard to move from an interface to an events/delegates approach as it is to move away from it.
personally, having used both approaches, i far prefer the events/delegates approach -- irrespective of the duplication that you mentioned in the design. here's why:
1) it is much easier to do acceptance testing at the controller/model/presenter layer if the model is not coupled to the view. by passing the view to the model, the model now acquires a back-reference to the view -- even though the view is abstracted behind an interface, the model still assumes that an instance exists. With the event approach, there is no assumption that anything is actually receiving the event. There could be one, zero or multiple receivers. From the acceptance testing standpoint, you only need to register for the events that you actually care about testing. Essentially the acceptance test driver becomes another view for your model that may only be interested in certain events.
2) the other concern that i have about the interface approach is that it makes it more difficult to decompose/componentise your view. as we build up the view for an application, we generally identify certain common view components that we extract out. our original view is now built up by a composition of reusable gui components. with the event-based approach, there is no need for the original view to implement an interface, creating a method to delegate to the component it is composed of. it's just a bit wasteful.

are any of these considerations relevant to your codebase?

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: The Price Of Two Posted: Jan 10, 2005 2:07 PM
Reply to this message Reply
What's also interesting is that a language's features can influence your decisions about what idioms to use. In C# there is nothing preventing you from doing events with interfaces instead of event objects, as they are done in Java. Yes, you have to "manually" maintain a list of listeners, but that isn't that much work and is not that hard to wrap up in a general pupose utility that does it everywhere where you need it. However, it seems that simply because they were using C#, the programmers (in your original example) felt they "should" use events. After all, that's the C# idiom, right? And it's better than Java, right?

By having only static, named inner classes, C# encourages using events over Java's annoymous inner class idiom for single events, but that doesn't mean you can't or shouldn't register interfaces for multi-event purposes.

Thomas Eyde

Posts: 5
Nickname: teyde
Registered: Apr, 2004

Re: The Price Of Two Posted: Feb 26, 2005 7:16 AM
Reply to this message Reply
The event model in C# is broken. The sender has to care if there are any listeners or not. You will get a null exception if you try to raise an event when there are no listeners. Why anyone would want an instane behaviour like this, is beyond me.

Is there really anyone who thinks the following code looks good?

if (Click != null) Click(this, EventArgs.Empty);

I have heard that under certain race conditions, we have to rewrite the above because the last listener could be removed between the test and invokation:

EventHandler h = Click;
if (h != null) h(this, EventArgs.Empty);

Can you imagine we have to do this every time we want to raise an event? A language feature? This is just insane.

Flat View: This topic has 27 replies on 2 pages [ « | 1  2 ]
Topic: Security?  What's that? Previous Topic   Next Topic Topic: Static Versus Dynamic Attitude

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use