What is the best practice to store base units?
Let's say I want to have a mile unit. So, I implement Number>>#miles, but what is the implementation?
The problem is that: (2 * (BaseUnit named: 'mile')) ~= (2 * (BaseUnit named: 'mile')), so it seems the mile base unit must be a singleton.
So I'd have something like:
Number>>#miles
^ self * Mile uniqueInstance
Am I on the right track, or can you think of a better way?
units are not really singletons but they use the original #= to see if two units are the same and the default implementation of #= verifies identity with #==, but that can be overridden if necessary.
The reason I did it that way is because I thought it was the most generic implementation. The easiest way to use them is to store units in global variables, therefore you can define:
Smalltalk at: #Mile put: (BaseUnit named: 'mile' etc etc).
And then you can do 2*Mile witch makes a lot of sense because... it is like saying that "the knowledge of mile is global"
Another way to do it is how Chalten does it. That is to have a class that knows each unit and you can access them with messages like "TimeUnits day"
The idea is to avoid having to create a class per unit that does not make any sense...
Another possibility is to 1) modify #= on Unit and use the uni's name to verify if two units are the equal 2) Subclass BaseUnit and do 1) :-)
If you have problems with Fuel, it is because you are not saving the root object that knows each unit, but once you do it the problem should be solved.
Hernan.
Yes the mile base unit must be a singleton, you can take a look at the Chalten framework which is using Aconcagua, in particular the TimeUnitsGlobal class.
For the Number method part, in Chalten it's done this way :
Number>>#daysMeasure
^TimeUnits day with: self
Although I have an issue with the way it's done there because I can't found a way to use Fuel with such units after that.
Related
What's the recommended way to handle an object that may not be fully initialized?
e.g. taking the following code (off the top of my head in ruby):
class News
attr_accessor :number
def initialize(site)
#site = site
end
def setup(number)
#number = number
end
def list
puts news_items(#site, #number)
end
end
Clearly if I do something like:
news = News.new("siteA")
news.list
I'm going to run into problems. I'd need to do news.setup(3) before news.list.
But, are there any design patterns around this that I should be aware of?
Should I be creating default values? Or using fixed numbers of arguments to ensure objects are correctly initialized?
Or am I simply worrying too much about the small stuff here.
Should I be creating default values?
Does it make sense to set a default? If so this is a perfectly valid approach IMHO
Or using fixed numbers of arguments to ensure objects are correctly initialized?
You should ensure that your objects cannot be constructed in an invalid state, this will make your's and other users of your code much simpler.
in your example not initializing number in some way is a problem, and this method is an example of temporal coupling. You should avoid this, and the two ways you suggested are ways to do this. Alternatively you can have another object or static method responsible for building your object in a valid state instead
If you do have an object which in not fully initialised then any invalid methods should produce appropriate and descriptive exceptions which let the users know that they are using the code incorrectly, and gives examples of the correct usage patterns.
In c# InvalidStateException is usually appropriate and similar exceptions exist in Java. Ruby is beyond my pay grade unfortunately :)
I have a lot to learn in the way of OO patterns and this is a problem I've come across over the years. I end up in situations where my classes' sole purpose is procedural, just basically wrapping a procedure up in a class. It doesn't seem like the right OO way to do things, and I wonder if someone is experienced with this problem enough to help me consider it in a different way. My specific example in the current application follows.
In my application I'm taking a set of points from engineering survey equipment and normalizing them to be used elsewhere in the program. By "normalize" I mean a set of transformations of the full data set until a destination orientation is reached.
Each transformation procedure will take the input of an array of points (i.e. of the form class point { float x; float y; float z; }) and return an array of the same length but with different values. For example, a transformation like point[] RotateXY(point[] inList, float angle). The other kind of procedure wold be of the analysis type, used to supplement the normalization process and decide what transformation to do next. This type of procedure takes in the same points as a parameter but returns a different kind of dataset.
My question is, what is a good pattern to use in this situation? The one I was about to code in was a Normalization class which inherits class types of RotationXY for instance. But RotationXY's sole purpose is to rotate the points, so it would basically be implementing a single function. This doesn't seem very nice, though, for the reasons I mentioned in the first paragraph.
Thanks in advance!
The most common/natural approach for finding candidate classes in your problem domain is to look for nouns and then scan for the verbs/actions associated with those nouns to find the behavior that each class should implement. While this is generally a good advise, it doesn't mean that your objects must only represent concrete elements. When processes (which are generally modeled as methods) start to grow and become complex, it is a good practice to model them as objects. So, if your transformation has a weight on its own, it is ok to model it as an object and do something like:
class RotateXY
{
public function apply(point p)
{
//Apply the transformation
}
}
t = new RotateXY();
newPoint = t->apply(oldPoint);
in case you have many transformations you can create a polymorphic hierarchy and even chain one transformation after another. If you want to dig a bit deeper you can also take a look at the Command design pattern, which closely relates to this.
Some final comments:
If it fits your case, it is a good idea to model the transformation at the point level and then apply it to a collection of points. In that way you can properly isolate the transformation concept and is also easier to write test cases. You can later even create a Composite of transformations if you need.
I generally don't like the Utils (or similar) classes with a bunch of static methods, since in most of the cases it means that your model is missing the abstraction that should carry that behavior.
HTH
Typically, when it comes to classes that contain only static methods, I name them Util, e.g. DbUtil for facading DB access, FileUtil for file I/O etc. So find some term that all your methods have in common and name it that Util. Maybe in your case GeometryUtil or something along those lines.
Since the particulars of the transformations you apply seem ad-hoc for the problem and possibly prone to change in the future you could code them in a configuration file.
The point's client would read from the file and know what to do. As for the rotation or any other transformation method, they could go well as part of the Point class.
I see nothing particularly wrong with classes/interfaces having just essentially one member.
In your case the member is an "Operation with some arguments of one type that returns same type" - common for some math/functional problems. You may find convenient to have interface/base class and helper methods that combine multiple transformation classes together into more complex transformation.
Alternative approach: if you language support it is just go functional style altogether (similar to LINQ in C#).
On functional style suggestion: I's start with following basic functions (probably just find them in standard libraries for the language)
collection = map(collection, perItemFunction) to transform all items in a collection (Select in C#)
item = reduce (collection, agregateFunction) to reduce all items into single entity (Aggregate in C#)
combine 2 functions on item funcOnItem = combine(funcFirst, funcSecond). Can be expressed as lambda in C# Func<T,T> combined = x => second(first(x)).
"bind"/curry - fix one of arguments of a function functionOfOneArg = curry(funcOfArgs, fixedFirstArg). Can be expressed in C# as lambda Func<T,T> curried = x => funcOfTwoArg(fixedFirstArg, x).
This list will let you do something like "turn all points in collection on a over X axis by 10 and shift Y by 15": map(points, combine(curry(rotateX, 10), curry(shiftY(15))).
The syntax will depend on language. I.e. in JavaScript you just pass functions (and map/reduce are part of language already), C# - lambda and Func classes (like on argument function - Func<T,R>) are an option. In some languages you have to explicitly use class/interface to represent a "function" object.
Alternative approach: If you actually dealing with points and transformation another traditional approach is to use Matrix to represent all linear operations (if your language supports custom operators you get very natural looking code).
I have to add a bunch of trivial or seldom used attributes to an object in my business model.
So, imagine class Foo which has a bunch of standard information such as Price, Color, Weight, Length. Now, I need to add a bunch of attributes to Foo that are rarely deviating from the norm and rarely used (in the scope of the entire domain). So, Foo.DisplayWhenConditionIsX is true for 95% of instances; likewise, Foo.ShowPriceWhenConditionIsY is almost always true, and Foo.PriceWhenViewedByZ has the same value as Foo.Price most of the time.
It just smells wrong to me to add a dozen fields like this to both my class and database table. However, I don't know that wrapping these new fields into their own FooDisplayAttributes class makes sense. That feels like adding complexity to my DAL and BLL for little gain other than a smaller object. Any recommendations?
Try setting up a separate storage class/struct for the rarely used fields and hold it as a single field, say "rarelyUsedFields" (for example, it will be a pointer in C++ and a reference in Java - you don't mention your language.)
Have setters/getters for these fields on your class. Setters will check if the value is not the same as default and lazily initialize rarelyUsedFields, then set the respective field value (say, rarelyUsedFields.DisplayWhenConditionIsX = false). Getters they will read the rarelyUsedFields value and return default values (true for DisplayWhenConditionIsX and so on) if it is NULL, otherwise return rarelyUsedFields.DisplayWhenConditionIsX.
This approach is used quite often, see WebKit's Node.h as an example (and its focused() method.)
Abstraction makes your question a bit hard to understand, but I would suggest using custom getters such as Foo.getPrice() and Foo.getSpecialPrice().
The first one would simply return the attribute, while the second would perform operations on it first.
This is only possible if there is a way to calculate the "seldom used version" from the original attribute value, but in most common cases this would be possible, providing you can access data from another object storing parameters, such as FooShop.getCurrentDiscount().
The problem I see is more about the Foo object having side effects.
In your example, I see two features : display and price.
I would build one or many Displayer (who knows how to display) and make the price a component object, with a list of internal price modificators.
Note all this is relevant only if your Foo objects are called by numerous clients.
I am building a package to handle data that arrives with up to 4 different types. Each of these types is a legitimate class in the form of a matrix, data.frame or tree. Depending on the way the data is processed and other experimental factors, some of these data components may be missing, but it is still extremely useful to be able to store this information as an instance of a special class and have methods that recognize the different component data.
Approach 1:
I have experimented with an incremental inheritance structure that looks like a nested tree, where each combination of data types has its own class explicitly defined. This seems difficult to extend for additional data types in the future, and is also challenging for new developers to learn all the class names, however well-organized those names might be.
Approach 2:
A second approach is to create a single "master-class" that includes a slot for all 4 data types. In order to allow the slots to be NULL for the instances of missing data, it appears necessary to first define a virtual class union between the NULL class and the new data type class, and then use the virtual class union as the expected class for the relevant slot in the master-class. Here is an example (assuming each data type class is already defined):
################################################################################
# Use setClassUnion to define the unholy NULL-data union as a virtual class.
################################################################################
setClassUnion("dataClass1OrNULL", c("dataClass1", "NULL"))
setClassUnion("dataClass2OrNULL", c("dataClass2", "NULL"))
setClassUnion("dataClass3OrNULL", c("dataClass3", "NULL"))
setClassUnion("dataClass4OrNULL", c("dataClass4", "NULL"))
################################################################################
# Now define the master class with all 4 slots, and
# also the possibility of empty (NULL) slots and an explicity prototype for
# slots to be set to NULL if they are not provided at instantiation.
################################################################################
setClass(Class="theMasterClass",
representation=representation(
slot1="dataClass1OrNULL",
slot2="dataClass2OrNULL",
slot3="dataClass3OrNULL",
slot4="dataClass4OrNULL"),
prototype=prototype(slot1=NULL, slot2=NULL, slot3=NULL, slot4=NULL)
)
################################################################################
So the question might be rephrased as:
Are there more efficient and/or flexible alternatives to either of these approaches?
This example is modified from an answer to a SO question about setting the default value of slot to NULL. This question differs in that I am interested in knowing the best options in R for creating classes with slots that can be empty if needed, despite requiring a specific complex class in all other non-empty cases.
In my opinion...
Approach 2
It sort of defeats the purpose to adopt a formal class system, and then to create a class that contains ill-defined slots ('A' or NULL). At a minimum I would try to make DataClass1 have a 'NULL'-like default. As a simple example, the default here is a zero-length numeric vector.
setClass("DataClass1", representation=representation(x="numeric"))
DataClass1 <- function(x=numeric(), ...) {
new("DataClass1", x=x, ...)
}
Then
setClass("MasterClass1", representation=representation(dataClass1="DataClass1"))
MasterClass1 <- function(dataClass1=DataClass1(), ...) {
new("MasterClass1", dataClass1=dataClass1, ...)
}
One benefit of this is that methods don't have to test whether the instance in the slot is NULL or 'DataClass1'
setMethod(length, "DataClass1", function(x) length(x#x))
setMethod(length, "MasterClass1", function(x) length(x#dataClass1))
> length(MasterClass1())
[1] 0
> length(MasterClass1(DataClass1(1:5)))
[1] 5
In response to your comment about warning users when they access 'empty' slots, and remembering that users usually want functions to do something rather than tell them they're doing something wrong, I'd probably return the empty object DataClass1() which accurately reflects the state of the object. Maybe a show method would provide an overview that reinforced the status of the slot -- DataClass1: none. This seems particularly appropriate if MasterClass1 represents a way of coordinating several different analyses, of which the user may do only some.
A limitation of this approach (or your Approach 2) is that you don't get method dispatch -- you can't write methods that are appropriate only for an instance with DataClass1 instances that have non-zero length, and are forced to do some sort of manual dispatch (e.g., with if or switch). This might seem like a limitation for the developer, but it also applies to the user -- the user doesn't get a sense of which operations are uniquely appropriate to instances of MasterClass1 that have non-zero length DataClass1 instances.
Approach 1
When you say that the names of the classes in the hierarchy are going to be confusing to your user, it seems like this is maybe pointing to a more fundamental issue -- you're trying too hard to make a comprehensive representation of data types; a user will never be able to keep track of ClassWithMatrixDataFrameAndTree because it doesn't represent the way they view the data. This is maybe an opportunity to scale back your ambitions to really tackle only the most prominent parts of the area you're investigating. Or perhaps an opportunity to re-think how the user might think of and interact with the data they've collected, and to use the separation of interface (what the user sees) from implementation (how you've chosen to represent the data in classes) provided by class systems to more effectively encapsulate what the user is likely to do.
Putting the naming and number of classes aside, when you say "difficult to extend for additional data types in the future" it makes me wonder if perhaps some of the nuances of S4 classes are tripping you up? The short solution is to avoid writing your own initialize methods, and rely on the constructors to do the tricky work, along the lines of
setClass("A", representation(x="numeric"))
setClass("B", representation(y="numeric"), contains="A")
A <- function(x = numeric(), ...) new("A", x=x, ...)
B <- function(a = A(), y = numeric(), ...) new("B", a, y=y, ...)
and then
> B(A(1:5), 10)
An object of class "B"
Slot "y":
[1] 10
Slot "x":
[1] 1 2 3 4 5
I need to deal with a two objects of a class in a way that will return a third object of the same class, and I am trying to determine whether it is better to do this as an independent function that receives two objects and returns the third or as a method which would take one other object and return the third.
For a simple example. Would this:
from collections import namedtuple
class Point(namedtuple('Point', 'x y')):
__slots__ = ()
#Attached to class
def midpoint(self, otherpoint):
mx = (self.x + otherpoint.x) / 2.0
my = (self.y + otherpoint.y) / 2.0
return Point(mx, my)
a = Point(1.0, 2.0)
b = Point(2.0, 3.0)
print a.midpoint(b)
#Point(x=1.5, y=2.5)
Or this:
from collections import namedtuple
class Point(namedtuple('Point', 'x y')):
__slots__ = ()
#not attached to class
#takes two point objects
def midpoint(p1, p2):
mx = (p1.x + p2.x) / 2.0
my = (p1.y + p2.y) / 2.0
return Point(mx, my)
a = Point(1.0, 2.0)
b = Point(2.0, 3.0)
print midpoint(a, b)
#Point(x=1.5, y=2.5)
and why would one be preferred over the other?
This seems far less clear cut than I had expected when I asked the question.
In summary, it seems that something like a.midpoint(b) is not preferred since it seems to give a special place to one point or another in what is really a symmetric function that returns a completely new point instance. But it seems to be largely a matter of taste and style between something like a freestanding module function or a function attached to the class, but not meant to be called by the insance, such as Point.midpoint(a, b).
I think, personally, I stylistically lean towards free-standing module functions, but it may depend on the circumstances. In cases where the function is definitely tightly bound to the class and there is any risk of namespace pollution or potential confusion, then making a class function probably makes more sense.
Also, a couple of people mentioned making the function more general, perhaps by implementing additional features of the class to support this. In this particular case dealing with points and midpoints, that is probably the overall best approach. It supports polymorphism and code reuse and is highly readable. In a lot of cases though, that would not work (the project that inspired me to ask this for instance), but points and midpoints seemed like a concise and understandable example to illustrate the question.
Thank you all, it was enlightening.
The first approach is reasonable and isn't conceptually different from what set.union and set.intersection do. Any func(Point, Point) --> Point is clearly related to the Point class, so there is no question about interfering with the unity or cohesion of the class.
It would be a tougher choice if different classes were involved: draw_perpendicular(line, point) --> line. To resolve the choice of classes, you would pick the one that has the most related logic. For example, str.join needs a string delimiter and a list of strings. It could have been a standalone function (as it was in the old days with the string module), or it could be a method on lists (but it only works for lists of strings), or a method on strings. The latter was chosen because joining is more about strings than it is about lists. This choice was made eventhough it led to the arguably awkward expression delimiter.join(things_to_join).
I disagree with the other respondent who recommended using a classmethod. Those are often used for alternate constructor signatures but not for transformations on instances of the class. For example, datetime.fromordinal is a classmethod for constructing a date from something other than an instance of the class (in this case, an from an int). This contrasts with datetime.replace which is a regular method for making a new datetime instance based on an existing instance. This should steer you away from using classmethod for the midpoint computation.
One other thought: if you keep midpoint() with the Point() class, it makes it possible to create other classes that have the same Point API but a different internal representation (i.e. polar coordinates may be more convenient for some types of work than Cartesian coordinates). If midpoint() is a separate function you start to lose the benefits of encapsulation and of a coherent interface.
I would choose the second option because, in my opinion, it is clearer than the first. You are performing the midpoint operation between two points; not the midpoint operation with respect to a point. Similarly, a natural extension of this interface could be to define dot, cross, magnitude, average, median, etc. Some of those functions will operate on pairs of Points and others may operate on lists. Making it a function makes them all have consistent interfaces.
Defining it as a function also allows it to be used with any pair of objects that present a .x .y interface, while making it a method requires that at least one of the two is a Point.
Lastly, to address the location of the function, I believe it makes sense to co-locate it in the same package as the Point class. This places it in the same namespace, which clearly indicates its relationship with Point and, in my opinion, is more pythonic than a static or class method.
Update:
Further reading on the Pythonicness of #staticmethod vs package/module:
In both Thomas Wouter's answer to the question What is the difference between staticmethod and classmethod in Python and Mike Steder's answer to init and arguments in Python, the authors indicated that a package or module of related functions is perhaps a better solution. Thomas Wouter has this to say:
[staticmethod] is basically useless in Python -- you can just use a module function instead of a staticmethod.
While Mike Steder comments:
If you find yourself creating objects that consist of nothing but staticmethods the more pythonic thing to do would be to create a new module of related functions.
However, codeape rightly points out below that a calling convention of Point.midpoint(a,b) will co-locate the functionality with the type. The BDFL also seems to value #staticmethod as the __new__ method is a staticmethod.
My personal preference would be to use a function for the reasons cited above, but it appears that the choice between #staticmethod and a stand-alone function are largely in the eye of the beholder.
In this case you can use operator overloading:
from collections import namedtuple
class Point(namedtuple('Point', 'x y')):
__slots__ = ()
#Attached to class
def __add__(self, otherpoint):
mx = (self.x + otherpoint.x)
my = (self.y + otherpoint.y)
return Point(mx, my)
def __div__(self, scalar):
return Point(self.x/scalar, self.y/scalar)
a = Point(1.0, 2.0)
b = Point(2.0, 3.0)
def mid(a,b): # general function
return (a+b)/2
print mid(a,b)
I think the decision mostly depends on how general and abstract the function is. If you can write the function in a way that works on all objects that implement a small set of clean interfaces, then you can turn it into a separate function. The more interfaces your function depends on and the more specific they are, the more it makes sense to put it on the class (as instances of this class will most likely be the only objects the function will work with anyways).
Another option is to use a #classmethod. It is probably what I would prefer in this case.
class Point(...):
#classmethod
def midpoint(cls, p1, p2):
mx = (p1.x + p2.x) / 2.0
my = (p1.y + p2.y) / 2.0
return cls(mx, my)
# ...
print Point.midpoint(a, b)
I would choose version one, because this way all functionality for points is stored in the point class, i.e. grouping related functionality. Additionally, point objects know best about the meaning and inner workings of their data, so it's the right place to implement your function. An external function, for example in C++, would have to be a friend, which smells like a hack.
A different way of doing this is to access x and y through the namedtuple's subscript interface. You can then completely generalize the midpoint function to n dimensions.
class Point(namedtuple('Point', 'x y')):
__slots__ = ()
def midpoint(left, right):
return tuple([sum(a)/2. for a in zip(left, right)])
This design works for Point classes, n-tuples, lists of length n, etc. For example:
>>> midpoint(Point(0,0), Point(1,1))
(0.5, 0.5)
>>> midpoint(Point(5,1), (3, 2))
(4.0, 1.5)
>>> midpoint((1,2,3), (4,5,6))
(2.5, 3.5, 4.5)