This week's book giveaway is in the Java in General forum.
We're giving away four copies of Event Streams in Action and have Alexander Dean & Valentin Crettaz on-line!
See this thread for details.
Win a copy of Event Streams in Action this week in the Java in General forum!
  • 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Knute Snortum
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Ron McLeod
  • Piet Souris
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Ganesh Patekar

When to mock in unit tests?

 
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When writing unit tests, at what level do I create mocks vs actual objects? In the code below, I am testing MyAuthorizer.methodToTest. Is it appropriate to mock MyService.methodOfInterest to return the expected value given the inputs (User, Project)? And separate unit tests for MyService.methodOfInterest handle the testing of that method. Or should I call myService.methodOfInterest in the MyAuthorizer.methodToTest test, passing the appropriate params?


 
author & internet detective
Posts: 39392
763
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There isn't a right or wrong here. It depends on how tightly coupled the code is an whether MyService makes external calls.

In this case, I think you'd want to mock out the service when testing authorizer. Because authorizer sounds pretty distinct so it would only matter that service was called and not what it does.
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if a class makes external calls, does that mean that I would want to mock it?
 
Jeanne Boyarsky
author & internet detective
Posts: 39392
763
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Definitely. Because that greatly increases the complexity and makes your tests brittle if you don't mock it out
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks for the advice!
 
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would not jump to any conclusions regarding mocks in this case. The code OP has shown does not give us enough context. Is that essentially what MyAuthorizer.methodToTest does, just validate the User object to make sure it isn't null before passing on the parameters to the service method? What does the test look like? What are you asserting in the test? That MyAuthorizer.methodToTest method looks very anemic -- there's nothing that you're showing it doing that couldn't just be done in the service class.  If you did that, MyAuthorizer has no reason to exist, unless it does other things besides this. Regardless, it's potentially one thing less that you can make MyAuthorizer responsible for.  There may be good reasons for or against this but again, we haven't really seen enough to say one way or another.

I would look at the test code first and see what kind of assertions it's making about the behavior of MyAuthorizer.methodToTest() before I'd make a judgement on whether mocking is appropriate. Maybe the doubt as to the propriety of mocking was in fact trying to tell you that your design itself needed to be refactored.

 
Jeanne Boyarsky
author & internet detective
Posts: 39392
763
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I would not jump to any conclusions regarding mocks in this case. The code OP has shown does not give us enough context.


Agreed. My "conclusion" came from the statement "if a class makes external calls, does that mean that I would want to mock it?"
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu, I always appreciate your feedback.

My actual methodToTest() looks like:



The projectService.isUserMemberOfProject loads the user.userProjects entity graph if loaded and looks for the passed in Project in the userProjects list.

does the userHasAccess method still look anemic? The reason I seperated the 2 methods is that I use projectService.isUserMemberOfProject when someone is trying to upload/modify a resource, and ProjectAuthorizer.userHasAccess when someone is trying to access a resource. isUserMemberOfProject was put in the projectService because it needs db access to possible load the user's projects.

Let me know what you think, as I'm always looking to improve my code.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One technique I use to explore other possible designs is to flip points of view / perspectives / approaches.

Looking at that code, I'd write tests to experiment with some alternative designs to see if they made more sense and made testing easier:

This might be a first cut at a test for Authorizer. It gives me an idea of the context in which the class will be used. That's why I've been asking to see the test you wrote involving this class. If I had a test like this, I'd think to myself, "Well, why do I even need all this service object at all? I can just set up the Authorizer to know what each user's access level is to whatever project. The service object doesn't need to get involved in the testing at this point since I'm only concerned with what the Authorizer object will do with the parameters its given. I'll test the interaction between the service and the Authorizer later, if I even need to do that."
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I'll test the interaction between the service and the Authorizer later, if I even need to do that."


