I am looking for a general consensus or opinions on With vs For as in things like:
-(NSImage *)imageWithStyle:(MyImageStyle)style
-(NSImage *)imageForStyle:(MyImageStyle)style
-(id)controllerWithView:(NSView *)view
-(id)controllerForView:(NSView *)view
Thoughts?
When you use one over the other and why?
I tend to work on the basis that if A has no relation to B, but aspects of B might change what A will do, then you're making an A with information from B.
If A has some relation to B, e.g. B has a way of listing all the A's that are associated with it, then I'll be making an A for (on behalf of) B.
The controller is a good example. If it's a controller being made with a view, it implies that the controller isn't "for" anything, it's just some controller, but it's using bits or all of a view to do Things. But if it's a controller for a view, then now we've implied a permanent association - this is a controller that is for, i.e. that controls, the view. So here, I'd use controllerForView.
In the image and style example, I imagine your intent is that some object describes default aspects of the images being built. I'd use imageWithStyle. Everyone likes an image with style... ;-)
It's subtle either way though. You could consider less conventional but clearer terms if you think there is ambiguity - e.g imageFromTemplate or imageBasedOnStyle. Cocoa tends to be more about almost-English legibility and less about being terse.
Related
E.g. let’s consider I have the following classes:
Item
ItemProperty which would include objects such as Colour and Size. There's a relation-property of the Item class which lists all of the ItemProperty objects applicable to this Item (i.e. for one item you might need to specify the Colour and for another you might want to specify the Size).
ItemPropertyOption would include objects such as Red, Green (for Colour) and Big, Small (for Size).
Then an Item Object would relate to an ItemProperty, whereas an ItemChoice Object would relate to an ItemPropertyOption (and the ItemProperty which the ItemPropertyOption refers to could be inferred).
The reason for this is so I could then make use of queries much more effectively. i.e. give me all item-choices which are Red. It would also allow me to use the Parse Dashboard to quickly add elements to the site as I could easily specify more ItemPropertys and ItemPropertyOptions, rather than having to add them in the codebase.
This is just a small example and there's many more instances where I'd like to use classes so that 'options' for various drop-downs in forms are in the database and can easily be added and edited by me, rather than hard-coded.
1) I’ll probably be doing this in a similar way for 5+ more similar kinds of class-structures
2) there could be hundreds of nested properties that I want to access via ‘inverse querying’
So, I can think of 2 potential causes of inefficiency and wanted to know if they’re founded:
Is having lots of classes inefficient?
Is back-querying against nested classes inefficient?
The other option I can think of — if ‘class-bloat’ really is a problem — is to make fields on parent classes that, instead of being nested across other classes (that represent further properties, as above), just representing them as a nested JSON property directly.
The job of designing is to render in object descriptions truths about the world that are relevent to the system's requirements. In the world of the OP's "items", it's a fact that items have color, and it's a relevant fact because users care about an item's color. You'd only call a system inefficient if it consumes computing resources that it doesn't need to consume.
So, for something like a configurator, the fact that we have items, and that those items have properties, and those properties have an enumerable set of possible values sounds like a perfectly rational design.
Is it inefficient or "bloated"? The only place I'd raise doubt is in the explicit assertion that items have properties. Of course they do, but that's natively true of javascript objects and parse entities.
In other words, you might be able to get along with just item and several flavors of propertyOptions: e.g. Item has an attribute called "colorProperty" that is a pointer to an instance of "ColorProperty" (whose instances have a name property like 'red', 'green', etc. and maybe describe other pertinent facts, like a more precise description in RGB form).
There's nothing wrong with lots of classes if they represent relevant truth. Do that first. You might discover empirically that your design is too resource consumptive (I doubt you will in this case), at which point we'd start looking for cheats to be somehow skinnier. But do it the right way first, cheat later only if you must.
Is having lots of classes inefficient?
It's certainly inefficient for poor humans who have to remember what all those classes do and how they're related to each other. It takes time to write all those classes in the first place, and every line that you write is a line that has to be maintained.
Beyond that, there's certainly some cost for each class in any OOP language, and creating more classes than you really need will mean that you're paying more than you need to for the work that you're doing, which is pretty much the definition of inefficient.
I’ll probably be doing this in a similar way for 5+ more similar kinds of class-structures
Maybe you could spend some time thinking about the similarity between these cases and come up with a single set of more flexible classes that you can use in all those cases. Writing general code is harder than writing very specific code, but if you do a good job you'll recoup the extra effort many times over through reuse.
I am working on a project build on the Zend Framework. I'm using Zend_Translate to do my translations, but I want to keep the amount of extra code in the front of my application (views) as minimal as possible. Translation of a text should look like this:
echo __("Text to translate");
Using a view helper isn't doing it, because then I get:
echo $this->__("Text to translate");
This would mean I have to declare a global function somewhere, that calls for Zend_Translate to do the rest of the magic. Because I want the project to stay as clean as possible I'd like some suggestions on where to put this function.
I have considered including a file with my global function inside of the _initLocale() in the bootstrap.
Basically my question is: am I now violating all the holy MVC principles, or is this the right way to go?
This is actually not an easy question to answer. Of course you're violating some principles of OOP because you're basically punctuating your objects with hundreds of little wholes where there should be just one. You should be injecting the translation object into your controllers and views once and then call $this->__(). This is also easily done by creating an intermediate layer between Zend_Controller_Action and your own controllers. BUT... translation is a very specific case and I don't see much potential harm coming from your solution. The Translation method is not likely to change its logics and if you need to rename it, finding and replacing two underscores followed by a bracket will most probably not yield anything else than translated strings... then again that use of 'most probably' is a smell already.
Summary: It seems more or less ok but I still wouldn't do it, especially if it's a software of some meaning with an expected life span of some years.
This is probably another thick, newbie question that will have everyone smacking their foreheads and going 'Duhhhhh!' BUT, after another long spell of reading and watching countless Brad Larson videos, I'm left perplexed at why delegation in general and CALayer delegation in particular seems to be such an enigmatic theme.
All the books and Dr Larson bang on about 'not sub-classing CALayers' unless you want a high degree of encapsulation but nowhere have I found a succinct and to-the-point example of the benefits that CALayer delegation can offer. Everyone seems to use either, the host view controller object as a, sort-of, perfunctory delegate or they shovel everything into the App delegate "as a brief example of what can be achieved".
I'm trying to learn "BEST PRACTICE" up-front - because I'm so new and because I don't want to develop any bad or slovenly programming traits - so I'm keen to examine each new step I take in minute detail. From what I can gather, a CALayer delegate class only has about 3 delegate-specific methods in it. These are 'displayLayer:', 'drawLayer:InContext:' and 'actionForLayer:ForKey:'. In my Opacity-generated Quartz stuff, I have used colour variables which I want to manipulate at runtime and do so without sub-classing CALayer. One of the side-effects of using Key-Value pairs is that there exists a class method called 'defaultValueForKey:' which describes the initial value of my colours according to the key value used to identify them. This is NOT (apparently) a CALayer delegate method. So how can I implement this code (which, after, all only sets a default value) without sub-classing CALayer? It seems that delegation is OK as long as you only need the few delegate-specific methods.
Could anyone explain why, when implementing delegation, the boffins at Apple didn't simply transpose the method-definition compilation unit from the class unit to the assigned delegate unit. e.g. Simply place an initial parameter in front of every method usually available in the class (or sub-class) by the phrase; 'forLayer: (CALayer *) TheRest: OfThe: method'? This way a simple switch or if-then stack could apply the usual method-ry of the class in one centralised object - the delegate.
As I said at the beginning, I'm probably missing something pretty basic but could anyone tell me how I implement all my key-value colour variable inits without sub-classing CALayer?
Thanks in advance,
V.V.
You're over thinking it all. As you mentioned, you're new to the platform. There are many idioms in Cocoa, but one of the idioms is a bit like Perl: "there's more than one way to do it".
Cocoa has a history of delegation because much of the time, you just need a method or two, and who wants the complexity of a zillion classes with few methods. Delegates let you work around that in a simple way.
So, basically rather than analyzing everything from the overall engineering point of view, just use the platform. Write some code. Write some code the "wrong way". Write lots of it.
Why? Because if it's the "wrong way", you will feel it yourself. You'll start cursing it in maintenance or whatever, and then you'll figure out the "right way". What is the "right way"? The way that feels better for YOU.
Most of these decisions have minimal impact on performance, etc., so don't worry about it. And because of that, it doesn't really matter which technique you choose.
Write code. Write lots of it. The more you write the more you'll get a feel as to when what technique is right, and which one is wrong. Or when the right way before now becomes the wrong way and should be refactored in to the new right way.
Because what's right or wrong now may not be later.
I've been reading this paper: Enforcing Strict Model-View Separation in Template Engines (PDF).
It contends that you only need four constructs within the views:
attribute reference
conditional template inclusion based upon presence/absence of an attribute
recursive template references
template application to a multi-valued attribute similar to lambda functions
and LISP’s map operator
No other logic is allowed within the view - for example if (attr < 5) would not be allowed, only if (valueLessThanFive)
Is this reasonable? Most MVC frameworks allow any logic within the views, which can lead to business logic creeping into the view. But is it really possible to get by with only those four constructs?
For "zebra striped" tables, the paper suggests mapping a list of templates onto the list of data - for example:
map(myList, [oddRowTemplate, evenRowTemplate])
But what if you want to make the first and last rows different styles? What if the 3rd row should be purple on Tuesdays because your graphic designer is mad? These are view-specific (for example if I was outputting the same data as XML I wouldn't use them) so don't seem to belong in the model or controller.
In summary:
Do you need logic above the four constructs listed above within views?
If so, how do you restrict business logic creeping in?
If not, how would you make the 3rd row purple on Tuesdays?
Terence Parr is a very smart guy and his paper has much to commend it, but from a practical point of view I have found using just these constructs somewhat limiting.
It is difficult to prevent business logic creeping in especially if you have the ability to do anything, as for example ASP.NET and JSP would give you. It boils down to how you spend your time:
Allow limited additional functionality (I'm not an advocate for "anything goes") and use code review mechanisms to ensure correct usage, or
Restrict to the four constructs above, and spend more time providing attributes like valueLessThanFive (remembering to rename it to valueLessThanSix when the business requirement changes, or adding valueMoreThanThree - it's a bit facetious as an example but I think you'll know what I'm getting at).
In practice, I find that allowing conditionals and looping constructs is beneficial, as is allowing property traversal such as attr[index].value in template expressions. That allows presentational logic to be effectively managed, while incurring only a small risk of misuse.
Allowing more functionality such as arbitrary method calls gets progressively more "dangerous" (in terms of facilitating misuse). It comes down, to some extent, to the development culture in place in your environment, the development processes, and the level of skill and experience in your team.
Another factor is whether, in your environment, you have the luxury of enforcing strict separation of work between presentation and logic, in terms of having dedicated non-programmer designers who would be fazed by advanced constructs in the template. In that event, you would likely be better off with the more restricted template functionality.
To answer your question about the 3rd row purple on Tuesdays:
The original (or one of the very early) MVC patterns had the 'View' being a data-view, there was no concept of a UI in the pattern. Modern versions of the MVC pattern have felt the need for this data-view which is why we have things like MVVM, MVP, even MV-poo. Once you can create a 'view' of your data that's specific to the UI View it's easier to solve lots of the concerns.
In our case our 'model' is going to get extra properties on it, such as Style or Colour (style is better as it still lets the view define how that style is represented). The controller will take raw 'model' items and present to the view custom 'model' items with this extra Style, giving the 3rd row on Tuesdays a style of 'MadDesignerSpecial', which the view uses to apply the purple colour.
I'm thinking of writing a CLI Monopoly game in Ruby. This would be the first large project I've done in Ruby. Most of my experience in programming has been with functional programming languages like Clojure and Haskell and such. I understand Object Orientation pretty well, but I have no experience with designing object oriented programs.
Now, here's the deal.
In Monopoly, there are lots of spaces spread around the board. Most spaces are properties, and others do other things.
Would it be smart to have a class for each of the spaces? I was thinking of having a Space class that all other spaces inherit from, and having a Property class that inherits from Space, and then having a class for every property that inherits from Property. This would mean a lot of classes, which leads me to believe that this is an awful way to do what I'm trying to do.
What I also intended to do, was use the 'inherited' hook method to keep track of all the properties, so that I could search them and remove them from the unbought list when needed.
This sort of problem seems to arise in a lot of programs, so my question is: Is there a better way to do this, and am I missing something very crucial to Object Oriented design?
I'm sorry if this is a stupid question, I'm just clueless when it comes to OOPD.
Thanks.
You're on the right track, but you've gone too far, which is a common beginner's mistake with OOP. Every property should not be a separate class; they should all be instances of the Property class. I'd do classes with attributes along these lines:
Space
Name
Which pieces are on it
Which space is next (and maybe previous?)
Any special actions which take place when landing on it
Property (extends Space)
Who owns it
How many houses/hotels are on it
Property value
Property monopoly group
Rent rates
Whether it is mortgaged
So, for example, Boardwalk would be an object of type Property, with specific values that apply to it, such as belonging to the dark blue monopoly group.
Classes for spaces is probably not a bad idea; but let's see why that's the case.
If you were writing this in a procedural language, where would the majority of the 'if' and 'switch' statements be? They'd be in determining what happened to each player when they landed on a space. In OO, we want to prevent as many if/switch statements as possible, and replace them with polymorphism. So, clearly, if we create many derivatives of Space, we will prevent a large number of if/switch statements.
But before we make that leap, let's look at the metaphor of the game. The game is all about a city. Addresses, streets, utilities, public works, jails, etc. Each square on the board represents some kind of location in the city. Indeed the players travel through the city paying rent (or some other action) anywhere they happen to land.
So let's call the spaces, CityBlocks. Each CityBlock has an address, like "Boardwalk" or "Electric Company", or "Community Chest". Are there different types of CityBlock objects? Or should we simply consider CityBlocks to be locations that have a certain kind of ZoningOrdinance?
I kind of like that. |CityBlock|---->|ZoningOrdinance|
Now we could have several different derivatives of ZoningOrdinance. This is the "Strategy" Pattern. I rather like the flexibility this give us, and the separation of 'where' and 'what' that it provides.
You'll also need a Game class that understand the rules of dice, tokens, FreeParking, Passing Go, etc. That class will manipulate the players, and invoke the methods on CityBlock. CityBlock will invoke methods on ZoningOrdinance.
Anyway, that's one way...