• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Co-dependent Classes

 
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've run into a problem with co-dependent classes. Have a look:



To declare an Alpha object, I need a Beta object, and vice versa. I thought I might try:



But I realized I'm passing a partially initialized Alpha object to Beta's constructor, which kinda scares me.

I could set Alpha and Beta after construction using methods, e.g. "alpha.setBeta(beta)" and "beta.setAlpha(alpha)", but that seems like a kludge.

Maybe you need some more context to offer advice? Alpha is actually my GUI class (contains checkboxes and buttons). Beta is my so-called Configuration class (handles the logic). It doesn't make much sense to initialize a GUI without the underlying logic, and it doesn't much much sense to initialize a Configuration without a GUI (or some interface) to get data from.

Examples:
  • When the GUI's "Start" button is clicked, the GUI will call "configuration.start()".
  • When the Configuration needs to know the status of something, it might call "gui.isResourceAvailable()".


  • Am I making any sense? It's difficult to generalize. I want to improve my design.
     
    Rancher
    Posts: 600
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    I could set Alpha and Beta after construction using methods, e.g. "alpha.setBeta(beta)" and "beta.setAlpha(alpha)", but that seems like a kludge.



    Actually, that seems like a far better solution, IMHO.

    John.
     
    David Sharpe
    Ranch Hand
    Posts: 36
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks for the input, John. You may be right, but have you considered what construction would look like in that case?

    Furthermore, for the sake of robustness, I might be tempted to do this:

    Or something like that. It looks alright, but it'd need to be pasted into every Beta method that depends on Alpha, which most of them do.

    As I said, you may be right, it might be better than many alternatives, but (1) it puts the onus on the user of the class, and (2) it allows an object to be constructed without actually being "good to go".

    I suppose if I wanted "good to go" handling, I could do something like this:

    Instead of throwing an exception... bah. I'm probably worrying too much. It's not as if anyone is going to reuse my classes. I'm just trying to write good code, and this awkward design has me feeling I've made some conspicuous mistakes.
     
    John de Michele
    Rancher
    Posts: 600
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    David:

    Those are certainly valid concerns. However, they suggest that maybe your two classes are too tightly coupled. Some questions:

    1) Does the division of work really make sense? Probably the simplest suggestion would be to make the configuration class independent of your GUI class, in which case, you could have something like this (pseudo code):

    2)Does it make more sense to have a monolithic GUI class? In that case, maybe making the configuration class an inner class to the GUI would make sense.

    John.
     
    Ranch Hand
    Posts: 362
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I'd do something like this. This way when you init the GUI it inits its own controller

     
    David Sharpe
    Ranch Hand
    Posts: 36
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks John, I'm thinking about your suggestions now. I agree with your point about tight coupling. An inner class would definitely work in this scenario, but isn't that more tightly coupled than my current solution?

    John de Michele wrote:



    This works for me to some extent, but the communication between the GUI and the Configuration is two-way. To me, your pseduocode implies that the GUI will call Configuration methods, but not necessarily vice versa.

    I'll show a bit more source code, stripped-down of course:

    (I've named variables such that a graphical solution is implied, but please note that this design allows the "GUI" to be substituted with anything that provides the right accessor methods, e.g. "boolean doOperationA()". A text GUI could quickly be made, for instance.)

    So you see, John, in my current mindset, it's impossible to make the Configuration independent of the GUI because the GUI is the Configuration's data/state source. I did say "in my current mindset": you're right to indicate that if my division of labour/assignment of responsibilities is off, then I'll have to rethink things considerably.

    When I tried to make Configuration more independent, I ended-up putting more domain logic in the GUI:

    So now the Configuration no longer needs to access the GUI for this information. This still leaves the problem of having the Configuration report back to the GUI when certain events occur (e.g. "Operation A is complete."), but I could use an observer pattern (i.e. the Configuration will announce to its listeners). Overall though, it doesn't feel any better.

    Gerardo, thanks for replying. That's similar to what I'm currently doing, but I worry about passing the Configuration constructor a partially initialized GUI object. I might be worrying unnecessarily, as long as I don't do work in the constructor.

    Ah, my carpool is waiting. See you tomorrow.
     
    Gerardo Tasistro
    Ranch Hand
    Posts: 362
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I'd use three classes. One inner and two external. Think of the inner class as a type of JSP. It's the one that's inside the view and knows everything about the elements. But it doesn't know what to do or how to do it. So it depends on what you call the configuration class. Which I'd equate to a controller class in MVC. And the configuration class then uses a business class to get the work done.

    Here's how it would look.

    GUI class. I added a mouse listener to show how it would work. The button click is fed to doSomethingButtonReleased(MouseEvent e) which in turn calls the inner class.



    Here's the configuration class. Which doesn't know too much about the GUI, but it might still be bound by Swing implementations. For example internationalization. Storing properties and settings, etc. In a web design this would be replaced by the controller ( a bit like a MultiActionFormController from Spring). It depends on SomeService to get stuff done. SomeService should be totally decoupled and unaware it is being used in a GUI or web scenario.

     
    Greenhorn
    Posts: 22
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    May I suggest separating the gui operations you are trying to automate on to a separate class.
    I think what you have is a simple GUI so a View class makes sense and along with it you will need a Model class which is actually the data values and all which in your case I guess is the Configuration class.
    Now I imagine you want the configuration to do some operations in a separate thread, which would be the only case where the GUI / View class would not exist.
    If you really want that you would want to create a separate controller class which would take you out of the dilemma. This controller would be responsible for creating instance of Model and View and providing whichever where - ever you need.

    If you really don't want/have a separate thread, you do not need to worry so much, its like you do not create one without the other and then you can use appropriate setters and getters to do the job. That part I guess has already been answered in the post.

    Hope this gives you some direction. This is a design problem not a general java problem.

    Regards
     
    John de Michele
    Rancher
    Posts: 600
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    David:

    Here's another suggestion (with pseudocode):

    Create a behavior interface, so you could have different behaviors. Have a registerGUI() method to hook up the GUI:

    Have your GUI class take a Behavior object in its constructor:

    Then when the classes are created, it's easy to do the setup:


    Hope this helps.

    John.
     
    David Sharpe
    Ranch Hand
    Posts: 36
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks for the help, Gerardo. I reread your post a few times, and I have some ideas to try in my own program now. (Paragraphs are great and all, but code, even pseudocode, is so much more precise.) Right now, I think I have my "Controller" embedded in "Configuration" (which might be my "Model"). I'm not completely sure I want to change that, but it's good to be able to make a conscious choice on the matter.

    Sunny, you're right to imagine that "Configuration" is doing some operations in a separate thread: that's exactly what it's doing. I'm making some assumptions here, but from your wording I picture taking Gerado's inner class ("Controller") and making it a separate class completely, one that would instantiate the GUI and "Configuration" (the "Model") and handle communication between the two.

    John, I like your solution, and let me tell you why: it's similar to what I'm doing ("Mirror, mirror, on the wall..."). When I said "please note that this design allows the GUI to be substituted with anything that provides the right accessor methods", I was really thinking of an interface, but I questioned the utility of an interface that would never be reused.

    On one hand, I like the "registerGUI(GUI)" method you suggest since it acknowledges that two-way communication will be necessary, but that does leave me in the awkward place of allowing an "AwesomeGUIBehaviour" object to be initialized without a GUI, thus forcing "if (myGui == null) throw new YouForgotToSetAGuiException()" handling in AwesomeGUIBehaviour's code for robustness.

    Thanks for the advice so far, everyone. I think I'll use John's interface and consciously choose not to use Gerardo's and Sunny's "Controller", but at least I won't be ignorant that I made a decision. If I do as Gerardo indicates and instantiate "Configuration" within "GUI", e.g. config = new Configuration(this), sure I'll be using a partially initialized "GUI" object, but that's a compromise I'm willing to make, lacking a preferable option.

    Sunny X Narula wrote:This is a design problem not a general java problem.



    What would you recommend? OO, Patterns, UML and Refactoring?
     
    Gerardo Tasistro
    Ranch Hand
    Posts: 362
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    David, if you make the inner class Controller no longer inner then line 32 ( doSomething.setText("Data Updated"); ) will not be valid. An advantage of inner classes is the ability to access the containing class' properties directly. Just keep that in mind.
    reply
      Bookmark Topic Watch Topic
    • New Topic