I have the following problem: I'm designing a game and summing up let's say that I have three classes:
Player
PowerPlant
Unit
Some "use cases"
Player has to know how many units and powerplants he has. If the limit has been reached, more units/powerplants should not be constructed (i.e. Player has to have a reference of each element that belongs to him)
Units request energy from the Player, and the Player gets the energy from the PowerPlants and sends it to the Units
Player has to know when a Unit or a PowerPlant has been destroyed (i.e. units and PowerPlants have to be able to notify to the player that they've been destroyed)
And the only way I can get this to work, is that Player knows about PowerPlants and Units, but also each PowerPlant and Unit knows about his Player/Owner, so that they can communicate in both ways.
I somehow think that this is a code smell... when I have been in similar situations, I always have had trouble at the long term.
Thanks in advance.
I have had that problem in multiple occasions, and what you said is not necessarily an anti-pattern but it does add undesired complexity.
YMMV, but in my case, I didn't really wanted to have a direct relationship between those different classes but a way to notify each other when something happens, so the cleaner way I had found was having an event manager (or any other sort of callback mechanism) to glue all logic parts together. With that tool in the belt it turned out that I could get rid of all those double references which simplified the hierarchy a lot.
Related
I'm designing a site which has an AV room which also has a bunch of other functionality relating to a medical exam. So, I have a store for the room "ExamStore" which contains domain data and logic for the doctor and patient, the notes the doctor has taken, past exams, etc. I also have two other "managers":
DeviceManager which managers things like cameras, mics, etc which are plugged in
AVManager which manages the actual AV functionality (it's a wrapper over Twilio.)
Now, AVManager I have made observable since it has actions like "muteLocalAudio" and computeds like "localAudioIsMuted".
My question is whether I should have one source of truth, "ExamStore", and expose only that to the UI components. So, if a user clicks a mute button, I would call examStore.muteLocalAudio, which would then simply delegate to avManager.muteLocalAudio. Or, should I just expose AVManager as well to my UI components and have them call avManager.muteLocalAudio directly.
I can see the benefit to both: In the first instance, everything goes through ExamStore, which makes tracking things down easy. Also, it's nice for centralizing everything. On the other hand, DeviceManager, AVManager, and other classes I might come up with have very distinct responsibilities from ExamStore. If I just have ExamStore as a pass through which delegates to them I'm, one, giving ExamStore too much responsibility, and, two, potentially making its surface area quite large.
Anyway, just wondering if there are best practices out there for a scenario like this.
We have a number of processes that rely on interactions between two people/groups. I am trying to figure out the best way to illustrate this in BPMN.
CONSIDER:
Using the example of a pizza order, I call a pizzeria to order, an order-taker answers the phone and then we discuss my order. I am trying to accurately capture the "we discuss the order" portion of the process. Here is how I envision the diagram playing out. I call, they answer, then there's branching for a simultaneous exchange, which converges at the end of the call and my order is finished. Is this illustrated correctly? or are there better ways to show that two different entities communicating with each other at the same time to accomplish a task?
The moment you want to show interaction in greater detail than high level bird view, you typically run into troubles when remaining within the paradigm of using "one pool with several lanes". In such a case you need to draw a so called "collaboration diagram", which means you make use of several pools and hence several process definitions interacting with each other by means of message exchange. I give you an example here:
You may use those envelope symbols attached to the message flows, but you don't need to.
The big advantage of that approach is that you can now show that those processes are dependent on each other, yes, but each participant also wants to remain in drivers seat of his/her own process, e.g. by deciding what to do if the other side doesn't provide the desired answer, doesn't do anything within a reasonable time and so on. Furthermore you can look at that diagram from both perspectives and people will actually see "their own process" - and not something mixed with the concerns of others involved.
For that same reason BPMN also offers the concept of "collapsed pools" to be able to look just at the communication from one side and treat the internal details of the other side as a kind of "black box":
I am interested in a general approach, not a particular library or framework.
I am trying to avoid spaghetti-code-ish conditionals when possible. It may be that I'm thinking of these apps in totally the wrong way, but I can't seem to find anything online that's helpful.
The problems arise when there are multiple sorts of states that all affect each other. Here's an example:
Image a Person that has these abilities:
Walk.
Run.
Sit.
I make a command pattern with Walk.execute(), Run.execute() and Sit.execute(). These commands are triggered by user input or whatever. What's great about this, of course, is that if running needs to be debugged or amended, it's easy to know where to look in the code base.
Now I'm asked to add a dog. The dog can...
Walk.
Run.
Sleep.
If the person is walking and the dog is running, the dog (being on a leash) will run slower than he will if he's running on his own. And if the dog is sleeping, the person will sit for longer than he normally does. In other words, the dog and the person are affected by each other.
Then I'm asked to add a refrigerator with food in it. The fridge affects the dog and person, because the amount they eat affects their energy for running, etc.
I am continually asked to tweak this system. "Please make the dog run sleep more, but only if he and the person have been walking and the fridge is almost empty." And then, later: "Please change it so that the amount the person has run has walked has no affect on the dog's sleep."
I want to avoid packing DogSleep with tons of conditionals, and I also want to avoid DogSleepIfDogAndManHaveBeenWalkingAndFridgeIsAlmostEmpty. That's not scalable.
At any time, we might want to rip the fridge out of the system. Or we might want to change it in some fundamental or subtle ways.
A more real-life example is a media player that can be displayed as a compact player, an expanded player (say one that takes up half of your screen) and a full-screen player. So there are those three screen states.
Meanwhile, the player could be displaying an image, video or text.
If it's displaying a video, that video could be playing, paused, completed, etc.
The state of the video affects the way the different screen states render. The type of media also affects the rendering. And the screen state affects things the other objects (e.g. maybe, for whatever reason, you're supposed to be able to pause a video when the player is compact but not when it's expanded or in full screen).
What is the best way to make multiple state systems interact with each other when those interactions are complex and flow in both (or multiple) directions? How can one organize such code so that it's easiest to debug and scale?
The primary way to manage complexity in complex systems is to find analogies and concepts in the real world upon which you can base your design and implementation. So, when you talk about people, dogs and refrigerators interacting in some system you base methods of interaction on the way these entries interact in the real world - which is largely autonomously based on sensed inputs and internal interests/goals/needs. When you talk about media players and images and text then finding the analogies is more difficult but just as important.
I am a C++ programmer trying to learn designing, as a start I am trying to get a hang of designing by giving myself a task to make a OO design for a game of chess.This is not a homework q just trying to develop some skills.
Here is the summary of what i have in my mind till now:
A "Piece" class which will hold the current position of the piece on the board.
specialized classes "Camel" "Horse" "Queen" "Knight" "Pawn" & "Elephant" which will be derived from the "Piece" class. Each of these classes will hold 2 members, "no of places allowed to move" & "rule of moving" and get methods to retrieve the same.
A base "Player" Class which will be extended by classes "BlackPiecePlayer" & "WhitePiecePlayer". Each of these classes will hold another class instance called "PieceManager" The "PieceManager" class will be the one which will determine the logic of moving around the pieces on the Board.
A "ChessBoard" class which will hold the mapping of all the pieces on the board and have access to set of rules with which pieces can be moved. It will provide interfaces to authenticate a move calculated by "PieceManager" and then make the move while updating its own mappings.
Heres a generic flow that i can visualize. A class "WhitePiecePlayer" is asked to make a move, it will ask its own "WhitePieceManager" to make a move. The "WhitePieceManager" will access the positions of pieces on board by using interfaces of "Board" class. Then it will use its internal logic to calculate a move for an piece.Each piece stores its position so it calculates position for that piece. Then authenticates the move is possible by calling a method of the Board class and then makes the move by using Board class interface..and so on..
Sorry for the long story, I am just trying to develop a feel for the design and this is what i have in mind right now, Do you think its good for a start or any suggestions on how to make it better(if it is correct)
A few suggestions
Your hierarchy of piece related classes seems reasonable (though using the proper names for the pieces Knight, Rook, and Bishop would probably be preferable to Horse, Camel, and Elephant).
I would not store the number of squares a piece is allowed to move. You would want to encode that in the "rule of movement" method if only because that can change depending on the situation. A pawn can move two squares on its initial move and then one square in subsequent moves. A king can only move one square unless it is castling.
Your piece classes will need to have some sort of method to get a list of all a piece's valid moves in order to provide those to the engine that is going to choose a move.
You don't need BlackPiecePlayer and WhitePiecePlayer classes. You just need to instantiate two different instances of the Player class and ensure that there is a "color" attribute.
A ChessBoard class is a good idea and will need to represent the positions of the pieces but it should not implement logic evaluating moves. That is something for the move engine to do.
As Javier discusses, building a chess program is likely going to involve quite a bit of effort on the design of an efficient algorithm for choosing a move. Assuming that your intention is to apply OO concepts and not to delve into the discussions about how to build a chess engine (which will often sacrifice OO purity for better performance), and assuming that you want to build something that can play well enough to be interesting, you may want to consider implementing antichess rather than regular chess. From an OO standpoint, it is essentially an identical problem, but the end result is something that plays reasonably well without investing hundreds of hours in mastering chess algorithms. That's a much more enjoyable outcome than a chess program that plays terribly.
A few comments
1) The most important thing in a chess prgoram is the algorithm to choose a move. Usually it is an alpha-beta pruning algorithm. In order for this algorithm to be efficient, the way that pieces in the board are represented is very important. You can read that in this implementation issues section of wikipedia. I'd read that for the basis of board-piece representation. There is a lot of discussion in internet, and open engines like Crazy or Fruit. I doubt that they use OO, though - I do not know if there is any Object Oriented engine in the wild.
2) What are the camel, elephant, etc? What kind of chess are you trying to represent? I am not familiar with that, sorry. Is elephant the rook and camel the bishop?
3) What is the utility of having two different classes, WhitePlayer and BlackPlayer? In which way would they be different from Player? Shouldn't you have two different instances of a Player class, called white and black?
Good luck with your project. I hope you learn a lot from it! :)
As a second interview I get people to sit down and write code...I try to make the problem really technology independent.
My programming problems that I have don't really exercise peoples OO abilities. I tend to try and keep the coding problem solvable within 2 hours ish. So, I've struggled to find a problem small enough and involved enough that it exposes peoples OO design skills.
Any suggestions?
This is a problem that I use with some trainings, looks simple but is tricky OOP-wise:
Create model classes that will properly represent the following constructs:
Define a Shape object, where the object is any two dimensional figure, and has the following characteristics: a name, a perimeter, and a surface area.
Define a Circle, retaining and accurately outputting the values of the aforementioned characteristics of a Shape.
Define a Triangle. This time, the name of the triangle should take into account if it is equilateral (all 3 sides are the same length), isoceles (only 2 sides are the same length), or scalene (no 2 sides are the same).
You can go on and on with quadrelaterals (which include squares, rectangles, rhombi, etc) and other polygons.
The way that they would solve the above problems would reveal the people who understand OOP apart from those who don't.
ideally, you want to present a problem that appears difficult, but has a simple, elegant, obvious solution if you think in OO terms
perhaps:
we need to control access to a customer web site
each customer may have one or more people to access the site
different people from different customers may be able to view different parts of the site
the same person may work for more than one customer
customers want to manage permissions based on the person, department, team, or project
design a solution for this using object-oriented techniques
one OO solution is to have a Person, a Customer, an Account, and AccountPermissions, where the Account specifies a Person and a Customer and an optional Parent Account. the use of a recursive Account object collapses the otherwise cumbersome person/team/department/project structure a direct ERD solution might yield
I have used the FizzBuzz Programming Test. And shockingly can corroborate the claims made by the article. As a second follow up I have asked candidates to compute the angle(s) between the hands on an analog clock. We set up a laptop with VS 2008 installed and the stub in place. all they have to do is fill in the implementation.
I am always stunned at how poorly candidates do on these two questions. I really am.
Designing Social Security Application is something which I ask a lot of people during interviews.
The nice thing about this is everyone is aware of how it works and what things to keep track of.
They also have to justify their design and this really helps me get inside their head :)
(As there is lots of flexibility here)
Kind regards,
Whether or not people do some coding in the interview, I make it a point to ask this:
Tell me about a problem you solved recently using object oriented programming. You'd be surprised how often people cannot answer that simple question. A lot of times I get a blank stare, or they say something like "what do you mean? I program in .NET, which is all object oriented."
These aren't specifically OO Questions, but check out the other questions tagged interview-questions
Edit: What about implementing some design patterns? I don't have the best knowledge in the area but it seems as if you would be getting two questions for the price of one. You can test for both OO and Design pattens in the one question.
How about some sort of simple GUI. It's got inheritance, overriding, possibly events. If you mean for them to actually implement as part of the test then you could hand them a blank windows-form with an OnPaint() and tell them to get to it.
You could do worse than ask them to design a MapReduce library with a single-process implementation. Will the interface still work for a distributed implementation? What's the exception-handling policy? Should there be special support for chaining MapReduce jobs in a pipeline? What's the interface to the inputs and outputs? How are inputs chunked up? Can different inputs in one job go to different mappers? What defaults are reasonable?
A good solution in Python takes about a page of code.
I've got a super simple set. The idea is mainly to use them to filter out people who really don't know their stuff rather than filtering in the rock stars.
These are all 5 minute white-board type questions, so they are really not that hard. But the act of writing up code, and talking through it reveals a lot about a candidate - and is brilliant for exposing those that can otherwise BS through the talk.
Write a method that takes a radius of a circle as an argument, and returns the area of the circle (You would be amazed how many people struggle on this one!)
Write a program that accepts a series of numbers as arguments from the command line. Add them up, and print the sum
Write a class that acts as a keyed counter (basically a map that keeps track of how many times each key is "counted")