Sorry for the bad question title.
Let's say that I have DateRange class that basically just consists of a start date and and end date.
My question is: How might I represent computed date ranges such as "This Week", "The Past Two Weeks", "Last Month", and "This Quarter", such that multiple clients can use these computed date ranges in a consistent way? That is, I'm going to have multiple objects of multiple classes that all need to know what "This Week" is.
I could build them into DateRange, but that doesn't seem like a good solution because more might be added or some may become obsolete over time....in fact this will happen most certainly. I could make DateRange abstract and extend it, but then I'm going to have a bunch of tiny classes. I could create some kind of static helper class that computes these dates. How might you approach this problem?
dateRange = new DateRange(RangeEnum.THISWEEK));
or
dateRange = new ThisWeek();
or
dateRange = DateHelper.getThisWeek();
or
?
To throw an additional wrench into this thing, let's say that I also need to represent a range like "the work week containing the date May 1, 2008". Upon stating that, I'm leaning towards the helper class...it just feels awkward having a big lump of goofy methods.
Why create a helper class. The common idiom used in the .NET framework would be to add Static properties to the existing class.
class DateRange
{
DateRange ourCurrentWeek = null;
public static DateRange ThisWeek
{
get
{
//create ourCurrentWeek if not yet assigned.
//test current week; is it still correct or does it need updating
return ourCurrentWeek;
}
}
}
Usage is simply:-
DateRange.ThisWeek
I would go the way with the helper class.
DateRange dr = Helper.getThisWeek();
You're right, you'll get a bunch a methods, but if you would subclass something you'll get a bunch of classes. This way you know for sure where to look.
Related
In order to extract data table values to use in a reporting extension for Spock, I am using the
following code:
#Override
public void beforeIteration(IterationInfo iteration) {
Object[] values = iteration.getDataValues();
}
This returns to me the reference to the objects in the data table. However, I would like to get
the name of the variable that references the value.
For example, in the following test:
private static User userAge15 = instantiateUserByAge(15);
private static User userAge18 = instantiateUserByAge(18);
private static User userAge19 = instantiateUserByAge(19);
private static User userAge40 = instantiateUserByAge(40);
def "Should show popup if user is 18 or under"(User user, Boolean shouldShowPopup) {
given: "the user <user>"
when: "the user do whatever"
...something here...
then: "the popup is shown is <showPopup>"
showPopup == shouldShowPopup
where:
user | shouldShowPopup
userAge15 | true
userAge18 | true
userAge19 | false
userAge40 | false
}
Is there a way to receive the string “userAge15”, “userAge18”, “userAge19”, “userAge40” instead of their values?
The motivation for this is that the object User is complex with lots of information as name, surname, etc, and its toString() method would make the where clause unreadable in the report I generate.
You can use specificationContext.currentFeature.dataVariables. It returns a list of strings containing the data variable names. This should work both in Spock 1.3 and 2.0.
Edit: Oh sorry, you do not want the data variable names ["a", "b", "expected"] but ["test1", "test1", "test2"]. Sorry, I cannot help you with that and would not if I could because that is just a horrible way to program IMO. I would rather make sure the toString() output gets shortened or trimmed in an appropriate manner, if necessary, or to (additionally or instead) print the class name and/or object ID.
Last but not least, writing tests is a design tool uncovering potential problems in your application. You might want to ask yourself why toString() results are not suited to print in a report and refactor those methods. Maybe your toString() methods use line breaks and should be simplified to print a one-line representation of the object. Maybe you want to factor out the multi-line representation into other methods and/or have a set of related methods like toString(), toShortString(), toLongString() (all seen in APIs before) or maybe something specific like toMultiLineString().
Update after OP significantly changed the question:
If the user of your extension feels that the report is not clear enough, she could add a column userType to the data table, containing values like "15 years old".
Or maybe simpler, just add an age column with values like 15, 18, 19, 40 and instantiate users directly via instantiateUserByAge(age) in the user column or in the test's given section instead of creating lots of static variables. The age value would be reported by your extension. In combination with an unrolled feature method name using #age this should be clear enough.
Is creating users so super expensive you have to put them into static variables? You want to avoid statics if not really necessary because they tend to bleed over side effects to other tests if those objects are mutable and their internal state changes in one test, e.g. because someone conveniently uses userAge15 in order to test setAge(int). Try to avoid premature optimisations via static variables which often just save microseconds. Even if you do decide to pre-create a set of users and re-use them in all tests, you could put them into a map with the age being the key and conveniently retrieve them from your feature methods, again just using the age in the data table as an input value for querying the map, either directly or via a helper method.
Bottom line: I think you do not have to change your extension in order to cater to users writing bad tests. Those users ought to learn how to write better tests. As a side effect, the reports will also look more comprehensive. 😀
I have a superclass Appointment that is then extended to a few different types of appointments. I need to make an ArrayList of appointments of different types which I did not think would be much of a problem since they all share a common superclass - Appointment. But when I try to add one of the subclasses Daily to the ArrayList<Appointment> book = new ArrayList<Appointment>() it fails to do so.
I have:
ArrayList<Appointment> book = new ArrayList<Appointment>()
Then later on in the program (I'm passing description, day, month, and year from the method it's place in):
book.add(new Daily(description, day, month, year));
And I get the suggestion of: The method add(AppointmentBook.Appointment) in the type ArrayList is not applicable for the arguments (Daily)
Change your code from ArrayList<Appointment> to ArrayList<? extends Appointment>
This question is probably pretty obvious to any person who knows how to use Bukkit properly, and I'm sorry if I missed a solution in the others, but this is really kicking my ass and I don't know what else to do, the tutorials have been utterly useless. There are really 2 things that I need help doing:
I need to learn how to create an indefinite number of instances of an object. I figure it'd be like this:
int num = 0;
public void create(){
String name = chocolate + num;
Thingy name = new Thingy();
}
So you see what I'm saying? I need to basically change the name that is given to each new instance so that it doesn't overwrite the last one when created. I swear I've looked everywhere, I've asked my Java professor and I can't get any answers.
2: I need to learn how to use the stupid scheduler, and I can't understand anything so far. Basically, when an event is detected, 2 things are called: one method which activates instantly, and one which needs to be given a 5 second delay, then called. The code is like this:
public onEvent(event e){
Thingy thing = new Thingy();
thing.method1();
thing.doOnDelay(method2(), 100 ticks);
}
Once again, I apologize if I am not giving too many specifics, but I cannot FOR THE LIFE OF ME find anything about the Bukkit event scheduler that I can understand.
DO NOT leave me links to the Bukkit official tutorials, I cannot understand them at all and it'll be a waste of an answer. I need somebody who can help me, I am a starting plugin writer.
I've had Programming I and II with focus in Java, so many basic things I know, I just need Bukkit-specific help for the second one.
The first one has had me confused since I started programming.
Ok, so for the first question I think you want to use a data structure. Depending on what you're doing, there are different data structures to use. A data structure is simply a container that you can use to store many instances of a type of object. The data structures that are available to you are:
HashMap
HashSet
TreeMap
List
ArrayList
Vector
There are more, but these are the big ones. HashMap, HashSet, and TreeMap are all part of the Map class, which is notable for it's speedy operations. To use the hashmap, you instantiate it with HashMap<KeyThing, ValueThingy> thing = new HashMap<KeyThing, ValueThing>(); then you add elements to it with thing.put(key, value). Thn when you want to get a value out of it, you just use thing.get(key) HashMaps use an algorithm that's super fast to get the values, but a consequence of this is that the HashMap doesn't store it's entries in any particular order. Therefore when you want to loop though it with a for loop, it randomly returns it's entries (Not truly random because memory and stuff). Also, it's important to note that you can only have one of each individual key. If you try to put in a key that already exists in the map, it will over-right the value for that key.
The HashSet is like a HashMap but without storing values to go with it. It's a pretty good container if all you need to use it for is to determine if an object is inside it.
The TreeMap is one of the only maps that store it's values in a particular order. You have to provide a Comparator (something that tells if an object is less than another object) so that it knows the order to put the values if it wants them to be in ascending order.
List and ArrayList are not maps. Their elements are put in with a index address. With the List, you have to specify the number of elements you're going to be putting into it. Lists do not change size. ArrayLists are like lists in that each element can be retrieved with arrayListThing.get(index) but the ArrayList can change size. You add elements to an ArrayList by arrayListThing.add(Thing).
The Vector is a lot like an ArrayList. It actually functions about the same and I'm not quite sure what the difference between them is.
At any rate, you can use these data structures to store a lot of objects by making a loop. Here's an example with a Vector.
Vector<Thing> thing = new Vector<Thing>();
int numberofthings = 100;
for(int i = 0; i < numberofthings; i++) {
thing.add(new Thing());
}
That will give you a vector full of things which you can then iterate through with
for(Thing elem:thing) {
thing.dostuff
}
Ok, now for the second problem. You are correct that you need to use the Bukkit Scheduler. Here is how:
Make a class that extends BukkitRunnable
public class RunnableThing extends BukkitRunnable {
public void run() {
//what you want to do. You have to make this method.
}
}
Then what you want to do when you want to execute that thing is you make a new BukkitTask object using your RunnableThing
BukkitTask example = new RunnableThing().runTaskLater(plugin, ticks)
You have to do some math to figure out how many ticks you want. 20 ticks = 1 second. Other than that I think that covers all your questions.
As a sort of continuation of this, I have the following newbie question:
What difference is there in building a wrapper class that expects lots of inputs parameters and inputting those parameters directly into the final constructor?
Don't get me wrong, I think the multiple input parameter thing is pretty ugly, and I'm trying to get around it since just like the poster of that question, I need to deal with a Calculator-like class that requires a lot of parameters. But what I don't understand is what would a wrapper class for input parameters solve, since I also need to build the input class--and that's just as ugly as the other alternative.
To summarize, I don't think this:
MyClass::MyClass(int param1, int param2, int param3... int paramN)
{
this->param1 = param1;
this->param2 = param2;
this->param3 = param3;
...
this->paramN = paramN;
}
...is much different from this:
Result MyClass::myInterface(MyInputClass input)
{
//perform calculations
}
MyInputClass::MyInputClass(int param1, int param2, int param3... int paramN)
{
this->param1 = param1;
this->param2 = param2;
this->param3 = param3;
...
this->paramN = paramN;
}
And, of course, I am trying to avoid setters as much as possible.
Am I missing something here? I'd love to have some insight on this, since I'm still a rather newbie programmer.
Here is some of the reasons, one would like to use a parameter class:
Reusability: You can save the parameters in a variable and reuse them, maybe in another method.
Separation of concerns: Parameter handling, say to verify which parameters are active, which are in their correct ranges, etc., is performed in the parameter class; your calculation method only knows how to calculate, so in the future you know where is each and no logic is mixed.
You can add a new value and impact minimally in your calcultor method.
Maybe your calculator method can be applied to two different set of parameters, say on an integer and on a double. It is more readable/mantainable/faster to write the calculation logic just once and change the parameter object.
Some classes do not need to initialize every single field at the constructor. Sometimes setters are the way to go.
The biggest benefits are:
Insulation from changes. You can add
new properties to the parameter class
and not have to change the class that
uses it or any of its callers.
Code reduction when you're chaining
methods. If MyClass needs to pass
its parameters around, MyInputClass
eliminates a bunch of code.
All the other points are completely valid and sound. Here's a little reinforcement from some authoritative text:
Code Complete suggests that you limit the number of parameters of any routine to seven, as "seven is the magic number for people's comprehension." It then goes on to suggest that passing more than seven parameters increases coupling with the calling scope and that you should use a structured variable (ala MyInputClass) instead.
Portfolio A → Fund 1
Portfolio A → Fund 2
Portfolio A → Fund 3
I couldn't frame my sentence without not using is/has. But between 1 & 2,
1) has a:
class PortfolioA
{
List<Fund> obj;
}
2) is a:
class PortfolioA : List<Fund>
{
}
which one do you think is better from the point of extensibility, usability? I can still access my funds either way, albeit with a small syntactical change.
I vote with the other folks who say HAS-A is better in this case. You ask in a comment:
when I say that a Portfolio is just a
collection of funds, with a few
attributes of its own like
TotalPortfolio etc, does that
fundamentally not become an "is-a"?
I don't think so. If you say Portfolio IS-A List<Fund>, what about other properties of the Portfolio? Of course you can add properties to this class, but is it accurate to model those properties as properties of the List? Because that's basically what you're doing.
Also what if a Portfolio is required to support more than one List<Fund>? For instance, you might have one List that shows the current balance of investments, but another List that shows how new contributions are invested. And what about when funds are discontinued, and a new set of funds is used to succeed them? Historical information is useful to track, as well as the current fund allocation.
The point is that all these properties are not correctly properties of a List, though they may be properties of the Portfolio.
do not 'always' favor composition or inheritance or vice-versa; they have different semantics (meanings); look carefully at the meanings, then decide - it doesn't matter if one is 'easier' than the other, for longevity it matters that you get the semantics right
remember: is-a = type, has-a = containment
so in this case, a portfolio logically is a collection of funds; a portfolio itself is not a type of fund, so composition is the correct relationship
EDIT: I misread the question originally, but the answer is still the same. A Portfolio is not a type of list, it is a distinct entity with its own properties. For example, a portfolio is an aggregate of financial instruments with an initial investment cost, a total current value, a history of values over time, etc., while a List is a simple collection of objects. A portfolio is a 'type of list' only in the most abstract sense.
EDIT 2: think about the definition of portfolio - it is, without exception, characterized as a collection of things. An artist's portfolio is a collection of their artwork, a web designer's portfolio is a collection of their web sites, an investor's portfolio consists of all of the financial instruments that they own, and so on. So clearly we need a list (or some kind) to represent a portfolio, but that in no way implies that a portfolio is a type of list!
suppose we decide to let Portfolio inherit from List. This works until we add a Stock or Bond or Precious Metal to the Portfolio, and then suddenly the incorrect inheritance no longer works. Or suppose we are asked to model, say, Bill Gates' portfolio, and find that List will run out of memory ;-) More realistically, after future refactoring we will probably find that we should inherit from a base class like Asset, but if we've already inherited from List then we can't.
Summary: distinguish between the data structures we choose to represent a concept, and the semantics (type hierarchy) of the concept itself.
The first one, because you should try to favour composition over inheritance when you can.
It depends whether the business defines a Portfolio as a group (and only a group) of funds. If there is even the remote possibility of that it could contain other objects, say "property", then go with option 1. Go with option 2 if there is a strong link between a group of funds and the concept of Portfolio.
As far as extensibility and usefullness 1 has the slight advantage over 2. I really disagree with the concept that you should always favour one over the other. It really depends on what the actual real life concepts are. Remember, you can always^ refactor.
^ For most instances of always. If it is exposed publicly, then obviously not.
I would go with option (1) - composition, since you may eventually have attributes specific to the portfolio, rather than the funds.
The first one, because it is "consists of". => Composition
I will differ with what appears to be the common opinion. In this case I think a portfolio is very little more than a collection of funds... By using inheritance you allow the use of multiple constructors, as in
public Portfolio(CLient client) {};
public Portfolio(Branch branch, bool Active, decimal valueThreshold)
{
// code to populate collection with all active portfolios at the specified branch whose total vlaue exceeds specified threshold
}
and indexers as in:
public Fund this[int fundId] { get { return this.fundList[fundId]; } }
etc. etc.
if you want to be able to treat variables of type Portfolio as a collection of funds, with the associated syntax, then this is the better approach.
Portfolio BobsPortfolio = new Portfolio(Bob);
foreach (Fund fund in BobsPortfolio)
{
fund.SendStatement();
}
or stuff like that
IS-A relation ship represents inheritances and HAS-A relation ship represents composition. For above mentioned scenario we prefer composition as PortfolioA has a List and it is not the List type. Inheritances use when Portfolio A is a type of List but here it is not. Hence for this scenario we should prefer Composition.