Should I seperate model classes or have them as a single unit? - unit-testing

My game logic model consists of multiple connected classes. There are Board, Cell, Character, etc. Character can be placed (and moved) in Cell (1-1 rel).
There are two approaches:
Make each class of model implement interfaces so that they can be mocked and each class can be tested independently. It forces me to make implementation of each class to not rely on another. But in practice it's hard to avoid Board knowing about Cells too much and Characters knowing how Cell storing mechanism works. I have a Character.Cell and Cell.CurrentCharacter properties. In order for setters to work correctly (not go recursively) they should rely on each others implementation. It feels like the model logic should be considered as a single unit.
Make all public members to return interfaces but use exact classes inside (can involve some downcasting). The cons here are such that I should test the whole model as a single and can't use mocking to test different parts independently. Also there is no sense to use dependency injection inside model, only to get another full model implementation from controller.
So what to do?
UPDATE
You can propose other options.

Why are these the only 2 options?
If you intend to have different versions/types of the classes then interfaces/abstract base classes are a good option to enforce shared behaviour and generalize many operations. However the idea of building the classes independently without knowledge of each other is ridiculous.
It is always a good idea to separate class storage/behaviour to the class/layer it belongs. E.g. no business logic code in the data layer, etc. but the classes need to know about each other in order to function properly. If you make everything independent and based on interfaces you run the risk of over generalizing the application and reducing your efficiency.
Basically if you think you would need to ever downcast the incoming objects to more than one type it's a good idea to look at the design and see if you are gaining anything for the performance loss and nasty casting code you are about to write. If you will be required to handle every type of downcast object you have not gained anything and using polymorphism and a base class is a much better way to go.
Using interfaces does not eliminate your trouble in testing. You will still have to instantiate some version of the objects to test most of the functions on the cell/board anyway. Which for full regression testing will require you test each character's interaction with both.
Don't get me wrong, your character class should most likely have a base class or have an interface. All characters will (I'm sure) share many actions and can benefit from this design. E.g. Moving a character on the board is a fairly generic operation and can be made independent of the character except for a few pieces of information (such as how the character moves, if they are allowed to move, etc.) which should be part of said base class/interface.
When it is reasonable, design classes independently so that they can be tested on their own, but do not use testing as a reason to write bad code. Simple stubs or basic testing instances can be created to help with component testing and takes far less time and effort than fixing unnecessarily complex code.
Interfaces have a purpose, but if you will not be treating 2 classes the same... that is not it.
*Using MVC gives you a leg up on testing as well. If done correctly you should be able to swap out any of the layers to ease your testing of a single layer.

Related

Does needing many forward declarition of classes indicates bad design

I have three classes in my project. Lets call them MainWindow , ProcessUserInput, InitialUIPreparer .
MainWindow's job is just to dialog with user via buttons,text,combobox etc.. ,
ProcessUserInput will make some calculation with value which are taken from MainWindow and after calc. finishes it will send back some processed data to MainWindow,
and also InitialUIPreparer will calculate the places of some shapes which should be drawn on MainWindow, it will just pass cordinates not draw them. But it also need to get some data like window size etc..
Ok problem starts like MainWindow need to get data from each class and classes needs to get data from MainWindow . This leads circular dependency. I solve the problem by including MainWindow.h to "ProcessUserInput" and "InitialUIPreparer" . But just using forward decleration in MainWindow like "class ProcessUserInput" and "class InitialUIPreparer".
I can still continue development ofcourse. But like in my case needing forward decleration many times, indicates bad design or not, should I reconsider the design for future projects?
In general, forward-declaring a class by itself does not indicate a bad design: this happens very often when your runtime dependency hierarchy is bidirectional. However, when the dependency graph is very dense (i.e. nearly every class depends on nearly all other classes) it is a valid reason to start worrying:
In your case it appears that you may benefit from separating your classes in a way consistent with the Model-View-Controller design pattern. Specifically, you may want to introduce another class, let's call it Model, that would keep all information that needs to be shared among your other classes. Each class would pull the information that it needs from the shared Model, and put the information that it produces into the model as well. This way the individual classes would be able to replace dependencies on all classes with a single dependency on the Model class:
The mere presence of forward-declarations is not, in itself, a code smell. However the reason for the need for the forward-declarations can be.
In your case you need the forward-declarations in order to construct a circular dependancy. That is your code smell. The presence of a circular dependancy is always a code smell -- which is not to say that it is always a design flaw, but it is something that should be looked at.
Especially in small programs, circular dependencies may in fact be a theoretic design flaw, but one which might not be worthwhile to fix. In your case you have two classes which communicate directly with each other. In a large, production system I would usually categorize this design as "broken; needs to be fixed." The way I would fix it would be to introduce some kind of message bus, or a sink/provider mechanism separate from both of the classes, and have each class communicate with that instead of each other. Building this system either involves expending a lot of work or a lot of money (to purchase one), and opens avenues to a whole slew of new bugs and challenges. In the case of small systems, I likely wouldn't even bother.