The reason I'd question whether or not I'd even need to test the interaction between the ProjectService and the Authorizer is that I might find that I can reduce coupling by not even injecting an Authorizer into a ProjectService. What if I just have my Controller ask an Authorizer whether a User is allowed to do something with a Project? Then I can make the assumption in the ProjectService class that authorization has already been verified by the time it has been invoked to do something. That would remove one responsibility from the ProjectService object and put it somewhere else: a negotiation between the Controller and the Authorizer. If this approach makes it easier for me to write tests, that is my cue that this is probably a better design choice. If it's still difficult to test, then I'll look for other alternatives.

Like I was telling someone else this morning, I always leave room for the possibility that one of my early design decisions was not or is no longer the best one in the current context. Tests that are easy and make sense help me find where to stop tracking back over my past decisions. When the test code doesn't make sense anymore, that's my cue to start refactoring.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is why I like TDD so much. To me, the testing part isn't so much about verifying correctness of the solution but rather about seeing the suitability of my design choices in a certain context. Taken as a whole, my tests give me a sense for the nature of my design and how it all comes together, or not.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the example I gave above, I'd probably end up refactoring the test to be something like:

These tests would be in the AuthorizerTest class. Now the question of whether or not I should mock at all goes away.
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm going to make it a priority to read through some of the books you've suggested to me in the past. I think I need to become more versed in TDD.

Currently in my design, the ProjectService doesn't handle the authorizing. This is all done in the Controller. My ProjectService is an abstraction layer where any db communication happens (between and other *Service classes and with the ProjectRepository). However, to determine if the user is a member of a project, I need to call the ProjectService as I need db access.

You can see the tests I've wrote below... I think my testing skills are lacking a bit, that's why I've started working on them

 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
just realized all the test say unAuthorized/Authorized, should be unAuthenticated/Authenticated
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let's look at this code. There's a tacit relationship in it.

Line 18 says in part, "When a ProjectAuthorizer is created, its relationship to an existing ProjectService must also be established." I don't even know how to read what the significance of the APP_ROOT parameter is. This relationship between the ProjectAuthorizer and the ProjectService must be important and relevant somehow to the next line of code that invokes the ProjectAuthorizer.userHasAccess() method. What exactly that relationship is remains a mystery that this test code does not reveal. Tests should be more explicit about how classes become related.

Consider the example I gave:

A direct causal relationship can be readily seen in that test code: In order for isGranted() to return true, you first have to call grant(). The same explicitness can be seen in the test with revoke() called to set up the fixture and asserting that isGranted() returns false as a result.

Your test code may make sense to you because you have intimate knowledge of the inner workings of the design. It's not apparent to someone who was not involved making the design decisions that led to this code though. If you were TDD'ing in a pair or group, a good discussion with your mates might have made this clear.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rj Ewing wrote:just realized all the test say unAuthorized/Authorized, should be unAuthenticated/Authenticated


In that case, is there even a need to involve a project entity to check authentication?
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rj Ewing wrote:I'm going to make it a priority to read through some of the books you've suggested to me in the past. I think I need to become more versed in TDD.


One word of caution about that: make sure you understand the principles. A lot of people fail at TDD because they get caught up in the mechanics of the technique and lose sight of the underlying principles. TDD is a design technique so it's important to know design principles. I'd advise you to read Understanding the Four Rules of Simple Design by Corey Haines. I think this is the best book about TDD that isn't all about TDD.

I always go back to my martial arts analogies. I study Aikido but I don't let myself get too caught up in the intricacies of Aikido techniques. I'm always looking for principles behind the techniques: balance, centeredness, breathing, non-resistance, etc. When you understand those principles, you start to see them manifested in other martial arts like Wing Chun and Tai Chi and you start to understand that specific techniques are just different ways of applying the principles.  To me, TDD is just another way of applying common design principles. I just happen to enjoy doing TDD more than other techniques, just as I enjoy practicing Aikido more than I do Tai Chi, although I still wish I could find a good Wing Chun school in my area. I hope that makes sense.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One that note, the example I gave for an alternative design is just that, an example. Don't get caught up in the details of my example. The more important point, the principle I'm trying to demonstrate, is that of expressiveness/coherence/cohesiveness. The test code should be expressive and coherent and it should lead you to a more expressive and coherent design and API. You may end up with a more coherent version of the same basic design or something that's entirely different from what we've discussed so far but more coherent in the context of your problem domain.
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I don't even know how to read what the significance of the APP_ROOT parameter is.



