What design patterns are available for Data Classes in Java? - java

I have a complex class in Java whose responsibility it to mainly store Data. I was wondering if there are any design patterns available to guide such use cases.
To be more specific, the class is something which records the overall performance of a student per semester.
Class StudentReport{
cgpa = 3.1;
Set <SubjectReport> perSubjectReportSet;
overallFeedback = "..."
...
}
Class SubjectReport{
subjectName = "Subject_A";
gpa = 2.4;
// Test Details
test = Pass;
testQuestionAnsweredCount = 8;
testQuestionsCount = 10;
testFeedback = None; // Feedback if FAIL
// Assignment Details
assignment = Pass;
...
//Exam Details
finalExam = Fail;
examQuestionAnsweredCount = 5;
examCorrectlyAnsweredQuestionCount = 2;
examQuestionsCount = 10;
examFeedback = "Blah Blah OOP" // Feedback if FAIL
}

A design pattern to encapsulate class attributes, is the private class data pattern. It seeks to reduce the visibility of the class attributes

The description: "I have a complex class in Java whose responsibility it to mainly store Data" is a bit to general, does not every object store data combined with behavior?
You're example code does show a design: the composition pattern.

Related

Filling an Object with multiple variables in Java?

Is it possible to add multiple attributes to an Object attribute in a class? For example, I have a queue for a bar where you can order drinks by providing: drink name, drink quantity and table number. Do I have to create a variable for each or can I store multiple attributes in a single Object foo? Ty!
You will have to define a class (i.e. class DrinkOrder) and enumerate the fields of that class -- i.e. a String drinkName, int quantity, String tableIdentifier, etc.). Then when you instantiate that class into an instance, each instance can hold as many values as you have defined fields.
// Should protect the fields with accessors, implement Comparable, etc.
public class DrinkOrder {
public String drinkName;
public int quantity;
}
// Somewhere else
DrinkOrder alex = new DrinkOrder();
alex.drinkName = "Beer";
alex.quantity = 1;
DrinkOrder andy = new DrinkOrder();
andy.drinkName = "Amaro Averna";
andy.quantity = 1;
System.out.println("Andy wants " + andy.quantity + " " + andy.drinkName); // => Andy wants 1 Amaro Averna
You should take advantage of Java training (plentiful on the web) such as the original Java Tutorials or Josh Bloch's "Effective Java" or Kathy Sierra's "Head First Java"

Are there any tools to create dummy objects to use for JUnit test cases?

