I'm working on a school project that's like a simpler Youtube clone. I know one of the attributes of the Video and Playlist classes is a String code, which I can generate in whatever way I want, as long as it's always unique. So I tougth to use UUID (tough I'm fairly new to it), and thing is a video and a playlist can have the same code, because they are in different libraries in my code, so in theory I'd want 2 UUID generators, one for videos, one for playlists, so the codes can overlap that way.
I thought to make a singleton so there's no more generators than those I need, and I can always assure I get unique codes. Here's what I got.
import java.util.UUID;
public class CodeGenerator {
private static CodeGenerator singleInstance = null;
private UUID videoGen;
private UUID listGen;
private CodeGenerator() {
}
public static CodeGenerator getInstance() {
if (singleInstance == null)
singleInstance = new CodeGenerator();
return singleInstance;
}
public String getCodeVideo() {
return videoGen.randomUUID().toString();
}
public String getCodePlaylist() {
return listGen.randomUUID().toString();
}
}
But Eclipse is warning me in both of my gets that I should change this instance-reference to a static reference and I've never really been good at static stuff, and since I want to get rid of all these code warning for my project, can anyone tell me a fix that does what I'm looking for?
P.S I try to generate some codes in a Test class with the two different methods, and they always come out different and such as expected. The code is woring fine and I can see, but I'm scared down the line it might give me problems.
The problem isn't anything to do with your singleton - it's because you're calling UUID.randomUUID(), which is a static method, as if it were an instance method.
Here's a shorter example which I'd expect to give the same warning:
import java.util.UUID;
public class Test {
public static void main(String[] args) {
UUID ignored = null;
UUID generated = ignored.randomUUID();
}
}
Fundamentally, your fields are pointless - you're never assigning a value to them anyway.
It's not clear to me whether you expect getCodeVideo() to always return the same string for the lifetime of your process. If that is the case, you should change the code to something like:
import java.util.UUID;
public class CodeGenerator {
private static CodeGenerator singleInstance = new CodeGenerator();
private String video;
private String codePlayList;
private CodeGenerator() {
video = UUID.randomUUID().toString();
codePlayList = UUID.randomUUID().toString();
}
public static CodeGenerator getInstance() {
return singleInstance;
}
public String getCodeVideo() {
return video;
}
public String getCodePlayList() {
return codePlayList;
}
}
If you actually want to generate a new string each time you call the method, you don't need a singleton or anything like it:
import java.util.UUID;
public class CodeGenerator {
public static String generateCode() {
return UUID.randomUUID().toString();
}
}
Related
While creating JUnit test cases, it takes a long time to reconstruct objects for every single one of them and perform some operations that all my unit tests use.
Is there anyway I can make some objects in a test case that I can freely use in all of my tests without recreating them each time?
Thanks in advance!
A simple way of doing this is to create a private method that creates test objects. These can take in the parameters (the ones that need to change in the various test cases), or just provide a default object that you could in turn change. If the same objects are used in multiple tests, then a testdata-builder might be what you are looking for.
Say you have a class like this:
public class Something {
private String someString;
private Integer someInt;
public Something(final String someString, final Integer someInt) {
this.someString = someString;
this.someInt = someInt;
}
//getters and stuff
}
Then you can create a testdata builder like this:
public class SomethingBuilder {
private String someString;
private Integer someInt;
public SomethingBuilder() {
someString = "Some default value";
someInt = 42;
}
public SomethingBuilder withSomeString(final String someString) {
this.someString = someString;
return this;
}
public SomethingBuilder withSomeInt(final Integer someInt) {
this.someInt = someInt;
return this;
}
public Something build() {
final Something something = new Something(someString, someInt);
return something;
}
}
Then, creating test data becomes really simple, you can mutate the fields you different than your default values easily:
final Something something =
new SomethingBuilder().withSomeString("I want to override the default!").build();
Might seem like a bit of overkill for my small, example class, but if you have a central data class that appears in many tests, it will save you a lot of time and lines of code.
I wonder what is the best practice of having some global mapping in a Java application?
Say I have a text file with the mapping:
key1:value1
key2:value2
...
keyN:valueN
The file is huge, and both keys and values are arbitrary, so I can't really use Enum.
In the Java application I'm going to instantiate a bunch of classes with keys as the input (note that the code is more adequate in reality, just trying to put it abstract and simple):
for(int i = 0; i < 10000; i++) {
String key = magicallyGetArbitaryKey();
SomeClass someClass = new SomeClass(key);
//do stuff
}
and assign a property in the constructor based on the map lookup.
public class SomeClass {
private String value;
public void SomeClass(String key) {
this.value = getValue(key);
}
private String getValue() {
// what is the best way to implement this?
}
}
I want my code to be simple and, what is important, testable. And avoid using frameworks such as Spring.
This is what I came up with so far: create a Holder class, which is simply a wrapper around the HashMap with the additional methods for initialization:
class MappingHolder {
private Map<String, String> keyValueMap = new HashMap();
public MappingHolder(String filePath){
keyValueMap = ...; //init from the file
}
public MappingHolder(Map initMap) { //constructor useful for testing
keyValueMap = initMap;
}
public String get(String key) {
return keyValueMap.get(key);
}
It seems to be obvious that I want to have only one instance of the mapping.
As far as I can see the options are:
Have the MappingHolder#getValue as a static method
public class SomeClass {
...
private String getValue() {
return MappingHolder.getValue()
}
Have the MappingHolder#getValue as an instance method, but make
field of the type MappingHolder static in the SomeClass
public class SomeClass {
...
private static MappingHolder mappingHolder = new MappingHolder();
private String getValue() {
return mappingHolder.getValue();
}
Make the MapppingHolder a singleton.
public class SomeClass {
...
private MappingHolder mappingHolder = MappingHolder.getInstance();
private String getValue() {
return mappingHolder.getValue();
}
Neither of this seems to me testable, having just JUnit and Mockito and not leveraging some more powerful mocking frameworks. Though I sucks in testing and maybe I am wrong.
So it would be great if one could recommend the approach, either how to develop further my own, or better one which I may be missing. Thanks!
In my Android application I have a class which gives me static string values; something like this:
public class VehicleInfo {
public static String getVehicleEnginePower(boolean isNew) {
return isNew ? "1800CC" : "1600CC";
}
}
Now I have another category, so I will have to pass another Boolean, and I will get the value I need. However, these categories will keep on increasing. So I looked into the Open/Closed principle which looks promising for quick enhancement. To ensure this I will make the VehicleInfo class as an Interface and then I will have other classes implement VehicleInfo.
public interface VehicleInfo {
String getVehicleEnginePower();
}
public class NewVehicle implements VehicleInfo {
#Override
public String getVehicleEnginePower() {
return "1800CC";
}
}
and the other category classes will also be something like this. In this way I will have to add another class for all the new categories.
The question I wanted to ask is: is there a way that I can have single instance of this interface? Because in the whole application flow, a user will only be able to see one category until he switches to another category.
I don't want to instantiate these classes at multiple points. To clarify my question, I want to do something like this at the start of my application:
if (isNew) {
VehicleInfo vehicleInfor = new NewVehicle();
}
And in the whole application, whenever I call VehicleInfo.getVehicleEnginePower, it should always return engine power from the NewVehicle class.
Is something like this possible? Or am I just being silly and I will have to instantiate this interface on multiple points?
Maybe you need a singleton here
public class VehicleInfoManager {
private static VehicleInfoManager INSTANCE = new VehicleInfoManager();
private VehicleInfo currentVehicleInfo;
public static VehicleInfoManager getInstance() {
return INSTANCE;
}
public void setCurrentVehicleInfo(VehicleInfo info) {
this.currentVehicleInfo = info;
}
public String getVehicleEnginePower() {
return this.currentVehicleInfo.getVehicleEnginePower();
}
private VehicleInfoManager() {
// Constructor private by default
}
}
Then you can call it from everywhere like this
VehicleInfoManager.getInstance().getVehicleEnginePower()
//Or set current info like this
VehicleInfoManager.getInstance().setCurrentVehicleInfo(new NewVehicle())
Just be careful as currentVehicleInfo is null by default so you need to handle null pointer cases.
If I understand your question correctly.
My solution to this would be Enum
public enum VehicleEnginePower {
NEW ("1800CC"),
OLD ("1600CC"),
private final String name;
private Modes(String s) {
name = s;
}
public String toString() {
return this.name;
}
}
Then you can do
if (isNew) {
String powerOfEngine = VehicleEnginePower.NEW.toString();
}
I met a problem that is , when I use smart-json to convert java bean to JSON Object, then i found some boolean filed was lost, can some boby tell me why? the who codes are below:
package com.huoli.crawler.test;
import java.util.HashMap;
import java.util.Map;
import net.minidev.json.JSONObject;
public class MiniDevJSONTest {
public static void main(String[] args) {
MyBean mybean = new MyBean();
mybean.setReturn(true);
mybean.setArrivingAirportCode("dadsa");
Map<String, MyBean> map = new HashMap<>();
map.put("mybean", mybean);
// output smart-json:{"mybean":{"arrivingAirportCode":"dadsa"}}
// so where is isRetrun ??
System.out.println("smart-json:" + JSONObject.toJSONString(map));
}
}
class MyBean {
private boolean isReturn;
public boolean isReturn() {
return isReturn;
}
public void setReturn(boolean isReturn) {
this.isReturn = isReturn;
}
private String arrivingAirportCode;
public String getArrivingAirportCode() {
return arrivingAirportCode;
}
public void setArrivingAirportCode(String arrivingAirportCode) {
this.arrivingAirportCode = arrivingAirportCode;
}
}
My question is why the boolean field value was lost?
This is a getter versus "is"-er problem:
Modify your code in MyBean as I have the following snippet, and change the set of the boolean in your MiniDevJSONTest class to match "setIsReturn". You will now get the value you are looking for. Not very familiar with the minidev.json classes, but there appears to be reflection going on underneath the covers that is looking for the getter for your boolean value and not the "is"-er. Since it doesn't find it, it's like it's not there..
I have seen this kind of behavior before in other libraries. In some libraries the choice between whether the code seeks out the is-er or the getter changes based on whether or not the boolean you are looking for is the primitive or the fully boxed type.
public class MyBean {
private boolean isReturn;
private String arrivingAirportCode;
public boolean getIsReturn() {
return isReturn;
}
public void setIsReturn(boolean isReturn) {
this.isReturn = isReturn;
}
public String getArrivingAirportCode() {
return arrivingAirportCode;
}
public void setArrivingAirportCode(String arrivingAirportCode) {
this.arrivingAirportCode = arrivingAirportCode;
}
}
Just a little more followup:
In eclipse, when you establish a class attribute for a class, if you use the "create getter and setter" shortcut, you will see that it automatically creates a getter for a big B Boolean, and a is-er for the primitive type.
Many libraries use this standard when trying to figure out the reflection pattern for examining a class. However, it appears that the library you are using does not. I tested it, and it is expecting the getter whether the attribute is a boxed type or the primitive.
Let's say I have an abstract class (BaseThing). It has one required parameter ("base required") and one optional parameter ("base optional"). I have a concrete class that extends it (Thing). It also has one required parameter ("required") and one optional parameter ("optional"). So something like:
public abstract class BaseThing {
public static final String DEFAULT_BASE_OPTIONAL = "Default Base Optional";
private final String baseRequired;
private String baseOptional = DEFAULT_BASE_OPTIONAL;
protected BaseThing(final String theBaseRequired) {
this.baseRequired = theBaseRequired;
}
final void setBaseOptional(final String newVal) {
this.baseOptional = newVal;
}
public final void selfDescribe() {
System.out.println("Base Required: " + baseRequired);
System.out.println("Base Optional: " + baseOptional);
selfDescribeHook();
}
protected abstract void selfDescribeHook();
}
and:
public final class Thing extends BaseThing {
public static final String DEFAULT_OPTIONAL = "Default Optional";
private final String required;
private String optional = DEFAULT_OPTIONAL;
Thing(final String theRequired, final String theBaseRequired) {
super(theBaseRequired);
required = theRequired;
}
#Override
protected void selfDescribeHook() {
System.out.println("Required: " + required);
System.out.println("Optional: " + optional);
}
void setOptional(final String newVal) {
optional = newVal;
}
}
I want to have a Joshua Bloch-style builder for Thing objects. More generally, though, I want to make it easy for concrete implementations of BaseThing to have builders, so what I really want (I think) is a BaseThing builder that can easily be used to make a ThingBuilder, or an OtherThingBuilder, or a SuperThingBuilder.
Is there a better way than the following that I've come up with (or are there problems with what I've come up with)?
public abstract class BaseThingBuilder<T extends BaseThing> {
private String baseOptional = BaseThing.DEFAULT_BASE_OPTIONAL;
public BaseThingBuilder<T> setBaseOptional(final String value) {
baseOptional = value;
return this;
}
public T build() {
T t = buildHook();
t.setBaseOptional(baseOptional);
return t;
}
protected abstract T buildHook();
}
and:
public final class ThingBuilder extends BaseThingBuilder<Thing> {
private final String baseRequired;
private final String required;
private String optional = Thing.DEFAULT_OPTIONAL;
public ThingBuilder(final String theRequired,
final String theBaseRequired) {
required = theRequired;
baseRequired = theBaseRequired;
}
public ThingBuilder setOptional(final String value) {
optional = value;
return this;
}
protected Thing buildHook() {
Thing thing = new Thing(required, baseRequired);
thing.setOptional(optional);
return thing;
}
}
Which can be used to build Thing objects in a manner similarly to the following:
BaseThingBuilder<Thing> builder =
new ThingBuilder("Required!", "Base Required!")
.setOptional("Optional!")
.setBaseOptional("Base Optional!");
Thing thing = builder.build();
thing.selfDescribe();
Which outputs:
Base Required: Base Required!
Base Optional: Base Optional!
Required: Required!
Optional: Optional!
One issue that I know about, but that I don't consider particularly important (though if it can be improved it would be nice to do so) is that you have to set all non-base options before you set any base option: Doing otherwise would result in a syntax error, as setBaseOptional() returns a BaseThingBuilder rather than a ThingBuilder.
Thanks in advance.
I don't think it's a good idea to think of builders that way. A hierarchy of builders usually leads to headaches and fragile code.
Cutting down the amount of code that needs to be written in the concrete builders and reusing logic from the base builder is closely tied to the domain. It's not easy to develop a general solution. But, let's try to go through an example anyway:
public interface Builder<T> {
T build();
}
public class Person {
private final String name;
//the proper way to use a builder is to pass an instance of one to
//the class that is created using it...
Person(PersonBuilder builder) {
this.name = builder.name;
}
public String getName(){ return name; }
public static class PersonBuilder implements Builder<Person> {
private String name;
public PersonBuilder name(String name){ this.name = name; return this; }
public Person build() {
if(name == null) {
throw new IllegalArgumentException("Name must be specified");
}
return new Person(this);
}
}
}
Groovy, baby! Now what? Maybe you want to add a class to represent a student. What do you do? Do you extend Person? Sure, that's valid. How about taking a more "strange" route and attempting aggregation? Yep, you can do that too... Your choice would have an affect on how you will end up implementing builders. Let's say you stick to the traditional path and extend Person (you should already starting asking yourself, does it make sense for Person to be a concrete class? If I make it abstract, do I really need a builder? If the class is abstract should the builder be abstract?):
public class Student extends Person {
private final long id;
Student(StudentBulder builder) {
super(builder);
this.id = builder.id;
}
public long getId(){ return id; }
//no need for generics, this will work:
public static class StudentBuilder extends PersonBuilder {
private long id;
public StudentBuilder id(long id){ this.id = id; return this; }
public Student build() {
if(id <= 0) {
throw new IllegalArgumentException("ID must be specified");
}
return new Student(this);
}
}
}
Ok, this looks exactly like what you wanted! So, you try it:
Person p = new PersonBuilder().name("John Doe").build();
Student s = new StudentBuilder().name("Jane Doe").id(165).build();
Looks great! Except, it doesn't compile... There's an error at line 2 and it states The method id(int) is undefined for the type Person.PersonBuilder. The problem is that PersonBuilder#name returns a builder of type PersonBuilder, which isn't what you want. In StudentBuilder you actually want the return type of name to be StudentBuilder. Now, you think ahead and realize that if anything extends StudentBuilder you'd want it to return something else entirely... Is that doable? Yes, with generics. However, it's ugly as hell and introduces quite a bit of complexity. Therefore, I refuse to post the code that illustrates it, for the fear that someone will see this thread and actually use it in their software.
You might think rearranging method calls will work (calling id before calling name): new StudentBuilder().id(165).name("Jane Doe").build(), but it won't. At least not without an explicit cast to Student: (Student)new StudentBuilder().id(165).name("Jane Doe").build() since, in this case, PersonBuilder#build is being called which has a return type of Person... This is simply unacceptable! Even if it worked without an explicit cast, it should make you wince to know that a builder's methods must be called in a certain order. Because if you don't, something won't work...
There are many more problems that would arise if you continue trying to get it to work. And even if you did get it to work, I don't think it would be easily comprehensible and certainly not elegant. Of course, feel free to prove me wrong and post your solution here.
By the way, you should also ask yourself what is an abstract builder? Because, it sounds like an oxymoron.
In the end, I believe that the scope of this question is too great. The answer is domain-specific and hard to come up with in the absence of your requirements. Just remember, the general guideline for builders is to have them be as simple as possible.
Also, take a look at a related question.
As far as I can tell if you remove the generics then
BaseThingBuilder<Thing> builder =
new ThingBuilder("Required!", "Base Required!")
changes to
BaseThingBuilder builder =
new ThingBuilder("Required!", "Base Required!")
The rest of it all remains same, including the restriction that subclass has to be initialized first. So I really don't think this warrants use of generics. Maybe I am missing something.
I seem to remember something like this from Bjarne Stroustrup, long back...