This is a hack that can't currently be worked around. I haven't gotten the okay to spend the time to fix it.

Junilu Lacar wrote:Tests should be more explicit about how classes become related.



This makes sense to me.

The basic logic of the projectAuthorizer goes:

1. all users have access if the project is public.
2. only users that are a member of the project have access if the project is private

If I didn't pass the projectService into the ProjectAuthorizer, I would be forced to load the projectMembers entity graph (currently lazily loaded) every time I used the ProjectAuthorizer. As there is a good chance the project is public (therefore anyone has read access), it seems to me that it makes sense to only load the projectMembers graph if the project is private.

Junilu Lacar wrote:A direct causal relationship can be readily seen in that test code: In order for isGranted() to return true, you first have to call grant().


I understand the benefit of having a direct causal relationship, but I do I go about showing this when the information to determine access is stored with the Project in the db? The public boolean, and the list of members. My current needs aren't to grant and revoke access, I just need to check if the project administrator has added the user as a project member.

Junilu Lacar wrote:If you were TDD'ing in a pair or group, a good discussion with your mates might have made this clear.



I would love to do this! However I'm basically the only on working on this project. But man would it be awesome to work with someone with more programming knowledge! For now, I do my best trying to learn on my own.

Thanks again, I really appreciate the in depth responses
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Rj Ewing wrote:just realized all the test say unAuthorized/Authorized, should be unAuthenticated/Authenticated


In that case, is there even a need to involve a project entity to check authentication?



ya, basically check if an authenticated user is authorized to access a project, another test if an unAuthenticated user is authorized to access a project
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Take this snippet of test code, for example:

These are the kind of things I'd imagine would come up in a good TDD discussion about this test code:

Line 64 gives a little more context about the relationship between a ProjectService and a ProjectAuthorizer. Line 64 says, "I'm expecting the authorizer to ask the service if the given user has access to the given project."

Why have such a circuitous conversation between objects though? Doesn't this now imply that the Project object has knowledge about its own security restrictions? Does the call to projectService.isUserMemberOfProject() lead us to write code that breaks the encapsulation of the Project object? Why is the parameter list to that method like that then? Do we really want the Project class to have knowledge of users' access rights to it?

Shouldn't project authorization responsibilities be assigned to the ProjectAuthorizer? Wouldn't it make more sense to encapsulate the information needed to make that determination in the ProjectAuthorizer instead? Then why do we need to involve the ProjectService in this conversation at all?
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Over the years, I have found that loose coupling is a very important characteristic of a good design. The fewer dependencies and middle men you have in your design, the more direct conversations objects can have with other objects, the more you limit the scope of knowledge about internal implementations, the more loosely coupled your designs tend to be.

At some level, that detailed knowledge needs to come out but you have to be aware of the smell that mocking gives off: Mocking exposes detailed knowledge about internal interactions. If you're trying to write high-level test code that should reveal intent and API usage rather than implementation details, then mocking is a big red flag.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another warning sign for me: Some of those tests set up expectations for the mock ProjectService while others don't. Yet, the ProjectAuthorizer constructor called in all the test methods is the same: it's the one that takes a ProjectService as a parameter. That makes me wonder the consistency of the design and whether these tests are all the same level of abstraction. When taken as a whole, you start to see inconsistencies in the way the test fixtures are set up and used. Those inconsistencies make the test code less coherent and thus call into question the coherence of the design of the production code itself.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rj Ewing wrote:Currently in my design, the ProjectService doesn't handle the authorizing. This is all done in the Controller. My ProjectService is an abstraction layer where any db communication happens (between and other *Service classes and with the ProjectRepository). However, to determine if the user is a member of a project, I need to call the ProjectService as I need db access.