I am writing JUnit test cases to test CRUD operations in DAO classes. It is pretty much boilerplate code and bulk of it is to create the test object and assign dummy values to the instance variables. Are there any tools in Java to create an object and assign dummy values based on the declared type?
I don't want to use JMock or Mockito as I need to interact with the database and test that the CRUD operations are successful.
A bit late to the party, but lorem-ipsum-objects can generate test data of any type for you on the fly.
Here's the basic usage example from the main page:
Basic usage:
LoremIpsumObjectCreator creator = new LoremIpsumObjectCreator();
creator.createLoremIpsumObject(clazz);
Usage with custom factories:
ClassBindings classBindings = new ClassBindings(); // or:
ClassBindings classBindings = ClassBindings.defaultBindings(); // defaults for collections
classBindings.add(List.class, new ClassBasedFactory<>(ArrayList.class));
LoremIpsumObjectCreator creator = new LoremIpsumObjectCreator(classBindings);
creator.createLoremIpsumObject(clazz);
To apply this to the example mentioned in the currently accepted answer:
Foo foo = new Foo();
foo.setIntValue(creator.createLoremIpsumObject(int.class));
foo.setStringValue(creator.createLoremIpsumObject(String.class));
Or even better:
Foo foo = creator.createLoremIpsumObject(Foo.class);
I don't know a tool which will create a mock object for you and fill it automatically with some fuzzy data.
But maybe the following approach would be close to what you want to achieve.
pseudo code
Foo foo = new Foo();
foo.setIntValue(generateInt());
foo.setStringValue(generateString(20));
...
// store the record in the database
// retrieve the record from the database
// check if the retrieved values are equal to the values in `foo`
If this is what you want to achieve you might have a look for QuickCheck
The goal of QuickCheck is to replace manually picked values with generated values. A QuickCheck-based test tries to cover the laws of a domain whereas classical testing can only test the validity for distinct values.
Basically, QuickCheck is about generators of data. The QuickCheck runner method is just a fancy for loop implementation. QuickCheck can help in scenarios where whole classes of test cases have to be tested and it is not feasible to write tests for all distinct test scenarios.
So you could create your own Generator which provides instances of Foo already filled with fuzzy data. In combination with Junit Theories you would be close to your initial requirement.
An example for using Theories with a custom generator you can find here. The example was written for a similar library (junit-quickcheck). But it should demonstrate your the idea.
edit Roughly based on the junit-quickcheck example. It might look as in the following snippet.
import net.java.quickcheck.Generator;
import static net.java.quickcheck.generator.PrimitiveGenerators.characters;
public class MyCharacterGenerator implements Generator<String> {
private static final String LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
private static final String UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String NUMBERS = "0123456789";
private static final String SPECIAL_CHARS = ".-\\;:_#[]^/|}{";
private static final String ALL_MY_CHARS = LOWERCASE_CHARS
+ UPPERCASE_CHARS + NUMBERS + SPECIAL_CHARS;
public static final int CAPACITY = 40;
Generator<Character> characterGenerator = characters(ALL_MY_CHARS);
public String generate() {
StringBuilder sb = new StringBuilder(CAPACITY);
for (int i = 0; i < CAPACITY; i++) {
sb.append(characterGenerator.next());
}
return sb.toString();
}
#Override
public String next() {
return generate();
}
}
.
import net.java.quickcheck.Generator;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class MyCharacterGeneratorTest {
#Test
public void testStringGenerator() {
Generator<String> fuzzyString = new MyCharacterGenerator();
for (int i = 0; i < 10; i++) {
String fuzzy = fuzzyString.next();
System.out.println("fuzzy: " + fuzzy);
assertTrue(fuzzy.length() == MyCharacterGenerator.CAPACITY);
assertTrue(fuzzy.matches("[a-zA-Z0-9.\\-\\\\;:_#\\[\\]^/|}{]*"));
}
}
}
output
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running MyCharacterGeneratorTest
fuzzy: ;d|xrS|dFS3H#xZRnzE6N\.ly600{C#ll;de5:jN
fuzzy: UCZBO|QJ/6fLqBH9QwFpPcUK.Qa5hEgFR_3A1#;b
fuzzy: Jg}xD44_AFVqy\UKMehGPnV8xmKKy]dDXJsYIG9C
fuzzy: k-eN-Sf^eK.bqqn4PR2[93{wyzgwr_F_ktBGkTP}
fuzzy: 1UDChf3aWN0d/95#}K[W2|P]}.ePzKvRJMJtB0/Z
fuzzy: #J2}kMK#.uZY]smpKWZ;C4#p-Kp9}KUtan#oVLX9
fuzzy: goL8o5qz-Ynga:i;WqGhKTo^1itHqENXM3OrO||4
fuzzy: _\1ifR:ssplcdT9l\s{clV9ZozgCA^I67IF/|t0t
fuzzy: /FwL9nCuRcemqR2SP3|XG9ui5Y21K:r0Ys1XIz/3
fuzzy: 8U[Xk^e60JhGfLTMyGZ:Z;gn9UCXcUEu#wV\oJ7]
Maybe this lib could help you.
six2six/fixture-factory
I've already used it in some projects, including recent ones. It's very simple to use.
One thing I think is worth pointing out is that it seems to me that the lib has not been updated in a few years.

Enum with functions?

I saw the page:
I'm familiar with this SO question for creating enums in Python. However, I can't find an example anywhere of an enum that has functions.
I'm mainly a Java programmer.
I wrote this code in Java:
public enum Role {
SOLDIER(4),
DEMOMAN(2),
SCOUT(4),
MEDIC(2);
private final int maxPlayers;
private Role(int maxPlayers) {
this.maxPlayers = maxPlayers;
}
public int getMaxPlayers() { return maxPlayers; }
}
I tried to do the same in Python:
class Klass:
SCOUT = 1
SOLDIER = 2
DEMOMAN = 3
MEDIC = 4
#staticmethod
def maxPlayers(klass):
return {
Klass.SCOUT : 4,
Klass.SOLDIER : 4,
Klass.DEMOMAN : 2,
Klass.MEDIC : 2,
}[klass]
For some reason. I feel like I'm doing it wrong.
What is the best practice for associating functions to enums in Python?
I don't actually care if the suggested answer doesn't use an enum; I'm just trying to understand the best practice for implementing the above Java code in Python.
I'm willing to use this enum in the following:
class Players(dict):
def countKlass(self, klass):
count = len(filter(lambda x: x == klass, self.values()))
return count
Let's remember what enums in Java really are -- static final instances of a class. All they really are is just named constants.
Generally, python favors a looser (or if you prefer, more flexible) coding style than Java. Part of that is that there's no such thing as a constant, and part of it is trusting users of your code not to do crazy things. In that vein, you can get a similar effect to your java code by doing this:
class Role(object):
class RoleType(object):
def __init__(self, maxPlayers):
self.maxPlayers = maxPlayers
SOLDIER = RoleType(4)
DEMOMAN = RoleType(2)
SCOUT = RoleType(4)
MEDIC = RoleType(2)
Then you can access them like this
s = Role.SOLDIER
print s.maxPlayers # Prints 4
What this doesn't do is prevent users of your library from creating new roles. Doing so is slightly awkward, though, which should be a hint to the user that "they're doing it wrong".
newRole = Role.RoleType(22) # as an example
If you go this route, you just more or less have to live with that. If you favor using convention though, this generally won't be a problem. They can always just access the values you've defined.
If you are looking for best practices, typically you'd just make a dictionary.
klass = {'SCOUT':4,
'SOLDIER':4,
'DEMOMAN':2,
'MEDIC':2,}
print klass['MEDIC']
2
If you want this to be a class method you could say:
class Klass:
def maxPlayers(self, klass):
return {'SCOUT':4,
'SOLDIER':4,
'DEMOMAN':2,
'MEDIC':2,}[klass]
This is how you'd use it:
print Klass().maxPlayers('MEDIC')
2
Using the AutoEnum recipe, your code could look like this:
class Role(AutoEnum):
SCOUT = 4
SOLDIER = 4
DEMOMAN = 2
MEDIC = 2
def __init__(self, max_players):
self.max_players = max_players
And now you have the benefits of the new Python Enum (backported if you don't have 3.4):
--> Role.SCOUT
<Role.SCOUT: 3>
--> Role.SCOUT.max_players
4

Calling an Instance method when user inputs the instance name as a String

In a small project I am working on I've gotten stuck. The user enters a command that may be "xp Speed", my command handler class finds that it wants to the XP value of the Speed Instance. In this case it needs to return the value of Skill.Speed.currentXP back to the user.
Small Part of the program:
//Example Instance initialization there is over 40 of these
Skill Speed = (new SkillSpeed(Skills.SKILL_SPEED,Skills.SKILL_SPEED_MODIFIER));
//Constructor for skill class
public Skill(String skillName, double modifier) {
this.name = skillName;
this.minLevel = Skills.MIN_SKILL_LEVEL;
this.Modifier = 1f;
this.currentLevel = (int)calculateLevel();
this.currentXP = 1;
this.leaderboard = getCurrentLeaderboard();
this.ID = getNextID();
}
Now, theres one way i could do this. by having a switch statement with case value being the string entered. However I'm sure having 40+ cases in one switch statement must be avoidable. The other theory I have had is creating a array of all current instances then iterating through that list, finding if the user inputted string is equal to the name of that instance, then returning the instance itself. This is what I came up with:
//method inside another classs that attempts to return the appropriate skill Instance
public Skill getSkillFromName(String Name) {
for(int i = 0; i < Skill.SkillArray.length; i++) {
final String SkillName = Skill.SkillArray[i].getName();
if(SkillName.equalsIgnoreCase(Name)) {
return Skill.SkillArray[i];
}
}
return null;
}
So here's what I need help with:
Creating a array of all initialized instances
Creating the method that will return Skill."InsertRandomInstanceDependingOnUserInputHere".currentXP
Fixing any problems you see in the getSkillFromName() method
Or perhaps I have overlooked a far easier way of doing this, and you can help me with that.
Thanks for the help,
BigDaveNz
If the names of the skills excatly match method names you might find the aswer at "How do I invoke a Java method when given the method name as a string?".
For finding instances by name you can still use Map's.
You can use a Map for this. E.g.:
Map<String, Skill> skills = new HashMap<String, Skill>();
To insert the values you put the values into the Map:
skills.put(skill.getName(), skill);
To retrieve your skill you can get the skill by name:
Skill skill = skills.get(name);

How best to specify a Protobuf for use with Netty (preferably using the built-in protobuf support)

I'm specifying a protocol in protocol buffers. The transport layer is harnessing Netty's Protocol Buffers support - the significance being that Netty's ProtobufDecoder accepts one, and only one, type of MessageLite.
Now, I want to send a variety of different message types down this channel, each subtype having structured information associated with it. Protocol-buffers doesn't have an inheritance mechanism, so I'm using a kind of composition. I'm not sure if I am going about it the correct way.
My approach has been to categorise my different events with an enum, and encapsulate their differences using optional members. See my .proto below, I've simplified it for the sake of clarity.
My issue here is that the receiving code needs to make the association between EventType.ERROR and ErrorEventDetail. This just feels a little clumsy.
Simplified Events.proto:
package events;
option java_package = "com.example";
option java_outer_classname = "EventProtocol";
message Event {
enum EventType {
START = 0;
DELEGATE = 1;
ERROR = 2;
STOP = 3;
}
required events.Event.EventType event_type = 1 [default = START];
required int32 id = 2;
required int64 when = 3;
optional StartEventDetail start_event_detail = 4;
optional DelegateEventDetail delegate_event_detail = 5;
optional ErrorEventDetail error_event_detail = 6;
optional StopEventDetail stop_event_detail = 7;
}
message StartEventDetail {
required string object_name = 1;
}
message DelegateEventDetail {
required int32 object_id = 2;
required string task = 3;
}
message ErrorEventDetail {
required string text = 1;
required int32 error_code = 2;
optional Event cause = 3;
}
message StopEventDetail {
required int32 object_id = 2;
}
Is this optimal?
Would I be better off using extends somehow, or perhaps some other use of enum?
Or even, should I be creating a whole new OneToOneDecoder which can identify a message type by some kind of header? I could do this, but I'd rather not...
Thanks
Seems like you are pretty close / already using one of the Google's protobufs techniques which called Union Types
The gist is you have a dedicated type field, that you would "switch" on to know which message to get:
message OneMessage {
enum Type { FOO = 1; BAR = 2; BAZ = 3; }
// Identifies which field is filled in.
required Type type = 1;
// One of the following will be filled in.
optional Foo foo = 2;
optional Bar bar = 3;
optional Baz baz = 4;
}
where Foo, Bar and Baz are/could be defined in other files as separate messages. And you can switch on the type to get the actual payload (it's Scala, but you can do the same thing with Java's switch):
OneMessage.getType match {
case OneMessage.Type.FOO =>
val foo = OneMessage.getFoo
// do the processing
true
case OneMessage.Type.BAR =>
val bar = OneMessage.getBar
// do the processing
true
case OneMessage.Type.BAZ =>
val baz = OneMessage.getBaz
// do the processing
true
}
I originally solved the same problem using the extension mechanism, which I document here
But I found the code in Java required to deal with extensions was horribly ugly and verbose, so I switched to the Union method as described. The code is much cleaner as the generated Java code provides a way to get and build each message in one go.
I use two mechanisms for deciding which optional message to extract. I use the switch method also described in another Answer when performance is needed and I use a reflection method when performance is not an issue and I don't want to have to maintain a switch statement, I just create a handle(Message) for each message. An example of the reflection method is given below, in my case the java wrapper is a class called Commands, and is decoded by Netty for me. It first tries to find a handler that has the specific message as a parameter then if that fails it calls a method using the camel case name. For this to work the Enum must be the underscore name of the camel case message.
// Helper that stops me having to create a switch statement for every command
// Relies on the Cmd enum naming being uppercase version of the sub message field names
// Will call the appropriate handle(Message) method by reflection
// If it is a command with no arguments, therefore no sub message it
// constructs the method name from the camelcase of the command enum
private MessageLite invokeHandler(Commands.Command cmd) throws Exception {
Commands.Command.Cmd com= cmd.getCmd();
//String name= CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_UNDERSCORE, com.name());
String name= com.name().toLowerCase();
jlog.debug("invokeHandler() - Looking up {} from {}", name, com.name());
FieldDescriptor field= Commands.Command.getDescriptor().findFieldByName(name);
if(field != null) {
// if we have a matching field then extract it and call the handle method with that as a parameter
Object c = cmd.getField(field);
jlog.debug("invokeHandler() - {}\n{}", c.getClass().getCanonicalName(), c);
Method m = getClass().getDeclaredMethod("handle", String.class, c.getClass());
return (MessageLite) m.invoke(this, cmd.getUser(), c);
}
// else we call a method with the camelcase name of the Cmd, this is for commands that take no arguments other than the user
String methodName= "handle"+CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, com.name());
jlog.debug("invokeHandler() - using method: {}", methodName);
Method m = getClass().getDeclaredMethod(methodName, String.class);
return (MessageLite) m.invoke(this, cmd.getUser());
}
another approach is to use the extension mechanism that protobuf is supporting. I'm using this approach in the situations where the union type is too large.

Categories

Resources