You have a Page class. This class naturally has all the methods and variables to deal with single page objects, create(), update(), delete(), and so on.
From an OOP architecture stand point, what would be the best practice for dealing with a significant number of manipulators for groups of this object?
Large quantities of operations such as : listAllPages(), getRecentPages(), getTop10Pages(), deleteAllPagesFromAuthor()
A few points to consider :
Since we are dealing with multiples, it would not make sens to put those methods in the class... after all, it would not be logical for a single page to manipulate all the other pages.
On the other hand, making all these operations into separate, "free floating" helper functions would be disorganized. That's what I usually do if i have only a couple of functions, but when I get a large quantity of them I keep thinking there must be a better OOP way to keep things organized logically.
I thought about creating a "Pages" class (plural), but I am not sure if structuring my application to consider plural of an object as an object makes sens on the long term.
Is there a best practice in this area? Or to be specific, what would be the optimal way to implement those group helpers for my Page object?
Related
I am trying to develop a card game with Kotlin, but I feel like the complex architecture decisions I feel I have to make are stalling my process.
I would like to create a solid and flexible foundation for potentially dozens of different cards with different effects, of different types (e.g. spell, vehicle, weapon...).
Intuitively I feel like giving each different Card its own subclass would be ridiculous for several reasons, such as the loss of flexibility (can't (without crazy hacks) create new kinds of cards dynamically) and escalating complexity.
On the other hand, there will be different categories of cards (types) which generally have more in common with each other than cards - so it feels like I should definitely subclass Card because otherwise I would end up with Type enums (SPELL, WEAPON, VEHICLE...) and ugly switch-statements replacing what's usually dealt with by inheritance and polymorphism.
I initially had problems conceiving how to access specific behaviors of subclasses who live in collections of superclasses, but I now understand how I can solve this using the visitor pattern - all fine so far.
My problem now is this architectural approach seems to conflict with other things I have planned and which I consider necessary or at least very worthwhile to have:
Hybrid of Prototype-Flyweight-Pattern:
I have created a 'cyclopedia' of prototype cards that can be copied. Cards consist of a shared static part and a unique dynamic part:
Naturally, I would like to create subinstances of the identifying components in the following manner:
Doing this doesn't seem to be possible in a satisfying way no matter how I approach it. There are many solutions but all seem like weak compromises to me:
Doing it the way I described it means subclasses have to save
multiple references to their components; a baseclass and one subclass
one for each. It also leads to an ugly situation where type
attributes are spread over several component-classes all dependent on
each other.
Using interfaces instead of inheritance leads to loads of code duplication.
Subclassing only the components but not card itself hides type information in the innards of cards and also demands ugly reflection
for accessing subclass traits.
Implementing a data-equivalent of type-information instead of subclassing to circumvent the limiting rules of Kotlin inheritance
hierarchies seems to be hacky and removes IDE support.
I am sure there are even more approaches I have considered over the course of the last two weeks, but these are all I can remember right now.
I know that you probably would require more complete information on what I am planning to do to give me concrete answers, but since it's too complex and I don't know all about where this is going either, I am satisfied with rough ideas in the sense of 'consider this' or 'whatever you are doing, stay away from this' or general advice about how to deal with such a 'design crysis' where things seem so complex you don't know how to start.
Of course I am ready to elaborate or detail parts of my description if it becomes necessary.
Just thinking here.
What about creating a BaseCard class with Card low-level common parts, then a class for each category that inherits from BaseCard, named like Category, where you store each category common parts, and then classes CardofSomeType inheriting from its respective Category. So in a CardofSomeType you inherit anything relevant from either class, and you just add new Card(s)ofSomeType(s) to extend your set.
About what data is instance specific or shared in the class, that's orthogonal to this and an implementation detail of each class.
I'm working on an iPhone game that has a bunch of monsters. Each monster has a name, up to 4 different attacks, and a few sprites that represent its state. I have a monster class set up and it works really well. I've managed to make two monsters battle and all that jazz and it works. My game though is going to have a predefined group of monsters in it that all have different statistics and I'm kind of struggling to come up with the best way to accomplish this. I have two ideas so far.
Ideas:
Make a class whose only purpose is to define all the monsters available in the game using the Monster class.
Subclass the monster class for each and every monster I need. Even though none of them will really add anything to the monster class.
The benefits for the second method are that it would be easier to make ties between two different monsters (like evolution trees).
What do you guys think would be the best way to do this? I'm leaning towards the second method. Is the another method that I'm missing?
A common pattern for this sort of problem is to create a factory class, which is close to your first idea. You make a single class, called perhaps MonsterFactory, whose job it is to manufacture instances of the Monster class for use elsewhere. If you structure the factory properly, it can even handle the evolution-tree sort of thing well.
An additional benefit of a factory is that it abstracts away the details of storing information about your monsters. For example, you could hardcode the first five or ten monsters' worth of info into the program to test it, but later reimplement the factory to use a database or file on disk for larger volumes of monsters. As long as your factory API remains constant, your Monster class doesn't have to care about those details; it's all in the factory.
Even though none of them will really add anything to the monster class.
The benefits for the second method are that it would be easier to make ties between two different monsters (like evolution trees)
Answered your own question.
I'm using OOP to write small games with different types of characters (e.g. platformers, shooters) that do different types of things. I typically try to spread out functionality into easily manageable, simple classes (e.g. an Environment class would perform common physics calculations for all its Inhabitants, so they don't need to worry about that). But, it seems that the more I refactor these programs to align with OOP principles, the heavier my character objects get. Since they're the ones with the important data, they use their own data to perform functions on themselves. This keeps them decoupled from things outside of their realm, but makes their classes seem to grow and grow. I'm totally comfortable with breaking these character classes down into more manageable components, but I worry that having many objects onscreen that are instantiated from classes with a lot of methods will result in a slow-running game.
1) Do the number of instance methods on an object directly impact its runtime performance?
2) Am I using OOP correctly if I end up with heavy character objects?
No. Or at least mostly no, anyway.
Maybe, but probably not.
For a character-based game, it's perfectly reasonable that a character would have a lot of associated data. Efficiency is rarely affected by representing that as a single "flat" collection of primitive objects, or a tree-like collection of a few large objects, each of which (recursively) has a number of smaller constituent parts.
As far as number of methods affecting performance: the number of methods can affect cache utilization, especially if you have (for example) lots of extremely small methods, and heavily-used methods are more or less interleaved with less used ones, so you end up with a lot of cache space devoted to less-used methods because they happen to be in the same cache line with something that's used more. Being methods affects this primarily because a compiler will typically arrange methods of the same class close to each other in memory, so sharing cache lines becomes more common. At least with typical implementations, however, calling a method will be O(1), so the number of methods doesn't directly affect speed.
No, its not what methods you have in an object, but what you do with them that increases runtime cost. Ofcourse there is a limit to this, but with current hardware you can completely forget about it. However, it is often questionable to go beyond a dozen or two members in a class from a design standpoint. Splitting your objects up doesn't need to incur any significant cost, you can inline all your getters and setters, and pass values by pointers and references. The compiler can flatten all your design decisions out and mostly the code from a "heavy" class is equivalent to code from a constellation of small classes
Correctly in this context is entirely dependant on the taste of the people developing the code. The processor doesn't care about what software engineering design decisions you make. If you wan't to make you objects all encompassing and it feels right to you then do it. There might come a point where things don't feel "right" to you, at that point you might split things up.
I have a very limited understanding of OOP.
I've been programming in .Net for a year or so, but I'm completely self taught so some of the uses of the finer points of OOP are lost on me.
Encapsulation, inheritance, abstraction, etc. I know what they mean (superficially), but what are their uses?
I've only ever used OOP for putting reusable code into methods, but I know I am missing out on a lot of functionality.
Even classes -- I've only made an actual class two or three times. Rather, I typically just include all of my methods with the MainForm.
OOP is way too involved to explain in a StackOverflow answer, but the main thrust is as follows:
Procedural programming is about writing code that performs actions on data. Object-oriented programming is about creating data that performs actions on itself.
In procedural programming, you have functions and you have data. The data is structured but passive and you write functions that perform actions on the data and resources.
In object-oriented programming, data and resources are represented by objects that have properties and methods. Here, the data is no longer passive: method is a means of instructing the data or resource to perform some action on itself.
The reason that this distinction matters is that in procedural programming, any data can be inspected or modified in any arbitrary way by any part of the program. You have to watch out for unexpected interactions between different functions that touch the same data, and you have to modify a whole lot of code if you choose to change how the data is stored or organized.
But in object-oriented programming, when encapsulation is used properly, no code except that inside the object needs to know (and thus won't become dependent on) how the data object stores its properties or mutates itself. This helps greatly to modularize your code because each object now has a well-defined interface, and so long as it continues to support that interface and other objects and free functions use it through that interface, the internal workings can be modified without risk.
Additionally, the concepts of objects, along with the use of inheritance and composition, allow you to model your data structurally in your code. If you need to have data that represents an employee, you create an Employee class. If you need to work with a printer resource, you create a Printer class. If you need to draw pushbuttons on a dialog, you create a Button class. This way, not only do you achieve greater modularization, but your modules reflect a useful model of whatever real-world things your program is supposed to be working with.
You can try this: http://homepage.mac.com/s_lott/books/oodesign.html It might help you see how to design objects.
You must go though this I can't create a clear picture of implementing OOP concepts, though I understand most of the OOP concepts. Why?
I had same scenario and I too is a self taught. I followed those steps and now I started getting a knowledge of implementation of OOP. I make my code in a more modular way better structured.
OOP can be used to model things in the real world that your application deals with. For example, a video game will probably have classes for the player, the badguys, NPCs, weapons, ammo, etc... anything that the system wants to deal with as a distinct entity.
Some links I just found that are intros to OOD:
http://accu.informika.ru/acornsig/public/articles/ood_intro.html
http://www.fincher.org/tips/General/SoftwareEngineering/ObjectOrientedDesign.shtml
http://www.softwaredesign.com/objects.html
Keeping it very brief: instead of doing operations on data a bunch of different places, you ask the object to do its thing, without caring how it does it.
Polymorphism: different objects can do different things but give them the same name, so that you can just ask any object (of a particular supertype) to do its thing by asking any object of that type to do that named operation.
I learned OOP using Turbo Pascal and found it immediately useful when I tried to model physical objects. Typical examples include a Circle object with fields for location and radius and methods for drawing, checking if a point is inside or outside, and other actions. I guess, you start thinking of classes as objects, and methods as verbs and actions. Procedural programming is like writing a script. It is often linear and it follows step by step what needs to be done. In OOP world you build an available repetoire of actions and tasks (like lego pieces), and use them to do what you want to do.
Inheritance is used common code should/can be used on multiple objects. You can easily go the other way and create way too many classes for what you need. If I am dealing with shapes do I really need two different classes for rectangles and squares, or can I use a common class with different values (fields).
Mastery comes with experience and practice. Once you start scratching your head on how to solve particular problems (especially when it comes to making your code usable again in the future), slowly you will gain the confidence to start including more and more OOP features into your code.
Good luck.
When developing how useful is it to create small classes to represent little data structures? For example say as a simplified example, a program is using an array of strings to represent names of something, e.g. cars. Instead of just keeping this array inside a method or class, how useful is it to separate this and make it it own class? This way I am thinking that it can be responsible for itself and more actions can be performed on it - validation, etc. which can all be kept separate. Also, it can be reused easily throughout the system. But then where does it stop, i.e. in the car example, you could then go on to create a car object etc. It really can be never ending can't it?
There are several guidelines I use to determine when I need to refactor a data structure into its own class:
Am I storing a lot of interrelated data? If you find yourself storing a couple of arrays, and manipulating them as a unit, it's probably best to store a single array containing objects.
Are these data structures exposed to other classes? If other classes are directly exposed to the data, it's probably best to encapsulate the data in its own class, which makes it easy to keep the conceptual and actual models separate.
Do I find myself frequently performing operations on the data? It might be fine to store an array of names, but if you start adding methods like validateName and checkName to the wrapping class, it might be a good idea to refactor and place those methods on a Name class itself.
Keep in mind: it's often a lot easier and cleaner to put a decent object model in place up front than to try and graft one on after the fact. You shouldn't do it arbitrarily, but as you're working through your program you should pay attention to when it becomes difficult to control the data structures you have--that's a good sign that you should refactor them, as needed.
It makes sense to do this as soon as you are repeating code to operate on the data structure.
Chris B. makes a great point about interrelated data. See the Extract Class refactoring example.