All this raises a series of questions. Why is authorizing done in the Controller? Did you mean initiated/coordinated instead? Authorizing seems more like a responsibility of something like ProjectAuthorizer, doesn't it?  Why does a Service layer object like ProjectService have to be called to get to DB information about project authorization? Shouldn't information about authorization go through something like an AuthorizationRepository instead? Do you need to call the ProjectService because it makes more sense to go through a ProjectService or because the design just happens to be like that right now? Would the design make more sense if we cut the ProjectService out of the picture, at least when it comes to authorization of the user?

You can see the tests I've wrote below... I think my testing skills are lacking a bit


The tests suggest you should work on understanding design principles and recognizing design smells more.
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:
All this raises a series of questions. Why is authorizing done in the Controller? Did you mean initiated/coordinated instead? Authorizing seems more like a responsibility of something like ProjectAuthorizer, doesn't it?  Why does a Service layer object like ProjectService have to be called to get to DB information about project authorization? Shouldn't information about authorization go through something like an AuthorizationRepository instead? Do you need to call the ProjectService because it makes more sense to go through a ProjectService or because the design just happens to be like that right now? Would the design make more sense if we cut the ProjectService out of the picture, at least when it comes to authorization of the user?



I agree that it doesn't make sense for the project to know about the authorization of the user, but why would it not know about which members are users of the project? It seems like it would make more sense for the project to know what it members are, and not the authorizer. The authorizer would just need to use the member information, along with other information to grant authorization to a user.

If the user knows what projects it is a member of, and the project know which users are member, I think this would be a code smell, based on DRY or duplicate knowledge. Is that correct?

Junilu Lacar wrote:The tests suggest you should work on understanding design principles and recognizing design smells more.



I read through the 4 rules of simple design today. It was interesting. Some of it I've heard before, however I definitely need to keep referencing the design patterns until they become engrained. Do you have suggestions on ways to better understand common design patterns? I was thinking it might be helpful to create a checklist that I could constantly refer to while coding until they become second nature.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rj Ewing wrote:If the user knows what projects it is a member of, and the project know which users are member, I think this would be a code smell, based on DRY or duplicate knowledge. Is that correct?


I'd have to examine some code to say for sure but it might. In these cases, it's usually a good idea to factor that knowledge out to something that falls under what Peter Coad calls a Moment-Interval Archetype in his writings about Modeling in Color. I don't know many people who have read his book about this but I have found those four archetypes quite useful on occasion.

I read through the 4 rules of simple design today. It was interesting. Some of it I've heard before, however I definitely need to keep referencing the design patterns until they become engrained. Do you have suggestions on ways to better understand common design patterns? I was thinking it might be helpful to create a checklist that I could constantly refer to while coding until they become second nature.


I would suggest that you just try to become familiar with the contexts in which common design patterns apply. Then I suggest you read Joshua Kerievsky's Refactoring to Patterns book. His advice is to not go around with a bunch of patterns in your head looking for problems that you can apply them to.  A more sane approach to design patterns is to be familiar with a bunch of useful ones, then when you see a problem and recognize, "Hey, this looks like a situation where the SoAndSo Pattern can help..." that's when you pull out the pattern and start refactoring your design towards it. After you've done that a few times, you will start to subconsciously recognize the elements of context and instinctively write code that is already close to the pattern that applies. That takes a while but with practice, it becomes almost second nature. See Shu Ha Ri for an idea of how that progression happens.

Also, there's a big difference between design patterns and design principles; make sure you know what the difference is.
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:
I'd have to examine some code to say for sure but it might. In these cases, it's usually a good idea to factor that knowledge out to something that falls under what Peter Coad calls a Moment-Interval Archetype in his writings about Modeling in Color.[\quote]

