I'm writing a code in Java, one for creating matrices specifically, and I've many different methods I use. I'm trying to separate like methods into separate files, so they're easier to modify, but I can't come up with a way to do it without horrendous inheritance. Is what I'm trying to do possible, or should I bite the bullet and put them all on one file?
For example, I have 4 separate files. The only way I can think of where I don't have to import many different classes is:
MatrixBase --> MatrixSort --> MatrixMethods --> Matrix
I get the feeling that this inheritance for one class is unnecessary, when all I want to do is store similar method in the same file.
What is my best solution?
Strategy is one of the OOP design patterns that allows to separate methods from objects. Although it's primary purpose is to provide a mechanism of supplying alternative algorithm implementations at runtime, you may want to check if it suits your case.
You are likely not using the best Object Oriented Design Approach if you have too much code in a single class. Also, importing many classes is fine in Java. However, I will give you a reasonable option within the bounds of your question. hope it helps.
Try using composition in order to make the functions available in a single location while still breaking them logically into separate classes. ... So lets assume you have MatrixMath as your root class to access all of your matrix manipulation. Lets suppose you want to have a collection of algebra and a collection of sorting.
// container that has all of your matrix math objects
public class MatrixMath {
MatrixMath(){};
public final MatrixAlgebra algebra = new MatrixAlgebra();
public final MatrixSort sort = new MatrixSort();
}
// put all of the algebra type functions here
public class MatrixAlgebra {
MatrixMultiply(){};
public static Matrix multiply(final Matrix a, final Matrix b) {
Matrix result;
// do something
return result;
}
}
// and your sorting functions here...
public class MatrixSort {
...
}
now to access matrix multiply you can use this:
// create a reference to your MatrixMath class so that you
// can use your function.
public class Matrix {
final MatrixMath math = new MatrixMath();
Matrix times(Matrix other) {
return math.algebra.multiply(this,other);
}
}
If you are truly just making functions and you make everything static you can use static references everywhere.
One approach is to make your functions static and move them into static utility classes.
So instead of
Matrix m = ...;
Matrix mt = m.transpose();
float det = mt.determinant();
Vector x = ..;
Vector b = ..;
Vector y = m.solve(x,b);
You end up with
Matrix m = ...
Matrix mt = MatrixGeometry.transpose(m);
float det = MatrixMath.determinant(m);
Vector x = ..;
Vector b = ..;
Vector y = LinearAlgebra.solve(m,x,b);
The fun part is working out which functions should stay member functions, and which should be static.
There is a down-side if you're using inheritance in your Matrix type though. If your heirachy looks like this,
static interface Matrix { ... }
class DenseMatrix implements Matrix { ... }
class SparseMatrix implements Matrix { ... }
class BandedMatrix implements Matrix { ... }
Then you will probably end up with implementations containing type based dispatch:
class LinearAlgebra {
public static Vector solve(Matrix m, Vector x, Vector b) {
if(m instanceof DenseMatrix)
return solveDense((DenseMatrix)m, x, b);
if(m instanceof SparseMatrix)
return solveSparse((SparseMatrix)m, x, b);
...
}
private solveSparse(SparseMatrix m, Vector x, Vector b) {
...
}
}
Which many would consider a "code smell". You can get around this by using a double-dispatch / visitor style in your Matrix class, but that is a bit more pain to set up - and in many cases is not really much more readable/maintainable.
You should not create such a big class--it's a really bad idea.
You need to start evaluating how you can extract portions of your functionality into other small classes. The other classes need not be exposed to users, they can be package private if you like (this is what you get if you don't supply an access level)
You can easily have a single class that is a "Matrix", but that can just be a facade over a large number of other classes.
I'm not sure if it is the same kind of thing you are doing but I spent a while developing a matrix class with a replaceable number implementation that would work with special types like rational and complex types the matrix could manipulate.
Java is miserable at this kind of work (and I'm probably the strongest java proponent you'll run into, so that's saying an awful lot!) The main problem is that number types don't have a useful base type, but to do this kind of work it really helps to be able to overload operators (Something I generally don't consider to be anything more than an attractive nuisance)
If this is the kind of thing you are working on, I highly recommend looking into groovy for the topmost level (using the classes). If that's not the kind of thing you're working on then sorry about the rant but you probably stopped reading before here anyway :)
Related
I can't find any information on this anywhere and was wondering whether such a use of a class is considered bad practise or not.
Let me explain. I have a class ToDecimalConverter which converts an integer from any base to decimal. However, I now need to add the functionality to also convert fractions. As such, I abstracted the integer conversion into a separate class and created a new class with the purpose of converting fractions. (Code isn't finished so I just added some comments to explain)
public class ToDecimalConverter {
private IntegerToDecimalConverter integerConverter;
private DoubleToDecimalConverter doubleConverter;
public double convert(String number, int baseNumber) {
this.integerConverter = new IntegerToDecimalConverter();
this.doubleConverter = new DoubleToDecimalConverter();
number = this.removeZerosAtBeginningOfNumber(number);
// split the number into integer and fraction so they can be used below:
int decimalInt = this.integerConverter.convert(integerNumber, baseNumber);
double decimalDouble = this.doubleConverter.convert(fractioNumber, baseNumber);
// add them together and return them
}
}
Now, except for the methods that remove the zero's from the start of a number and the method that splits the number into integer and fraction (both of which can easily be abstracted into their own class), the ToDecimalConverter class does nothing but group the integer and fraction converters together.
When searching online, I don't see a lot of classes being used like this. Should this be avoided or not? and if so, what are alternatives?
This meant as a more general question, the above is just to explain what I mean.
Edit: Or should I see it as a sort of mini GoF Facade pattern?
There is nothing wrong with it by default, but I would guess that you could achieve the same result with two methods. something like:
public int convertFromInt(String number, int baseNumber) {
int theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
public double convertFromFraction(String number, int baseNumber) {
double theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
Also, keep in mind that a lot of this conversions are already done by Java native classes like BigInteger, BigDecimal, Integer, Decimal, Double, the Math package and so on.
Not going into the specifics of what your class is doing, there indeed value in grouping several or many function/classes together to from a single unified API.
This is called the Facade design pattern.
The intent is that instead of relying on your client to have to know of the various classes/objects you use internally to achieve a feature and to have to look all over the place inside your implementation code is that you put in place a single entry point for given feature/set of feature. It is much better for discoverability & documentation.
Also this way, you ensure to only provide the public API that is only one or a few classes that make the facade while the implementation remains hidden and can change at any time.
I've put together two separate programs which play a card game called 'Crazy Eights'.
The classes I've written for this program are based on a default 'card' package which provides playing card objects and some generic methods for playing cards.
I've taken two separate approaches to achieve this which are both functional in their own right.
Here are two UML class diagrams which depict the two approaches:
Inherited subclass 'conversion' method
Composed subclass with similar methods
As you can see in approach 1 the class EightsCard contains a method convert(Card) Here's the method:
/**
* Converts a Card into an EightsCard
* #param card The card to be converted
* #return The converted EightsCard
*/
public EightsCard convert(Card card) {
if (card != null) {
EightsCard result = new EightsCard(card.getRank(), card.getSuit());
return result;
}
return null;
}
}
This method allows you to call methods from CardCollection which otherwise wouldn't be legal. For example, in the play method from the EightsPlayer class shown below:
/**
* Removes and returns a legal card from the player's hand.
*/
public EightsCard play(Eights eights, EightsCard prev) {
EightsCard ecard = new EightsCard(0, 0);
ecard = ecard.convert(searchForMatch(prev));
if (ecard == null) {
ecard = drawForMatch(eights, prev);
return ecard;
}
return ecard;
}
Approach 2 doesn't require any conversions as the similar methods have been written in a new class EightsCardCollection which extends CardCollection. Now the play methods can be written like this:
public EightsCard play(Eights eights, EightsCard prev) {
EightsCard card = searchForMatch(prev);
if (card == null) {
card = drawForMatch(eights, prev);
}
return card;
}
This brings me to a couple of questions:
Are there any advantages to either approach beyond personal preference?
Is there a better way to compose this program?
For example, might it be better to write 'similar' classes which are more specific1 and not use default classes2 at all.
1 labelled 'crazyeights.syd.jjj' or 'chaptwelvetofort' in the class diagrams.
2 labelled 'defaults.syd.jjj' or cards.syd.jjj' in the class diagrams.
Too many subclasses
Neither of these approaches is very good, as both of them have more subclasses than necessary. Why does EightsCard extend Card? What if you wanted to implement some other card game? (There are quite a few, you know...) Would you make one subclass for each card game? Please don't.
I would have these classes:
Card
CardCollection
Player
I wouldn't even have a Deck class as it seems like it does nothing else than extend CardCollection without providing any more functionality.
Then I would have one class for each game implementation, so one EightsController class that handles the game logic for that game. No specific class for EightsCard, no specific class for EightsCardCollection, etc.
The reason is simple: You don't need anything more than this. A Card and a CardCollection is exactly the same no matter which card game you are playing. A Player is also the same thing in all games.
With regard to those domain models, I agree with Simon Forsberg that those are way too complicated, and I understand they're designed to demonstrate some concepts, but even then they could have used a more realistic example, like components in an automobile and their relations. You probably need only two domain classes, Card and Player. For an ordered collection of Cards, use a List<Card>. When it comes to dealing, taking turns, etc. there is a lot of room for creativity for how to organize game logic. Generally it is preferable to compose types out of other ones rather than rely heavily on inheritance which is less flexible in practice.
When it comes to performance, common rules apply. For instance, reuse objects where possible. If you're always using the 52-card deck then there's no reason to even have a Card class. There's probably nothing better-performing than reusing enumeration values everywhere.
enum Card {
ACE_CLUBS,
TWO_CLUBS,
// ...
ACE_DIAMONDS,
// ...
}
(You can't really make this enum any more complicated, since different games use different orderings, place different values on different cards depending on the context, etc.)
For an excellent practical guide to programming for performance, I recommend the book, Java Performance: The Definitive Guide.
Simon's comment caught my attention: "I would prefer having two enums - one for Suit and one for Rank - instead of one enum for the whole card"
Is there a better way to compose this program?
The key point is this -- most of your program should be completely insulated from the in memory representation of a card.
In memory, a card might be
an integer
a byte
an enum
a String
a URL (http://example.org/cards/hearts/7)
an integer/byte restricted to the range [0,52)
a tuple
int, int
enum, enum
byte, byte
mix and match
a reference to a third party implementation
Most of your code should not care.
Ideally, the only bits that care at all would be the module that provides the implementation, and perhaps the composition root.
Most places in your diagram where you have <<Java Class>> you should instead have <<Java Interface>>.
See Parnas, 1972
In that sort of a design, you would use composition to attach your crazy eight semantics to a generic definition of card defined somewhere else.
Eights.Deck deck(Iterable<Generic.Card> standardDeck) {
List<Eights.Card> cards = new ArrayList();
for(Generic.Card c : standardDeck) {
cards.add(
new Eights.Card(c)
);
}
return new Eights.Deck(cards);
}
or perhaps
Eights.Deck deck(Generic.Deck standardDeck) {
return new Eights.Deck(
standardDeck
.stream()
.map(Eights.Deck::new)
.collect(Collectors.toList())
);
}
The composition root would look something like
public static void main(String [] args) {
GenericCards genericCards = new ApacheGenericCards();
EightsCards eightsCards = MyAwesomEightsCardsV2(genericCards);
EightsGame game = new EightsGame(eightsCards)
game.play();
}
I'm trying to make a class which represents an Ability of a Champion in my game. The impediment I've faced is that I don't know how to design an Ability class with multiple properties i.e. damaging, stuning, slowing. My idea was to create enum class which represents all these properties and then assign them to my abilities, for example:
public enum Effect {
DAMAGE,
SLOW,
STUN,
...
}
But what if I have an ability that stuns and deals damage at the same time? Should I create an Effect[] array and to deal with it somehow or should I create interface-markers like Serializable(it's the creaziest idea I've had)? Or maybe there is some technique for cases like that?
An array with Effect objects seems fine, a list would be even better. You can even create your own wrapper class to provide additional methods calculating entity properties based on applied effects.
For example:
public class Effects
{
public int calculateDamage(int baseDamage)
{
int damage = baseDamage;
if (effects.contains(Effect.DAMAGE)) {
// some effect stacking :)
damage *= 1.5 * Collections.frequency(effects, Effect.DAMAGE);
}
if (effects.contains(Effect.STUN)) {
damage = 0;
}
return damage;
}
private final List<Effect> effects = new ArrayList<>();
}
Collections.frequency() is a utility method from Apache Commons library, which I highly recommend.
you can create a class of type Effect with all properties as Boolean attributes and then assign true or false to them as you like, and if you like to extend properties to ones you can't decide at compile time think about putting one hashmap of type HashMap in Effect class
I am relatively new to OOP. Sometimes I come across situations where I'm not sure where a method should go. I will try to give a minimal example; I hope I don't go overboard and make it too abstract.
Say I have a Point class which holds the position of a point, and a Line class which holds the equation of a line. I now need a method that computes the (perpendicular) distance between a Point and a Line. I could do:
Point::distance_to_line(Line L)
Line::distance_to_point(Point P)
a free-standing function: point_line_distance(Line L, point P)
Is there a preferred way in OOP in general, or is it language-dependant? In C++ a free-standing function is an option, but from my limited understanding of Java, it does not allow free-standing functions. In that case would you create a class like PointLineDistanceCalculator?
Your 3rd option of some other place that is not in the Point or Line class is the best option.
Points shouldn't have to know about Lines and vice versa. Otherwise, they will be tightly coupled.
http://en.wikipedia.org/wiki/Loose_coupling
However, there can be some other class that knows about both.
In java, I would probably made a 3rd Distance class or DistanceCalculator that could compute distances between several objects.
Distance.between(Point a, Point b)
Distance.between(Point a, line l)
etc
In java you could always create the free standing function as a static method of one of the two classes (or of a third helper class).
I don't think there's a preferred way in general, but you could have all three for the most flexibility, and reuse the code.
For example, one method would hold the logic :
class Point {
...
float distToLine (Line l) {
....
return some result;
}
...
}
and then the other methods will call the original method :
class Line {
...
float distToPoint (Point p) {
return p.distToLine (this);
}
...
static float pointToLineDistance (Point p, Line l) {
return p.distToLine (l);
}
...
}
A fourth option is to find/construct a common ancestor in the class hierarchy which could
be something like "GeometricEntity". Anything for which "distance to annother GeometricEntity" has a meaning.
The Situation is that I have to use Function pointers for so many functions in Java (so I did it this way) and saved each anonymous class to a static variable of the Interface, so that I could use them directly.
/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(DoubleMatrix netSum, double theta) {
return netSum.gt(theta);
}
public String getFuncName() {
return "HARDLIM";
}
};
But the problem is that sometimes I don't need to provide the Theta so if I remove it the polymorphism won't work, (2 Functions out of 10 don't need theta) so I had to put it (Function declaration conventions now ugly) so I thought of passing the whole Object which actually contains both netsum and theta.
But I'm starting to worry, cause it's also going to ruin what this function really is for. So at last I suggested I put these function separately (non anonymous) and then make anonymous functions use them but the argument would be the object. Like the following:
/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(MyObject obj) {
return MyObjectUtilFun.hardlim(obj.getNetsum,obj.getTheta);
}
public String getFuncName() {
return "HARDLIM";
}
};
So Am I taking the right steps ? or I'm messing around, Please guide me!
Do you really need the instance to be public static final? If you can instantiate the instance wherever you have a reference to theta, then your anonymous class can use that theta reference. For example:
final double theta = 123d;
class TransferePatternable {
public String transfere(String whatever) {
return whatever + theta;
}
}
TransferePatternable myInstance = new TransferePatternable();
myInstance.transfere("arg");
Alternatively you can specify the input as a generic type such that your MyObject need not be a superset of all possible inputs, but rather can differ by TransferePatternable type. Obviously the drawback here is that you need to know what type you're calling in order to provide the right input, but you sort of need to know this anyway if you don't want to provide theta in some situations.
Finally, another common solution to this problem is to replace ALL method parameters with just one Map. Then, you can pass in whatever you want! This has lots of obvious drawbacks, but lots of APIs do exactly this, and generally you'll see them refer to the map as the "context". Here are a few examples:
javax.servlet .ServletRequests store parameters in a Map
AOP has the javax.interceptor.InvocationContext class
Spring's IoC container basically is a big Map of named javabeans
The JSP Expression Language allows you to refer to Implicit Objects that basically are stored in several Maps
I myself have used this Map solution when implementing an Excel-like formula language in java years ago. Such a formula can be parsed into functions and variables, and when executing the function we provided a Map containing the variables keyed by variable name. Obviously you still need to know something about what you're invoking, and in fact we always did know enough about the formula that providing the right inputs in a Map was easy. But again I have to caution you: this sort of code is fairly hard to implement and maintain. Unless you anticipate growing a large set of functions over time, don't go down this route. It's not OO-friendly, and it should be a last resort.
If MyObject is a generally used interface or class and TransferePatternable is not expected to work with anything else, your second idea is best. It opens up the possibilities of a TransferePatternable being able to work with more than just netSum and theta and gets rid of the unneeded theta. My guess is that this is what you want to do, even if it means expanding the capabilities and scope and importance of the MyObject class/interface.
But you are restricting a TransferePatternable to working with a MyObject instance. The unused theta is a problem, but it's a small price to pay for the power of polymorphism (and its a lot simpler and neater than most other solutions). If the MyObject solution doesn't look perfect to you, stick with the unused theta. My guess is a good idea will come along sooner or later, with no harm done if it doesn't.
Is there any reason you can't have an overloaded "transfere" function in the HARDLIM?
/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(DoubleMatrix netSum, double theta) {
return netSum.gt(theta);
}
public DoubleMatrix transfere(DoubleMatrix netSum) {
return netSum.whateverYouNeedToDoWithoutTheta();
}
public String getFuncName() {
return "HARDLIM";
}
};
At the end I used The second choice but with some notes in mind:
To always have functions (i.e Hardlim) defined independently in utility classes.
To state in Javadocs what this variable really is and the utility function being used.
I also found the price of confusing users with unnecessary arguments to be high cause the application is already complex no need to be more complicated.
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(MyObject obj) {
return MyObjectUtilFun.hardlim(obj.getNetsum,obj.getTheta);
}
public String getFuncName() {
return "HARDLIM";
}
};