This week's giveaway is in the Beginning Java forum.
We're giving away four copies of Bad Programming Practices 101 (e-book) and have Karl Beecher on-line!
See this thread for details.
Win a copy of Bad Programming Practices 101 (e-book) this week in the Beginning Java forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Design pattern: actor-role  RSS feed

 
Greenhorn
Posts: 6
1
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone, I've asked the following question on javaprogrammingforums.com - apologies if cross-forum posting is frowned upon, but no one there has replied.

I'm new to design patterns and currently trying to create a simple example of the following actor-role pattern (sometimes known as player-role pattern):

I have no problems creating the classes and inheritance relationships. My confusion is, let's say I want to create a new Student object who has the role of undergraduate. When I construct the Student object, how/where do I pass the information that I want the Student to be a postgraduate? Let's say this is my Student class:



and let's say my UnderGraduate class is this:



If I construct a new Student object, I don't understand how to set the level role as undergraduate:



I'm not sure if it's too much to ask, but if anyone could show me the Java code of the above Student/level role/attendance role example, I'd be so grateful. I've genuinely searched hard for a simple Java actor-role example and I'm surprised very little has come back (I can find good Java examples for just about every other single design pattern, but this one is elusive).

Many thanks, I really appreciate your time.

 
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is all right to post on multiple fora as long as you inform people of it. Don't post the same question twice on the same forum, however.

What do the numbers 1...1 mean? Who says there is a one‑to‑one relationship between students and courses? I used to have a 1...n relationship with courses at different levels. Also, is that UML diagram intended for use creating objects or for tables in a database? It looks rather like a database schema to me, and database schemata don't usually map easily and directly to objects.
I think you have been given a design, and you design from the centre towards the periphery. And I think it is easier to code from periphery to centre. I suggest you write down in simple words how you would describe the problem. Is an undergraduate a special kind of student? Or is an undergraduate a student who has a special kind of status? Is a full‑time student a special kind of student, or an ordinary student with a special status. The shapes of the arrows in your UML suggest that there is full‑time status and part‑time status and both are subclasses of status, but is that correct? Is full‑time status an instance of status?

This question is too difficult for this forum, so I shall move it.
 
Lyle Christine
Greenhorn
Posts: 6
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1....1 means a student can only have one type of AttendanceRole at a time, and only one LevelRole at a time. For example, a student can not be both full-time and part-time at the same time. This diagram is nothing to do with databases, it's purely for creating objects; and it doesn't mention courses - indeed you are correct that if this diagram had a courses class, that would be a 1...n relationship.

Here's a good description of what problem the Player-Role design pattern solves: http://ece.eng.umanitoba.ca/undergraduate/ECE3740/Lecture%20Slides/L36PlayerRoleDesignPattern.pdf which might be clearer if my explanation has confused everyone.

Cheers.
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you; the link does apply additional restrictions, e.g. that a student must be undergraduate or postgraduate and not both, what in classical logic you could write as UG ⊕ PG, and you would require that evaluate to true. Similarly an animal is living on dry land or in water but not both. A student can change from UG to PG and an animal can move from dry land to water or vice versa, as do frogs.
That description does constrain your design; go back to the animals. Is DryLand a class or is it an instance of Habitat; is Water a class or is it an instance of Habitat? Are there Food classes with Meat, Grass and Anything subclasses, or is there a Food class with Meat, Grass and Anything instances? I think the same answer will apply to UG/PG status and FT/PT.
The fact that habitat is described on those slides as a “property” of an animal suggests you would want a habitat object as a field in tthe animal class.

Do you know how to create a class with a predetermined number of instances? That is a pretty easy task.
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The slide you showed headed “Anti‑Pattern 2” appears to show a LandCarnivore inheriting from a Carnivore and a LandAnimal; that is impossible to implement in Java®.
 
Lyle Christine
Greenhorn
Posts: 6
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

The fact that habitat is described on those slides as a “property” of an animal suggests you would want a habitat object as a field in the animal class.



Yeah, totally - that's what I was thinking. And if you look back up the code I wrote for the Student class, I have included the LevelRole as a field:



I think the crux of my question is, how do I set this variable to be undergraduate or postgraduate? At first I thought I this would be incorporated into the constructor of the Student class, but I think that must be wrong. Perhaps the approach would be to have a setLevelRole() method in the Student class which you would have to call immediately after a Student object is created? e.g.



But would the parameter be a String? Or would I first create an Undergraduate object, and then pass that Undergraduate object as the parameter?

Thanks again for taking a look at this, I appreciate your feedback.
 
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From the problem you describe, I think of LevelRole and AttendanceRole should be part of Student Class as attributes.

LevelRole can be extended by UG class and PG Class.