I'll have to read about the Moment-Interval Archetype.

Junilu Lacar wrote:Also, there's a big difference between design patterns and design principles; make sure you know what the difference is.


Ya, I meant principles. I would think I would be better off getting the principles down first, then start looking at patterns.

 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rj Ewing wrote:I agree that it doesn't make sense for the project to know about the authorization of the user, but why would it not know about which members are users of the project? It seems like it would make more sense for the project to know what it members are, and not the authorizer. The authorizer would just need to use the member information, along with other information to grant authorization to a user.


You have to watch out for this kind of thinking; it's often a trap. Object-orientation is not about anthropomorphism and mimicking real-world objects. That's just a cognitive device that useful to some extent. Taken too far, however, it can often lead to over-complex designs that have too much coupling and overlapping of responsibilities. Again, go back to principles and try not to violate the Single Responsibility Principle.

The problem is that real-world objects are complex and they have multiple facets. A Person can be an Employee or Manager or Coach or Athelete or Director or Actor or Pilot or Passenger or Parent or ... you get the idea. All these are Roles, one of Coad's four archetypes. In the real world, any instance of a person can take on multiple roles, sometimes taking on multiple roles at the same time, like Teacher and Student or Husband and Father. In the world of object-oriented programming and design, however, that's often not a good idea. Most of the time, it's better to assign different aspects of the real-world idea to different classes/objects, each one with their own specific responsibility and focus/specialization.  That's what I'd do with projects, authorization, and users. What aspect about a User does a Project really have to know about in the context of the current problem domain? Does that really include authorization? Would it be better to separate the concern of authorization into a Security Module for instance, where a ProjectAuthorizer resides and presides over decisions that have to do with project and user relationships as it pertains to securing the application? If you do that, the Project and User classes can focus on the relationships and behaviors that are directly related to the problem domain.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Separation of Concerns and the Single Responsibility Principle are two key concepts you really have to master. They are very helpful in keeping you from falling into the trap of trying to model your program objects too closely to real-world objects.
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:Would it be better to separate the concern of authorization into a Security Module for instance, where a ProjectAuthorizer resides and presides over decisions that have to do with project and user relationships as it pertains to securing the application? If you do that, the Project and User classes can focus on the relationships and behaviors that are directly related to the problem domain.


This is actually a very common design approach. Study Spring Security and you'll see how it's focused on only certain aspects of the idea of a "User"; it doesn't try to be all encompassing of what a User object can be in all applications but only is concerned with aspects of a User that have to do with application security.
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I'd have to examine some code to say for sure but it might. In these cases, it's usually a good idea to factor that knowledge out to something that falls under what Peter Coad calls a Moment-Interval Archetype in his writings about Modeling in Color.



After reading that article, it brought up some questions. The moment-interval class would be something like a ProjectMembers class? This is because members can be added/removed over time? I assume there wouldn't be a MI-Detail class involved and the ProjectMembers class would keep track of the User objects?

Then would it be a good idea to have only the Project be aware of it members and the User is not aware of their Projects?
 
Junilu Lacar
Sheriff
Posts: 13554
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rj Ewing wrote:Then would it be a good idea to have only the Project be aware of it members and the User is not aware of their Projects?


The answer depends entirely on the context. I don't think that having one know of its relationship with the other is necessarily a bad idea. You have to separate your consideration of the logical relationship and the mechanics of representing that relationship. Creating an M-I class that represents the Project-User relationship is more about normalization and not duplicating knowledge.  That is, a Project object might have a reference to a ProjectTeam object and a User object might reference that same ProjectTeam object. In a logical sense, both the Project and User have a way of finding out about each other but mechanically, it's through the ProjectTeam object that they can obtain that knowledge.

Does that make sense?
 
Rj Ewing
Ranch Hand
Posts: 120
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:Does that make sense?



sure does. Thanks
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!