I'm still studying OOP designs, so what's the best way to achieve an inventory for a simple flash game ? It seems that more than one design pattern could deliver some kind of an invetory but I would lose the flexibility if I try to adapt it somehow without a good knowledge about the subject.
For money to buy what is available in an inventory I thought of Singleton. If there's enough cash earned while playing the game, then one can buy new skills.
Maybe decorator pattern could list many thumbnails as buttons, and clicking on it applies new features and skills to the character.
I'd like to read standard advices on solving this problem, because I feel I'm on the wrong way. Thanks.
Stay away from singleton if possible
Singleton has its uses, however I believe it's overused in a lot of cases.
The biggest problem with a singleton is that you're using Global State, which is generally regarded as a bad thing as when complexity in your software grows it can cause you to have unintended side effects.
Object composition might be a better way
For games you might want to take a look at using Object Composition rather than traditional OOD Modelling.
A software component is a software element that conforms to a
component model and can be independently deployed and composed without
modification according to a composition standard.
A component model defines specific interaction and composition
standards. A component model implementation is the dedicated set of
executable software elements required to support the execution of
components that conform to the model.
A software component infrastructure is a set of interacting software
components designed to ensure that a software system or subsystem
constructed using those components and interfaces will satisfy clearly
defined performance specifications.
Component based game engine design
http://www.as3dp.com/2009/02/21/design-pattern-principles-for-actionscript-30-favor-object-composition-over-class-inheritance/
Reading over the material in the first link should give you some excellent ideas on how to model your inventory system and have it extendable in a nice way.
Related
I'm looking to get some good books on design patterns and I'm wondering what particular pattern you'd recommend for a Realtime Strategy Game (like Starcraft), MVC?.
I'd like to make a basic RTS in Flash at some point and I want to start studying the best pattern for this.
Cheers!
The problem with this kind of question is the answer is it completely depends on your design. RTS games are complicated even simple ones. They have many systems that have to work together and each of those systems has to be designed differently with a common goal.
But to talk about it a little here goes.
The AI system in an rts usually has a few different levels to it. There is the unit level AI which can be as simple as a switch based state machine all the way up to a full scale behavior tree (composite/decorators).
You also generally need some type of high level planning system for the strategic level AI. (the commander level and the AI player)
There are usually a few levels in between those also and some side things like resource managers etc.
You can also go with event based systems which tie in nicely with flash's event based model as well.
For the main game engine itself a basic state machine (anything from switch based to function based to class based) can easily be implemented to tie everything together and tie in the menu system with that.
For the individual players a Model-View-Controller is a very natural pattern to aim for because you want your AI players to be exposed to everything the human player has access to. Thus the only change would be the controller (the brain) without the need for a view obviously.
As I said this isn't something that can just be answered like the normal stackoverflow question it is completely dependent on the design and how you decide to implement it. (like most things) There are tons of resources out there about RTS game design and taking it all in is the only advice I can really give. Even simple RTS's are complex systems.
Good luck to you and I hope this post gives you an idea of how to think about it. (remember balance is everything in an RTS)
To support lots of units, you might employ Flyweight and Object Pool. Flyweight object can be stored entirely in a few bytes in a large ByteArray. To get usable object, read corresponding bytes, take empty object and fill it with data from those bytes. Object pool can hold those usable objects to prevent constant allocation/garbage collection. This way, you can hold thousands of units in ByteArray and manage them via dozen of pooled object shells.
It should be noted that this is more suitable to store tile properties that units, however — tile are more-or-less static, while units are created and destroyed on regular basis.
It would be good to be familiar with a number of design patterns and apply them to the architecture of your game where appropriate.
For example, you may employ an MVC architecture for your overall application, factory pattern for creating enemies, decorator pattern for shop items, etc. Point being, design patterns are simply methodologies for structuring your objects. How you define those object and how you decide how they fit together is non prescriptive.
Which presentation patterns do you think Ext favors or have you successfully used to achieve high testability and also maintainability?
Since Ext component instances usually come tightly coupled with state and some sort of presentation logic (e.g. format validation for text fields), Passive View is not a natural fit. Supervising Presenter seems like it can work (and I've painlessly used it in one occasion). How about the suitability of Presentation Model? Any others?
While this question is specifically for Ext, it can apply to similar frameworks like SmartClient and even RIA technologies like Flex. So, if you have any first-hand pattern experiences with any other web UI technologies, your input would still be appreciated.
When thinking of presentation patterns, this is a great quote:
Separating user interface code from
everything else is a key principle in
well-engineered software. But it’s not
always easy to follow and it leads to
more abstraction in an application
that is hard to understand. Quite a
lot design patterns try to target this
scenario: MVC, MVP, Supervising
Controller, Passive View,
PresentationModel,
Model-View-ViewModel, etc. The reason
for this variety of patterns is that
this problem domain is too big to be
solved by one generic solution.
However, each UI Framework has its own
unique characteristics and so they
work better with some patterns than
with others.
As far as Ext is concerned, in my opinion the closest pattern would be the Model-View-Viewmodel, however this pattern is inherently difficult to code for whilst maintaining the separation of the key tenets (state, view, model).
That said, as per the quote above, each pattern tries to solve/compartmentalise/simplify a problem/situation often too complex for the individual application at hand, or which often fails when you try and take it to its absolute. As such, think about getting a 'best fit' as opposed to an absolute when pattern matching application development.
And remember:
The reason
for this variety of patterns is that
this problem domain is too big to be
solved by one generic solution.
I hope this helps!
2 yeas have passed since this question was aksed and now Ext-JS 4 has a built-in implementation of the MVC pattern. However, instead of an MVP (which I prefer), it favors a straight controller because the views attachment themselves to the models through stores.
Here's the docs on the controller:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.app.Controller
Nonetheless it can be made to act more like a supervising controller. One nice aspect of Ext-JS is the global application objects ability to act like an event bus for handling controller to controller communication. See this post on how to do that:
http://www.sencha.com/forum/showthread.php?176495-How-to-listen-for-custom-events-fired-in-application
Of course the definitive explanation of all these patterns can be found here:
http://martinfowler.com/eaaDev/uiArchs.html
People like Alexander Stepanov and Sean Parent vote for a formal and abstract approach on software design.
The idea is to break complex systems down into a directed acyclic graph and hide cyclic behaviour in nodes representing that behaviour.
Parent gave presentations at boost-con and google (sheets from boost-con, p.24 introduces the approach, there is also a video of the google talk).
While i like the approach and think its a neccessary development, i have a problem with imagining how to handle subsystems with amorphous behaviour.
Imagine for example a common pattern for state-machines: using an interface which all states support and having different behaviour in concrete implementations for the states.
How would one solve that?
Note that i am just looking for an abstract approach.
I can think of hiding that behaviour behind a node and defining different sub-DAGs for the states, but that complicates the design considerately if you want to influence the behaviour of the main DAG from a sub-DAG.
Your question is not clear. Define amorphous subsystems.
You are "just looking for an abstract approach" but then you seem to want details about an implementation in a conventional programming language ("common pattern for state-machines"). So, what are you asking for? How to implement nested finite state-machines?
Some more detail will help the conversation.
For a real abstract approach, look at something like Stream X-Machines:
... The X-machine model is structurally the
same as the finite state machine, except
that the symbols used to label the machine's
transitions denote relations of type X→X. ...
The Stream X-Machine differs from Eilenberg's
model, in that the fundamental data type
X = Out* × Mem × In*,
where In* is an input sequence,
Out* is an output sequence, and Mem is the
(rest of the) memory.
The advantage of this model is that it
allows a system to be driven, one step
at a time, through its states and
transitions, while observing the
outputs at each step. These are
witness values, that guarantee that
particular functions were executed on
each step. As a result, complex
software systems may be decomposed
into a hierarchy of Stream
X-Machines, designed in a top-down
way and tested in a bottom-up way.
This divide-and-conquer approach to
design and testing is backed by
Florentin Ipate's proof of correct
integration, which proves how testing
the layered machines independently is
equivalent to testing the composed
system. ...
But I don't see how the presentation is related to this. He seems to speak about a quite mainstream approach to programming, nothing similar to X-Machines. Anyway, the presentation is quite confusing and I have no time to see the video right now.
First impression of the talk, reading the slides only
The author touches haphazardly on numerous fields/problems/solutions, apparently without recognizing it: from Peopleware (for example Psychology of programming), to Software Engineering (for example software product lines), to various programming techniques.
How the various parts are linked and what exactly he is advocating is not clear at all (I'm accustomed to just reading slides and they are usually consequential):
Dataflow programming?
Constraints solving for User Interfaces? For practical implementations, see Garnet for Common Lisp, Amulet/OpenAmulet for C++.
What advantages gives us this "new" concept-based generic programming with respect to well-known approaches (for example, tools based on Hoare logic pre/post conditions and invariants or, better, Hoare's Communicating Sequential Processes (CSP) or Hehner's Practical Theory of Programming or some programming language with a sophisticated type-system like ATS, Qi or Epigram and so on)? It seems to me that introducing "concepts" - which, as-is, are specific to C++ - is not more simple than using the alternatives. Is it just about jargon and "politics"? (Finally formal methods... but disguised).
Why organizing program modules as a DAG and not as a tree, like David Parnas advocated decades ago in Designing software for ease of extension and contraction? (here a directly accessible .pdf and here slides from a lecture). The work on X-Machines probably is an answer to this question (going even beyond DAGs), but, again, the author seems to speak about a quite conventional program development regime in which Parnas' approach is the only sensible.
If/when I will see the video I will update this answer.
"Abstraction and encapsulation are complementary concepts: abstraction focuses on the observable behavior of an object... encapsulation focuses upon the implementation that gives rise to this behavior... encapsulation is most often achieved through information hiding, which is the process of hiding all of the secrets of object that do not contribute to its essential characteristics." - Grady Booch in Object Oriented Analysis and Design
Can you show me some powerfully convincing examples of the benefits of encapsulation through information hiding?
The example given in my first OO class:
Imagine a media player. It abstracts the concepts of playing, pausing, fast-forwarding, etc. As a user, you can use this to operate the device.
Your VCR implemented this interface and hid or encapsulated the details of the mechanical drives and tapes.
When a new implementation of a media player arrives (say a DVD player, which uses discs rather than tapes) it can replace the implementation encapsulated in the media player and users can continue to use it just as they did with their VCR (same operations such as play, pause, etc...).
This is the concept of information hiding through abstraction. It allows for implementation details to change without the users having to know and promotes low coupling of code.
The *nix abstraction of character streams (disk files, pipes, sockets, ttys, etc.) into a single entity (the "everything is a file") model allows a wide range of tools to be applied to a wide range of data sources / sinks in a way that simply would not be possible without the encapsulation.
Likewise, the concept of streams in various languages, abstracting over lists, arrays, files, etc.
Also, concepts like numbers (abstracting over integers, half a dozen kinds of floats, rationals, etc.) imagine what a nightmare this would be if higher level code was given the mantissa format and so forth and left to fend for itself.
I know there's already an accepted answer, but I wanted to throw one more out there: OpenGL/DirectX
Neither of these API's are full implementations (although DirectX is certainly a bit more top-heavy in that regard), but instead generic methods of communicating render commands to a graphics card.
The card vendors are the ones that provide the implementation (driver) for a specific card, which in many cases is very hardware specific, but you as the user need never care that one user is running a GeForce ABC and the other a Radeon XYZ because the exact implementation is hidden away behind the high-level API. Were it not, you would need to have a code path in your games for every card on the market that you wanted to support, which would be completely unmanageable from day 1. Another big plus to this approach is that Nvidia/ATI can release a newer, more efficient version of their drivers and you automatically benefit with no effort on your part.
The same principle is in effect for sound, network, mouse, keyboard... basically any component of your computer. Whether the encapsulation happens at the hardware level or in a software driver, at some point all of the device specifics are hidden away to allow you to treat any keyboard, for instance, as just a keyboard and not a Microsoft Ergonomic Media Explorer Deluxe Revision 2.
When you look at it that way, it quickly becomes apparent that without some form of encapsulation/abstraction computers as we know them today simply wouldn't work at all. Is that brilliant enough for you?
Nearly every Java, C#, and C++ code base in the world has information hiding: It's as simple as the private: sections of the classes.
The outside world can't see the private members, so a developer can change them without needing to worry about the rest of the code not compiling.
What? You're not convinced yet?
It's easier to show the opposite. We used to write code that had no control over who could access details of its implementation. That made it almost impossible at times to determine what code modified a variable.
Also, you can't really abstract something if every piece of code in the world might possibly have depended on the implementation of specific concrete classes.
I create business applications with heavy database use. Most of the programming work is just to connect components to the database and modifying components to adapt to general interface behaviour. I mostly use Delphi with its rich VCL library, and generally buy components needed. I keep most of the business logic in the database. I rarely get the chance to build a nice class hierarchy from the bottom up as there really is no need. Anyone else have this experience?
For me, occasionally a problem is clearer or easier with subclassing, but not often.
This also changes quite a bit in a given design as it's refactored.
My biggest problem is that programming courses and texts give so much weight to inheritance, hierarchies, and polymorphism through base classes (vs. interfaces or dynamic typing). This helps create legions of programmers that subclass everything and their mother.
The answer to this question is not totally language-agnostic;
Some languages like Java have a fairly limited set of language features available, meaning that subclassing is fairly often used because it's a convenient method for re-use, technical inheritance.
Closures and lambdas of C# make inheritance for technical reasons much less relevant. So normally inheritance is used for semantic reasons (like cat extends animal).
The last C# project I worked on, we more or less made all of the class hierarchies within a few weeks. After that it was more or less over.
On my current java project we create new class hierarchies all of the time.
Other languages will have other features that similarly affect this composition (mixins come to mind)
I put on my architecting/class design hat probably once or twice a month. It's probably the best hat I have and is the most fun to wear.
Depends what stage of the lifecycle your project is in though.
When your tackling problem domains you are well familiar with and already have a common code base to work from, you often have no need to create a new class hierarchy. It's when you stumble upon problems you have no ready solutions for, that you start building your own.
It's also very dependant on the type of applications you develop. If your domain already has well accepted conventions and libraries to work from, there probably isn't any need to reinvent the wheel (other than personal / academic interests). Some areas have inherently less available resources to work with, and in those you'll find yourself building everything from scratch most of the time.
A majority of applications, especially business applications, contains at least some kind of business logic in it. I would contend that business should not be in the database, but should rather be in the application. You can put referential integrity in the database as I think this is a good choice, but business logic should be only in the application.
By class hierarchy, I suppose you mean do you always have to end up with some inheritance in your object model, then the answer is no. But chances are you can often find some common code, factor it out and create a base class to contain the common code.
If you agree with me on the point that business logic should not be in the database, but should be in the application, then I recommend you look into the MVC Design Pattern to guide your design. You will find your design contain classes or objects. Your VCLs will represent your View, and you can have your Model classes map directly to the database table, i.e. each member in the class in the model corresponds to a field in a database table (again, this is the norm but there will be exception, where this simplicity fails to apply). Then you'll need a layer to handle the CRUD (Create, Read, Update, Delete) of the Model classes to the database tables. You will end up with an "layered" application that is easier to maintain and enhance.
It depends on what you mean by hierarchy - inheritance or layering?
When object oriented languages first came out, inheritance was overused. Complicated hierarchies were common. Now, interfaces (as in Java and C#) provide a simpler way to get the benefit of polymorphism without the complications of inheritance. I rarely use inheritance anymore.
Layering, however, is vital when creating a large application. Layering prevents general low-level classes (like lists) from directly referencing specific high-level classes (like web browser windows). As far as I know, there isn't a formal way to describe layering, but there are general guidelines (model-view-controller (MVC), separate GUI logic from business logic, separate data from presentation, etc.).
It really depends on the types/phases of the projects you're working on. I happen to do that everyday because I'm working on database internals for a new database, creating related libraries/frameworks. I'd imagine doing that a lot less if I'm working within a mature framework using other people's libraries.
I'm doing Infrastructure for our companys' product, so I'm writing a lot of code that will be used later by guys in other teams. So I end up writing lots of abstract classes, interfaces, hierarchies and so on. Mostly it's just a pattern of "default behaviour in an abstract/virtual class, which other programmers may override".
Very challenging, I must say.
The time that I find class hierarchies most beneficial is when the relationship between objects actually does match a true "is-a" relationship in the domain.
However if I can avoid large hierarchies I will due to the fact that they are often a little more tricky to map to relational databases and can really complicate your database designs. Since you say most of your applications make heavy use of databases this would be something to take into consideration.