Similarly attentancelevel can be extended by FullTime class and PartTime class.

Note: if the behaviour doesnt change based on the levelrole/attendencerole then think about using simple ENUM
 
Lyle Christine
Greenhorn
Posts: 6
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lakshman Arun wrote:From the problem you describe, I think of LevelRole and AttendanceRole should be part of Student Class as attributes.

LevelRole can be extended by UG class and PG Class.

Similarly attentancelevel can be extended by FullTime class and PartTime class.

Note: if the behaviour doesnt change based on the levelrole/attendencerole then think about using simple ENUM



Thanks for the reply Lakshman - if you take a look at the post above your reply, my confusion is how would set theLevelRole and AttendanceRole attributes. Is my setter method suggestion correct, and if so, what do I pass as the parameter in the setter method?

 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lakshman Arun wrote:. . . LevelRole can be extended by UG class and PG Class. . . .

Have you tried that? What is going to happen when you have this sort of pseudocode?How are you going to tell from the field what the student's status is? Please show a brief implementation.
 
Lakshman Arun
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Lakshman Arun
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lyle Christine wrote:

Lakshman Arun wrote:From the problem you describe, I think of LevelRole and AttendanceRole should be part of Student Class as attributes.

LevelRole can be extended by UG class and PG Class.

Similarly attentancelevel can be extended by FullTime class and PartTime class.

Note: if the behaviour doesnt change based on the levelrole/attendencerole then think about using simple ENUM



Thanks for the reply Lakshman - if you take a look at the post above your reply, my confusion is how would set theLevelRole and AttendanceRole attributes. Is my setter method suggestion correct, and if so, what do I pass as the parameter in the setter method?



A student can be either UG or PG or in other words those are mandatory attributes without setting that , Student Object is not complete.

So should be passed thru constructor
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is different from what you said before, so you have obviously given up on the idea of PartTime extends Attendance. If you had that, you would have something like this:-. . . which I hope shows the problem inherent in the inheritance option.
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lakshman Arun wrote:. . . mandatory attributes without setting that , Student Object is not complete.

So should be passed thru constructor

. . . and using something like Objects#requireNonNull().
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you put the something() and somethingDifferent() methods into the two Attendance objects, but with the same name? That would be an even more OO solution?
 
Lakshman Arun
Ranch Hand
Posts: 52
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can be added methods in enum LevelRole as abstract and in each type UG/PG override it. I got your point.
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lakshman Arun wrote:Can be added methods in enum LevelRole as abstract and in each type UG/PG override it. I got your point.

Good, but don't call UG and PG types; they are instances. Even if they have different implementations of a method.
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lyle Christine wrote:. . . At first I thought I this would be incorporated into the constructor of the Student class, . . . have a setLevelRole() method in the Student class which you would have to call immediately after a Student object is created?  . . .

If you set the level in the constructor, you can be sure it will be set. As you will see from this discussion, also today, there are ways to avoid null being passed. If you have a method, there is no way you can “make” users call that method, so there is a risk of that field not being set and the object being in an inconsistent state. In fact, most users take it for granted that the object will be in a consistent state after the constructor completes and won't look for methods to be called afterwards.

A nice feature of an enum is that it is impossible to pass a non‑null argument outwith the permissible range
 
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's my problem with this kind of instruction about patterns: There's no apparent context. A design is only good if it fits the context in which it is applied and solves specific problems. Without a problem to solve, coming up with a design becomes a theoretical exercise that can go on and on forever. There have to be bounds to curb your imagination and those bounds are defined by the problem that needs to be solved.

Patterns are meant to provide clean, maintainable solutions to a problem in a certain context. OOP is not about defining relationships between objects in the real world. It's really about assigning responsibilities properly so that you can keep actions and the data that those actions operate upon together. Encapsulation, information hiding, and polymorphism are OOP mechanisms that help us create abstract representations of these responsibility-information relationships.

So, my first question would be this: What problem(s) are you trying to solve with this design?

Possible answers to this question are:
1. I want to write a program that will track student enrollment
2. I want to know how many undergraduate students are enrolled.
3. I want to know how many postgraduate students are enrolled.
4. I want to know which students have paid their fees

Only when I have these end goals in mind would I set out to design an object hierarchy that would help me represent the relationships, behaviors, and data/information needed to achieve the goals cleanly and clearly.
 
Junilu Lacar
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let's take a look at AntiPattern 1 in the slides. It says:


* Problem:
  - Two or more objects are required if the animal needs to play different
roles, like aquatic and land carnivore, which is not good OO design.


Was it clearly explained to you why this is not a good OO design? What problems would this design create? Why are they problems? What do they prevent you from doing or make it difficult to do?