How to unit test code with very few units

How can I write unit tests for existing and already implemented code which has taken a procedural implementation as opposed to an OOP implementation. We are using Java/Spring, however there are not a lot of different beans for the different concerns, which are all mixed into one large class per piece of of major functionality. (EG: we have classes/beans for each batch job, for our DAOs and a few util type beans and that's it).
Just to give some more details, these major classes which need to be tested are about 1k-2k lines of code, and the only dependency injection/OOP they use is DAOs and some odd utilities. They have about 1 public method which they implement for an interface they all share.
Start by refactoring. Modern IDEs will allow you to refactor safely without breaking or changing the code semantics. But you have to do this consciously and be smart.
Start from "outer" classes that are not dependencies of any other classes.
First step is to extract as many methods as you can. Typically when you find a huge method with lots of blank lines/comments separating blocks of code they are good candidates for extractions. Also loops, nested conditionals, long switches, etc. should be considered.
Once you have plethora of well named methods look around and try to group them by moving them up and down. If some method are closely coupled and logically dependent, extract them to a separate class. IDE will assist you.
This process can be repeated on every layer and multiple times. Aim for small, cohesive classes, if you cannot name it (e.g. you have to use "And" to express what method/class is doing), extract further.
Of course you can test it as-is - I guess every possible execution path can be reached with different set of input parameters. But this will be a nightmare to debug.
Just to add some other considerations to the great answer from Tomasz Nurkiewicz (which I second completely):
Sometimes (well, always really), it's useful to write at least one encapsulating "acceptance test" before starting the refactoring (if there is no existing one). Once it passes, you can then start refactoring and make sure you haven't broken anything "important" at each step. Before starting an important refactoring task, it's very useful to have such a harness to keep you sane :)
Refactoring is not just a technical task: you don't only want to break big classes into smaller ones and extract code to methods. You want to think about what your code is supposed to do, in terms of objects, and move to a better design. It will make your life easier in the long run.
As a rule of thumb, I try to have no class above 80-100 lines of code (and ideally lower than 50). Of course there are exceptions, but when it gets bigger, I usually try to refactor separate concerns into collaborator objects that get injected into the main class. It keeps the code readable and easy to test.

Do I only have to mock out external dependencies in a unit test? What's about internal dependencies?

Do I only have to mock out external dependencies in a unit test?
What if my method that I want to test, has a dependency on another class within the same assembly? Do I have to mock out the dependency for going sure to test only one thing and there for to make a unit test instead of an integration test?
Is an integration test a test that tests dependencies in general or do I have to difference between internal and external dependencies?
An example would be a method that has 2000 lines of code with 5 method invocations (all methods coming from the same assembly).
Generally a proper unit test is testing only that single piece of code. So a scenario like this is where you start to ask yourself about the coupling of these two classes. Does Class A internally depend on the implementation of Class B? Or does it just need to be supplied an instance of Type B (notice the difference between a class and a type)?
If the latter, then mock it because you're not testing Class B, just Class A.
If the former, then it sounds like creating the test has identified some coupling that can (perhaps even should) be re-factored.
Edit: (in response to your comment) I guess a key thing to remember while doing this (and retro-fitting unit tests into a legacy system is really, really difficult) is to mentally separate the concepts of a class and a type.
The unit tests are not for Class A, they are for Type A. Class A is an implementation of Type A which will either pass or fail the tests. Class A may have an internal dependency on Type B and need it to be supplied, but Type A might not. Type A is a contract of functionality, which is further expressed by its unit tests.
Does Type A specify in its contract that implementations will require an instance of Type B? Or does Class A resolve an instance of it internally? Does Type A need to specify this, or is it possible that different implementations of Type A won't need an instance of Type B?
If Type A requires an instance of Type B, then it should expose this externally and you'd supply the mock in your tests. If Class A internally resolves an instance of Type B, then you'd likely want to be using an IoC container where you'd bootstrap it with the mock of Type B before running the tests.
Either way, Type B should be a mock and not an implementation. It's just a matter of breaking that coupling, which may or may not be difficult in a legacy system. (And, additionally, may or may not have a good ROI for the business.)
Working with a code base you're describing isn't easy with multiple problems combined into something you don't know how to start changing. There are strong dependencies between classes as well as between problems and maybe even no overall design.
In my experience, this takes a lot of effort and time as well as skill in doing this kind of work. A very good resource to learn how to work with legacy code is Michael Feather's book: Working Effectively with Legacy Code.
In short, there are safe refactorings you can do without risking to break things, which might help you get started. There are also other refactorings which require tests to protect how things work. Tests are essential when refactoring code. This doesn't of course come with a 100% guarantee that things don't break, because there might be so many hidden "features" and complexity you cannot be aware of when you start. Depending on the code base the amount of work you need to do varies greatly, but for large code bases there is usually a lot of work.
You'll need to understand what the code does, either by simply knowing it or by finding out what the current code does. In either case, you start by writing "larger" tests which are not really unit tests, they just protect the current code. They might cover larger parts, more like integration/functional tests. These are your guards when you start to refactor the code. When you have such tests in place and you feel comfortable what the code does, you can start refactoring the parts the "larger" tests cover. For the smaller parts you change you write proper unit tests. Iterating doing various refactorings will at some point make the initial large tests unnecessary because you now have a much better code base and unit tests (or you simply keep them as functional test).
Now, coming back to your question.
I understand what you mean with your question, but I'd still like to change it slightly because there are more important aspects than external and internal. I believe a better question is to ask which dependencies do I need to break to get a better design and to write unit tests?
The answer to this question is you should break all dependencies you are not in control over, slow, non-deterministic or pulls in too much state for a single unit test. These are for sure all external (filesystem, printer, network etc.). Also note that multi-threading is not suitable for unit tests because this is not deterministic. For internal dependencies I assume you mean classes with members or functions calling other functions. The answer to this is maybe. You need to decide if you are in control and if the design is good. Probably in your case you are not in control and the code is not good, so here you need to refactor things to get things under control and into a better design. Michael Feather's book is great here, but you need to find how to apply the things on your code base of couse.
One very good technique for breaking dependencies is dependency injection. In short, it changes the design so that you pass in the members a class uses instead of letting the class itself instantiate them. For these you have an interface (abstract base class) for these dependencies you pass in, so you can easily change what you pass in. For instance, using this you can have different member implementations for a class in production and when you do unit test. This is a great technique and also leads to good design if use wisely.
Good luck and take your time! ;)
Generally speaking, a method with 2000 lines of code is just plain BAD. I usually start to look for reasons to make new classes -- not even methods, but classes -- when i have to use the pagedown key more than three or four times to browse through it (and collapsable regions doesn't count).
So, yes you do need to get rid of dependencies from outside and inside of the assembly, and you need to think of responsibility of the class. It sounds like this one has way too much weight on its shoulders, and it sounds like it is very close to impossible to write unittests for. If you think testability, you will automatically start to inject dependencies, and downsize your classes, and BAM!!!There you have it; nice and pretty code!! :-)
Regards,
Morten

