Converting enum to class, but not sure what pattern to use? - objective-c

I'm relatively new to Objective-C and I have an enum with a corresponding array of string descriptions:
typedef enum {
kCoverage = 0,
kSingulation,
kPopulation,
kDownforce,
} MapTileType;
static NSString* const kMapTileTypeString[] = {
[kCoverage] = #"Coverage",
[kSingulation] = #"Singulation",
[kPopulation] = #"Population",
[kDownforce] = #"Downforce",
};
I'm discovering that I actually need to define behavior for the "type" of map tile. For instance, I have a tile rendering behavior that applies to a specific type of map tile.
static RenderingStrategy* const kMapTileTypeRenderingStrategy[] = {
[kCoverage] = ...,
[kSingulation] = ...,
...
};
I'm wondering if all of this stuff would be better suited for a class definition for encapsulation purposes. Or would I just use a factory method that receives a MapTileType and returns a RenderingStrategy?
I was thinking that I could also perhaps just use a delegate:
#protocol MapTileDelegate <NSObject>
-(NSString*)description;
-(void)renderBlahBlah...;
#end
Can somebody help break my analysis paralysis? :)

Without knowing more, there are two approaches that sound like they might make sense:
Turn the MapTileTypes into subclasses of MapTile that implement the custom behavior you're looking for.
Create a MapTileBehavior class or something along those lines and have instances of that class take the place of your MapTileTypes values.

Related

Testing private methods in Raku