This is why I prefer to learn patterns in a "backwards" fashion. I start with code that doesn't explicitly follow any design pattern. I look for problems in the code. I identify what the design prevents me from doing or makes it difficult for me to do. Then I find out if there's a pattern that can be applied in that context. Then I slowly refactor the code, move things around, change the design little by little, so that it eventually follows the known pattern.
 
Junilu Lacar
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lyle Christine wrote:and let's say my UnderGraduate class is this:


This is the kind of code you get when you are just given a pattern to follow without a specific problem in mind that you want to solve. It's like trying to get all dressed up without knowing exactly where you're going. How do you know you're dressed appropriately then? Same thing is happening with this code. How do you know this is going to help you solve a problem? Are you trying to design so that you can solve any problem? That won't work. You'll just keep thrashing about, adding more and more complexity to the design with each hypothetical situation your imagination comes up with.

Why would an UndergraduateStudent extend LevelRole? Is it a specialization of LevelRole? Doesn't seem like it. If anything, my first inclination would be to define an enum:

If the problem is to be able to tell if the Student is an undergrad or post-grad level student, that's all I really need. Why should I add more complexity than that?
 
Campbell Ritchie
Marshal
Posts: 59386
187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . Then I slowly refactor the code, move things around, change the design little by little, so that it eventually follows the known pattern.

I know a slightly different version of that process.

. . . Then I slowly refactor the code, move things around, change the design little by little, until I realise it is following a pattern.



We all seem to be converging on the enum as a nice solution.
OP: Since this discussion is well beyond a beginning level, find the Wayback Machine, and get it to search for the Java™ Tutorials from the year 2005. Find the section about enums; they might have used an older name: “enumerated types”. Find the bit about “glorified integers”. Look at the current edition, too. Cay Horstmann says in his big book that C, C++ and C# still use ints as enum elements. If you go through sources like Effective Java by Joshua Bloch (in the 2nd edition start page 147), you can see some of the problems you can get if you use integers instead of enum objects.
 
Junilu Lacar
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I know a slightly different version of that process

. . . Then I slowly refactor the code, move things around, change the design little by little, until I realise it is following a pattern.


Yes, that's often the case, too. The key is recognition. You have to already know about a pattern in order to realize (or realise, if you prefer ) that what you have follows it. Otherwise, you just have to keep browsing through catalogs of patterns and see if what you have matches anything you don't already know about.

It's a bit like how we recognize when someone like OP is struggling to learn and we explain to them why that is because we've seen the pattern (or anti-pattern as the case may be) before. When we have a good idea of what the problem is and why it's a problem, then we can draw on our experience to apply a solution that worked for us in the past. That's all patterns really are. The first slide even says that.
 
Junilu Lacar
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think there's a fundamental conceptual flaw in the example given by OP. Neither Attendance (full-time / part-time) nor Level (undergrad / postgrad) seem to fit the concept of "Role" - they are temporal states whose values are mutually exclusive. That is, you can't be both full-time and part-time and you can't be both undergrad and postgrad. It's either/or with these. A "role" entails behaviors and privileges and an object can take on multiple roles at the same time.

This pattern may also be taken with the Interface Segregation Principle (ISP) so that you can write something like this:

The OOP principle of Polymorphism plays a role in all this. (pun intended)
 
Junilu Lacar
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
See a working example here: https://repl.it/@jlacar/ActorRoleExample

What might help you understand the benefits of adding the concept of "role" to the design is if you tried to write the same program without the Athlete and Scholar interfaces. Exercise left to OP and anyone else interested in doing it.

Additionally, the example works but the astute observer will recognize a smell in the implementation that hints at potential problems with the design. I'll also leave that as an exercise for OP and anyone else to figure out what the smell is and the kind of problems it might hint at.
 
Junilu Lacar
Sheriff
Posts: 12072
197
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another example of where the Actor-Role pattern might be applicable is where you have Employee objects and want to treat them as either Manager or Subordinate. An Employee can be a Manager and Subordinate at the same time. Which role the Employee takes on and used to interact with it just depends on the context.
 
Saloon Keeper
Posts: 1691
68
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mooo!

Your posting was just mentioned in the June 2018 CodeRanch Journal and for that you get a cow.
 
Ranch Hand
Posts: 104
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lyle Christine wrote:Hi everyone, I've asked the following question on javaprogrammingforums.com - apologies if cross-forum posting is frowned upon, but no one there has replied.

I'm new to design patterns and currently trying to create a simple example of the following actor-role pattern (sometimes known as player-role pattern):



Hey Lyle, what tool or IDE are you using for modelling the UDM ?



 
These are the worst of times and these are the best of times. And this is the best tiny ad:
Why should you try IntelliJ IDEA ?
https://coderanch.com/wiki/696337/IntelliJ-IDEA
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!