Mixing component based design and the model-view(-controller) pattern

'm developing a 2D game and I want separate the game engine from the graphics.
I decided to use the model-view pattern in the following way: the game engine owns game's entities (EnemyModel, BulletModel, ExplosionModel) which implement interfaces (Enemy, Bullet, Explosion).
The View receives events when entities are created, getting the pointer to the interface: in this way the View can only use the interface methods (i.e. ask for informations to perform the drawing) and cannot change the object state. The View has its onw classes (EnemyView, BulletView, ExplosionView) which own pointers to the interfaces.
(There is also an event-base pattern involved so that the Model can notify the View about entity changes, since a pure query approach is impraticable but I wont' discuss it here).
*Model classes use a compile-time component approach: they use the boost::fusion library to store different state componets, like PositionComponent, HealthComponent and so on.
At present moment the View isn't aware of the component based design but only of the model-view part: to get the position of an enemy it calls the Enemy::get_xy() method. The EnemyModel, which implements the interface, forwards this call to the PositionComponent and returns the result.
Since the bullet has position too, I have to add the get_xy method to Bullet too. BulletModel uses then the same implementation as the EnemyModel class (i.e. it forwards the call).
This approch then leads to have a lot of duplicate code: interfaces have a lot of similar methods and *Model classes are full of forward-methods.
So I have basically two options:
1) Expose the compoment based design so that each component has an interface as well: the View can use this interface to directly query the component. It keeps the View and the Model separated, only at a component level instead of a entity level.
2) Abandon the model-view part and go for pure component based design: the View is just a component (the RenderableComponent part) which has basically full access to the game engine.
Based on your experience which approach would be best?
I'll give my two cents worth. From the problem you're describing, it seems to me that you need an abstract class that will do the operations that are common amongst all of your classes (like the get_xy, which should apply to bullet, enemy, explosion, etc.). This class is a game entity that does the basic grunt work. Inheriting classes can override it if they want.
This abstract class should be the core of all your interfaces (luckily you're in C++ where there is no physical difference between a class, and abstract class and an interface). Thus the Views will know about the specific interfaces, and still have the generic entity methods.
A rule of thumb I have for design - if more than one class has the same data members or methods, it should probably be a single class from which they inherit.
Anyway, exposing the internal structure of your Model classes is not a good idea. Say you'll want to replace boost with something else? You'd have to re-write the entire program, not just the relevant parts.
MVC isn't easy for games as when the game becomes larger (including menu, enemies, levels, GUI...) and transitions, it'll break.
Component or entity-system are pretty good for games.
As a simpler case for you, you may consider using a HMVC. You'll still have issues with transitions, but at least your code will be grouped together in a more clean manner. You probably want your tank's code (rendering and logic) to get close together.
There have been presentation architectures designed especially for agent-based systems, such as Presentation-Abstraction-Control. The hard part in designing such a system is that you ultimately end up hardwiring sequences of collaborations between the agents.
You can do this, but don't use OO inheritance to model the message passing hierarchy. You will regret it. If you think about it, you are really not interested in using the OO inheritance relationship, since the interfaces defined are really just a "Record of functions" that the object can respond to. In that case, you are better off formally modeling your communication protocol.
If you have questions, please ask -- this is not an obvious solution and easy to get wrong.

N-tier architecture design separation of concerns

I realize there have already been a number of posts on n-tier design and this could possibly be me over thinking things and going round in circles, but I have myself all confused now and would like to get some clarity from the community please.
I am trying to separate a project I created, (and didn't design architecturally very well to start with), out into different layers (each in their own project):
UI
Business Objects
Logic / Business
DAL
The UI should only call the Logic layer to get its stuff
The Business Objects should not call or have references to anything else, just be a way of storing the data
The Logic / BUSINESS layer should hold all of the methods to get, create, update, delete (CRUD) objects in the system and would have references to both the BO and the DAL. It would apply the business logic to the operations then delegate the actual CRUD to the DAL.
The DAL would just do the CRUD operations on the DB. It would have a reference to the BO's as it would return them for the Gets etc.
My question is should the Logic classes only call their equivalent DAL class and just call logic classes instead? In other words, CompanyLogic class should only call CompanyDAL class. So if it wanted to get A Client object by ID it would call ClientLogic.GetClientByID(int) rather than the ClientDAL.GetClientByID(int).
The reason I thought it maybe should stay on the its own layer was that:
It would seem to loosen the coupling between projects
What about the Logic, if getting a client object had some logic validation in it (possibly not the best example, but hope it gets the point across).
EDIT:
I am not sure if it is bad design by me but at the moment the BUSINESS layer has a number of classes including ClientBULL and CompnayBULL, both classes have a call to one another. I use an interface for each class and have a factory to build the objects to try and reduce any coupling but they can not exist without each other now due to calling methods in both classes. Is this a bad idea?
Well, here's my comments on your design:
Logic is a bad name for what essentially is a layer assigned to abstract persistence. I would probably call it "Repository" or "Persistence" or DAO (data access objects) instead of "Logic", which is ambiguous and could absolutely mean anything.
If you really want to decouple your business layer from your DAL, your Logic layer should only accept interfaces to the DAL, and not concrete DAL classes.
There are two schools of thought as to where validation should reside. Some are completely fine with validation sitting at the UI layer; others would rather throw exceptions or pass messages from the business layer. Whichever way you go, just be consistent, don't duplicate validations in multiple places, and you'll be fine.
Go ahead and try coding it would probably be the best piece of advice I could give you. It's well and fine thinking it through, but at one point you'll need to see it while you're coding it and only then will subtle quirks and pitfalls reveal themselves. Whatever prototypes you can come up with will definitely be valuable to the direction your development and design takes you.
Goodluck!
Update
Re your edit: Within the same namespace or assembly, calls to concrete classes are definitely fine. I think it will be overly convoluted for you to need to put up interfaces for business logic -- I mean is there more than one set of rules you should follow?
I'm a believer of keeping things simple and following YAGNI. Don't make an interface until there are more than two classes that are going to implement/already implementing that interface (the DAL is always an exception to this though).