Is there a way to test private methods in Raku?
I understand that one should ideally define their tests targeting the public methods, but is there a way to do it "the wrong way"? :)
I initially thought about defining a subclass for the Testing that inherited from the class I wanted to test and do the tests there, but it seems that private methods are not inherited.
Then I saw the 'trusts' routine, but I wouldn't want to reference a Testing class on any of the classes of the code.
Is there something like changing the 'private' property of a method via introspection?
What would be the best way to call/test a private method?
This can be done using introspection.
Consider this is the class you want to test:
class SomeClass {
has Int $!attribute;
method set-value(Int $value) returns Nil {
$!attribute = $value;
return;
}
method get-value returns Int {
return $!attribute;
}
# Private method
method !increase-value-by(Int $extra) returns Nil {
$!attribute += $extra;
return;
}
}
You may create a test like this:
use Test;
use SomeClass;
plan 3;
my SomeClass $some-class = SomeClass.new;
my Method:D $increase-value = $some-class.^find_private_method: 'increase-value-by';
$some-class.set-value: 1;
$increase-value($some-class, 4);
is $some-class.get-value, 5, '1+4 = 5';
$increase-value($some-class, 5);
is $some-class.get-value, 10, '5+5 = 10';
my SomeClass $a-new-class = SomeClass.new;
$a-new-class.set-value: 0;
$increase-value($a-new-class, -1);
is $a-new-class.get-value, -1, '0+(-1) = -1; The method can be used on a new class';
done-testing;
You first create an instance of the class and the use ^find_private_method to get its private Method. Then you can call that Method by passing an instance of a class as the first parameter.
There's a more complete explanation on this answer:
How do you access private methods or attributes from outside the type they belong to?
A fresh cup of tea and #Julio's and #JJ's answers inspired the following:
class SomeClass { method !private ($foo) { say $foo } }
use MONKEY-TYPING; augment class SomeClass { trusts GLOBAL }
my SomeClass $some-class = SomeClass.new;
$some-class!SomeClass::private(42); # 42
My solution tweaks the class using monkey typing. Monkey typing is a generally dodgy thing to do (hence the LOUD pragma). But it seems tailor made for a case just like this. Augment the class with a trusts GLOBAL and Bob's your Uncle.
Raku requires the SomeClass:: qualification for this to work. (Perhaps when RakuAST macros arrive there'll be a tidy way to get around that.) My inclination is to think that having to write a class qualification is OK, and the above solution is much better than the following, but YMMV...
Perhaps, instead:
use MONKEY-TYPING;
augment class SomeClass {
multi method FALLBACK ($name where .starts-with('!!!'), |args) {
.(self, |args) with $?CLASS.^find_private_method: $name.substr: 3
}
}
and then:
$some-class.'!!!private'(42); # 42
I've used:
A multi for the FALLBACK, and have required that the method name string starts with !!!;
A regular method call (. not !);
Calling the method by a string version of its name.
The multi and !!! is in case the class being tested already has one or more FALLBACK methods declared.
A convention of prepending !!! seems more or less guaranteed to ensure that the testing code will never interfere with how the class is supposed to work. (In particular, if there were some call to a private method that didn't exist, and there was existing FALLBACK handling, it would handle that case without this monkey FALLBACK getting involved.)
It should also alert anyone reading the test code that something odd is going on, in the incredibly unlikely case that something weird did start happening, either because I'm missing something that I just can't see, or because some FALLBACK code within a class just so happened to use the same convention.
Besides using introspection, you can try and use a external helper role to access all private methods and call them directly. For instance:
role Privateer {
method test-private-method ( $method-name, |c ) {
self!"$method-name"(|c);
}
}
class Privateed does Privateer {
method !private() { return "⌣" }
}
my $obj = Privateed.new;
say $obj.test-private-method( "private" );
The key here is to call a method by name, which you can do with public and private methods, although for private methods you need to use their special syntax self!.

Can I add methods to an Objective-C enum?

In Java, I have an enum like:
public enum Toppings {
PEPPERONI,
EXTRA_CHEESE,
SECRET_SAUCE;
#Override
public String toString() {
switch(this) {
case EXTRA_CHEESE: return "Extra Cheese";
case SECRET_SAUCE: return "Secret Sauce™";
}
String name = name();
return name.charAt(0) + name.substring(1, name.length()).replace('_', ' ').toLowerCase();
}
}
I want to re-made this in Objective-C. So far, I've done this:
NS_ENUM(NSInteger, Toppings) {
PEPPERONI,
EXTRA_CHEESE,
SECRET_SAUCE
};
And then I was stumped. How would I make the toString() method? I know it's rather complex and uses some Java-specific behaviors, but I'm sure there's a way.
The only thing that comes to mind is to have a separate helper class with this functionality, but that seems a bit much, doesn't it?
Unfortunately, there is no way to add methods to an Objective-C enum. (Sidenote: you can add methods to a Swift enum.)
Traditionally, a standalone function would be used for this purpose, with a body similar to your Java method:
NSString* NSStringFromToppings(Toppings toppings)
{
switch (toppings)
{
case PEPPERONI: return #"Pepperoni";
case EXTRA_CHEESE: return #"Extra Cheese";
case SECRET_SAUCE: return #"Secret Sauce";
}
}
(Sidenote: you should name your enum Topping instead of Toppings--you can see how the code above would be clearer with a singular type name. You should also add a two- or three-letter prefix to all your type names (and this function) to avoid naming collisions.)
NSString * const ToppingsList[] = {
[PEPPERONI] = #"Pepperoni",
[EXTRA_CHEESE] = #"Extra Cheese",
[SECRET_SAUCE] = #"Secret Sauce",
};
NSLog("Topping: %#", ToppingList[PEPPERONI]);
After declaring your enum, you can add this to use type string. It seems like toString() method
EDIT: Meanwhile #andyvn22 is right. There is no way to add methods to enums in Objective-C. I just gave a solution for using enums with string.
Yeah, it's not as straightforward as in, say, Java or .NET. However, I think that option 2 of yar1vn's answer looks ok:
Convert objective-c typedef to its string equivalent
You could also add enum serialization as an NSString extension, making it possible to ask NSString to give you a string based on your enum.
No, there is no way to declare a method in an enum using Objective-C.
However, you can use an enum as a parameter to any method. This might be a solution for you:
typedef NS_ENUM(int, PatientActivity)
{
Exercise = 101,
Smoke,
Alcohol
};
- (void)getPatientDetail:(NSString *)PatID withActivity:(enum PatientActivity) activity;

Chain up to 'Gtk.Box.new' not supported

I'm new to Vala and so far I think it's pretty cool but I'm having trouble understanding inheritance. I read here that I should use base() to call the parents constructor. Alright, cool, seems understandable but It din't work for me. I kept getting the error on the title. Here is my snippet to show:
public class MyBox : Gtk.Box {
public MyBox(Gtk.Orientation orientation, int spacing) {
// I have to this
this.set_orientation(orientation);
this.set_spacing(spacing);
// I want to do this:
base(orientation, spacing);
//workaround is this:
Object(orientation: orientation, spacing: spacing);
}
}
Please help me understand why Object(....) works but not base(...)
Shouldn't it be the same thing?
This is due to implementation of the C code. When Vala generates a constructor, it generates two C functions a _new function that allocates memory and calls the _construct and a _construct function that initialises the object. When you case the base constructor using base(), it needs a matching _construct function to call. Not all the classes written in C have this; in the VAPI file, you will find has_construct_function = false for some constructors. If this is the case, no chain-up can be done. The base GObject can set properties from arguments, so this becomes the only way to set defaults in the base class.

Reducing the number of arguments to a constructor

I am reading "Clean Code" and having trouble figuring out how to keep some of my functions (usually constructors) to their MAXIMUM of 3 parameters.
Often my objects need an awful lot of information to work - am I supposed to make a small constructor and then use mutator functions to give them all of the information? This doesn't seem any better than just using a big constructor.
As an example, I have a "MovablePatch" class. It lets the user drag a square around in a window. It needs a several parameters, including Radius, Color, Renderer, InitialPosition, and Visibility. Currently I collect all of these from my GUI and then call:
MovablePatch(int radius, Renderer* renderer, Color color, Position initial, bool visibility)
These are only some of the things that I need in this class. Can anyone suggest how else I might package this information to pass to the constructor? I don't see any obvious "break it into smaller classes" appearing here.
You could have
MovablePatch(Renderer* renderer, CircleAppearance circleAppearance)
where CircleAppearance gathers the other info.
However, clean code and other books that generalize about what good code should look like, are aiming for 80 percent of the code out there. Your code seems to be "closer to the metal" than the typical LoB (Line of Business) variety. As such, you may run into places where certain coding ideals are not applicable.
The most important part is that you're thinking about it and trying to keep things nice and tidy! :)
Do not take maxims like "thou shalt not have more than 3 parameters in thy constructors" at face value. If you have the slightest chance of making an object immutable, make it; and if it being immutable means that it is going to have a constructor with 50 parameters, so be it; go for it; don't even think about it twice.
Even if the object is going to be mutable, still, you should pass its constructor as many parameters as necessary so that immediately upon construction it will be in a valid and meaningful state. In my book, it is absolutely impermissible to have to know which are the magic mutator methods that have to be called (sometimes even in the right order) before any other methods can be invoked, under penalty of segfault.
That having been said, if you would really like to reduce the number of parameters to a constructor, or to any function, simply pass this method an interface that it can invoke to get from it the stuff it needs in order to work.
Some of the things you are passing in could be abstracted into a larger construct. For example, visibility, color, and radius, could make sense to be placed into an object that you define. Then, an instance of this class, call it ColoredCircle, could be passed into the constructor of MovablePatch. A ColoredCircle doesn't care where it is or what renderer it is using, but a MovablePatch does.
My main point, is that from an OO perspective, radius isn't really an integer, it's a radius. You want to avoid these long constructor lists because it is daunting to understand the context of these things. If you collect them into a larger class, kind of like how you already have with Color and Position, you can have fewer parameters passed in and make it easier to understand.
The Named Parameter Idiom is useful here. In your case, you might have
class PatchBuilder
{
public:
PatchBuilder() { }
PatchBuilder& radius(int r) { _radius = r; return *this; }
PatchBuilder& renderer(Renderer* r) { _renderer = r; return *this; }
PatchBuilder& color(const Color& c) { _color = c; return *this; }
PatchBuilder& initial(const Position& p) { _position = p; return *this; }
PatchBuilder& visibility(bool v) { _visibility = v; return *this; }
private:
friend class MovablePatch;
int _radius;
Renderer* _renderer;
Color _color;
Position _position;
bool _visibility;
};
class MovablePatch
{
public:
MovablePatch( const PatchBuilder& b ) :
_radius( b._radius );
_renderer( b._renderer );
_color( b._color );
_position( b._position );
_visibility( b._visibility );
{
}
private:
int _radius;
Renderer* _renderer;
Color _color;
Position _position;
bool _visibility;
};
then you use it like so
int
main()
{
MovablePatch foo = PatchBuilder().
radius( 1.3 ).
renderer( asdf ).
color( asdf ).
position( asdf ).
visibility( true )
;
}
overly simplified, but I think it gets the point across. If certain parameters are required they can be included in the PatchBuilder constructor:
class PatchBuilder
{
public:
PatchBuilder(const Foo& required) : _foo(required) { }
...
};
Obviously this pattern degenerates into the original problem if all arguments are required, in which case the named parameter idiom isn't applicable. The point being, this isn't a one size fits all solution, and as Adam describes in the comment below there are additional costs and some overhead with doing so.
One good option is to use a Builder pattern, where each "setter" method returns the own instance, and you can chain the methods as you need.
In your case, you will get a new MovablePatchBuilder class.
The approach is very useful and you can find it in many different frameworks and languages.
Refer here to see some examples.

Best design for lookup-and-possibly-change method

I am designing a class that stores (caches) a set of data. I want to lookup a value, if the class contains the value then use it and modify a property of the class. I am concerned about the design of the public interface.
Here is how the class is going to be used:
ClassItem *pClassItem = myClass.Lookup(value);
if (pClassItem)
{ // item is found in class so modify and use it
pClassItem->SetAttribute(something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However I don't want to have to expose ClassItem to this client (ClassItem is an implementation detail of MyClass).
To get round that the following could be considered:
bool found = myClass.Lookup(value);
if (found)
{ // item is found in class so modify and use it
myClass.ModifyAttribute(value, something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However this is inefficient as Modify will have to do the lookup again. This would suggest a lookupAndModify type of method:
bool found = myClass.LookupAndModify(value, something);
if (found)
{ // item is found in class
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
But rolling LookupAndModify into one method seems like very poor design. It also only modifies if value is found and so the name is not only cumbersome but misleading as well.
Is there another better design that gets round this issue? Any design patterns for this (I couldn't find anything through google)?
Actually std::set<>::insert() does precisely this. If the value exists, it returns the iterator pointing to the existing item. Otherwise, the iterator where the insertion was made is returned.
It is likely that you are using a similar data structure for fast lookups anyway, so a clean public interface (calling site) will be:
myClass.SetAttribute(value, something)
which always does the right thing. MyClass handles the internal plumbing and clients don't worry about whether the value exists.
Two things.
The first solution is close.
Don't however, return ClassItem *. Return an "opaque object". An integer index or other hash code that's opaque (meaningless) to the client, but usable by the myClass instance.
Then lookup returns an index, which modify can subsequently use.
void *index = myClass.lookup( value );
if( index ) {
myClass.modify( index, value );
}
else {
myClass.add( value );
}
After writing the "primitive" Lookup, Modify and Add, then write your own composite operations built around these primitives.
Write a LookupAndModify, TryModify, AddIfNotExists and other methods built from your lower-level pieces.
This assumes that you're setting value to the same "something" in both the Modify and Add cases:
if (!myClass.AddIfNotExists(value, something)) {
// use myClass
}
Otherwise:
if (myClass.TryModify(value, something)) {
// use myClass
} else {
myClass.Add(value, otherSomething);
}