As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am facing a rather annoying software design problem which has been troubling me for quite some time now. The problem is the initialization of an object and that a lot of getters are used to achieve that. I bumped into an article of Allen Holub [1] about why a lot of getters and setters usually indicate poor design. I listed several other articles below which also discuss this design issue.
Now concerning my problem. I am currently working on a fluid simulation. I have a Simulation class which contains the functions and variables relevant for simulating a fluid. At first, this class had only one public function called timeStep() which executes a time step of the simulation. Now, I want to simulate several well-known flows, one could see them as scenario's. This usually boils down to correctly initializing the simulation. For example, I have the Taylor-Green vortex flow. The simulation does not need to know that it is simulating a particular flow, it only has to execute the simulation algorithm, so I created a separate class TaylorGreenVortex. The class TaylorGreenVortex has to initialize the Simulation in such a way that it corresponds to the Taylor-Green vortex flow. Now here comes the trouble: the initialization equations of the Taylor-Green vortex flow require many variables that are also needed by Simulation and therefore are present in that class. So, the result is that I added a lot of getters to the Simulation class to obtain these variables. This is however also undesired, because all these getters makes the Simulation class very exposed and also generates high coupling between Simulation and TaylorGreenVortex. In addition, it is also annoying that the initializer (TaylorGreenVortex) first constructs a Simulation object, so it can get the relevant variables, and then later resets other variables of the Simulation object so that it will simulate a Taylor-Green vortex flow.
I have thought about several solutions, but all of these solutions do not really solve the problem, but merely shift the problem to a different class or make the design even worse. For example, if I follow the 'information expert' pattern, then I should remove the TaylorGreenVortex class and move all its functionality to the Simulation class. This however makes the Simulation class bulky when the simulation has to support many different flows. I could also introduce some sort of Data class which has the variables required by both TaylorGreenVortex and Simulation, but then I have to add a lot of getters to this Data class so that Simulation and TaylorGreenVortex get the variables from Data. What are your suggestions for a clean solution? If you know of a particular design pattern related to the problem, could you please explain somewhat concretely how it can be applied in the above situation? Thanks in advance.
http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html
http://martinfowler.com/bliki/GetterEradicator.html
http://pragprog.com/articles/tell-dont-ask
To give a better advise I guess I should see the code, but from the description it sounds like you need a builder. However the TaylorGreenVortex class that you describe seems like it is doing the builder job, so maybe it is not what you are looking for, which puzzles me a bit. IMHO having a class that takes care of the simulations and different builder classes that know how to configure that simulation to represent different scenarios is a good design. I would start by having a constructor in the Simulation class that takes all the parameters a simulation needs and then let each specific builder pass the constructor arguments according to the specific simulation needs. If the parameters are too many then you may consider that there is something that you are not modeling and the Simulation class is having more than one responsibility (see SRP). In that case you may want to refactor the Simulation class, but again, it is hard to tell without looking at the code :(. Could you post some snippets?
HTH
I don't know much about the subject matter, or your design, so I can't comment totally on what you're trying to achieve (more snippets please) but it sounds like you're attempting to hold state (Simulation) in one location and what to do with that state (TaylorGreenVortexFlow) in the other, and are having problems decoupling them when the two need to interact.
Have you fully discarded the idea of inheritance from a common Simulation object? Overriding the timeStep() function to reflect what happens during a Taylor-Green Vortex Flow? This may be your only sensible option if you're using Java due to a lack of proper pass-by-reference.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I came across different interview where question was asked to me why encapsulation is used? Whose requirement actually is encapsulation? Is it for users of program? Or is it for co-workers? Or is it to protect code from hackers?
Encapsulation helps in isolating implementation details from the behavior exposed to clients of a class (other classes/functions that are using this class), and gives you more control over coupling in your code. Consider this example, similar to the one in Robert Martin's book Clean Code:
public class Car
{
//...
public float GetFuelPercentage() { /* ... */ };
//...
private float gasoline;
//...
}
Note that the client using the function which gives you the amount of fuel in the car doesn't care what type of fuel does the car use. This abstraction separates the concern (Amount of fuel) from unimportant (in this context) detail: whether it is gas, oil or anything else.
The second thing is that author of the class is free to do anything they want with the internals of the class, for example changing gasoline to oil, and other things, as long as they don't change its behaviour. This is thanks to the fact, that they can be sure that no one depends on these details, because they are private. The fewer dependencies there are in the code the more flexible and easier to maintain it is.
One other thing, correctly noted in the underrated answer by utnapistim: low coupling also helps in testing the code, and maintaining those tests. The less complicated class's interface is, the easier to test it. Without encapsulation, with everything exposed it would be hard to comprehend what to test and how.
To reiterate some discussions in the comments:
No, encapsulation is not the most important thing in OOP. I'd dare even to say that it's not very important. Important things are these encouraged by encapsulation - like loose coupling. But it is not essential - a careful developer can maintain loose coupling without encapsulating variables etc. As pointed out by vlastachu, Python is a good example of a language which does not have mechanisms to enforce encapsulation, yet it is still feasible for OOP.
No, hiding your fields behind accessors is not encapsulation. If the only thing you've done is write "private" in front of variables and then mindlessly provide get/set pair for each of them, then in fact they are not encapsulated. Someone in a distant place in code can still meddle with internals of your class, and can still depend on them (well, it is of course a bit better that they depend on a method, not on a field).
No, encapsulation's primary goal is not to avoid mistakes. Primary goals are at least similar to those listed above, and thinking that encapsulation will defend you from making mistakes is naive. There are just lots of other ways to make a mistake beside altering a private variable. And altering a private variable is not so hard to find and fix. Again - Python is a good example for sake of this argument, as it can have encapsulation without enforcing it.
Encapsulation prevents people who work on your code from making mistakes, by making sure that they only access things they're supposed to access.
At least in most OO languages, encapsulation is roughly equivalent to the lock on the door of a bathroom.
It's not intended to keep anybody out if they really insist on entering.
It is intended as a courtesy to let people know that entering will lead mostly to:
embarrassment, and
a stinking mess.
Encapsulation allows you to formalize your interfaces, separating levels of abstraction (i.e. "application logic accesses IO code only in this and this way").
This in turn, allows you to change the implementation of a module (the data and algorithms inside the module) without changing the interface (and affecting client code).
This ability to modify modules independently of each other, improves your ability to measure your performance and make predictions in a project's deadlines.
It also allows you to test modules separately and reuse them in other projects (because encapsulation also lowers inter-dependencies and improves modularity of your code).
Not enforcing encapsulation tends to lead to a project's failure (the problem grows with the complexity of the project).
I architected a fast-track project. Encapsulation reduces the propagation of change through the system. Changes cost time and money.
When code is not encapsulated, a person has to search many files to find where to make the change(s). Adversely, there is the question of "Did I find all the places?" and the other point "what effect to the entire system to do all of these scatter changes have?"
I'm working on an embedded medical device and quality is imperative. Also, all changes must be documented, reviewed, unit tested and finally a system test performed. By using encapsulation, we can reduce the number of changes and their locality, reducing the number of files that must be retested.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am working on a game/simulation application that uses multiple mathematical solvers. There is an already existing adapter class for each of them. These adapter classes provide all rendering and functional information for the application.
Broadly speaking, we keep an adapter object to represent an instance and call methods to achieve:
Generate rendering data.
modify object state. There are just too many function to do it.
read data model information for various purposes.
Now the problem is that these classes keep growing over a period of time and carry too much information and responsibility.
My question is how can I redesign/restructure these classes to make better sense. Is there any design pattern I should be looking at?
Edit: As requested, here is the broad list of things any adapter class will be doing.
Sync with the current data stored in mathematical solver.
Sync with the data model of our application. For things like
undo/redo.
Modify object state: Change in shape. This is most important and have
various, more than 50, functions to achieve it. All are self
contained single service call with parameters. I am trying to insert
interfaces and factory here but function signatures are not
compatible.
Get data model information of mathematical solver. Like getChildern
etc.
Change visibility and other graphic property.
The principle to use would be Information Expert from GRASP:
[…] Using the principle of Information Expert, a general approach to assigning responsibilities is to look at a given responsibility, determine the information needed to fulfill it, and then determine where that information is stored. Information Expert will lead to placing the responsibility on the class with the most information required to fulfill it. […]
Though never explicitly mentioned, applying this principle will likely lead you to using the patterns given by Martin Fowler in the chapter Moving Features Between Objects in his Refactoring book:
[…] Often classes become bloated with too many responsibilities. In this case I use Extract Class to separate some of these responsibilities. If a class becomes too irresponsible, I use Inline Class to merge it into another class. If another class is being used, it often is helpful to hide this fact with Hide Delegate. Sometimes hiding the delegate class results in constantly changing the owner’s interface, in which case you need to use Remove Middle Man […]
In general, break down your classes so that each only has one reason to change, per the Single Responsibility Principle. Leave your "adapters" in place as a Facade over the classes you'll extract; it will make the refactor smoother.
Since you describe a list of responsibilities that are common to all your adapters, you probably have a lot of code that is almost the same between the adapters. As you go through this exercise, try extracting the same responsibility from several adapters, and watch for ways to eliminate duplication.
It would be tempting to start with extracting a class for "Modify Object state". Since you have more than 50 (!) functions fulfilling that responsibility, you should probably break that down into several classes, if you can. As this is likely the biggest cause of bloat in your adapter class, just doing it may solve the problem, though it will be important to break it down or you'll just move the God class, instead of simplifying it.
However, this will be a lot of work and it will likely be complex enough that you won't easily see opportunities for reuse of the extracted classes between adapters. On the other hand, extracting small responsbilities won't get you a lot of benefit. I would pick something in the middle to start.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I'm trying to get into OOP lately, and I'm having trouble with SOLID principles and design patterns. I see why people use them, and I really want to use them too, but I can't wrap my head around developing my classes to the specifications. I would really appreciate anything that would help my understanding of such.
I've taken a class in college that spent two weeks around design patters, and read the Gang of Four book to no avail. Understanding what each pattern served for and how to use them to fit my problems was very hard for me, a developer that didn't have much experience in OO programming.
The book that really made it click for me was Head First Design Patterns. It starts by showing a problem, different approaches the developers considered, and then how they ended up using a design pattern in order to fix it. It uses a very simple language and keeps the book very engaging.
Design patterns end up being a way to describe a solution, but you don't have to adapt your classes to the solution. Think of them more as a guide that suggest a good solution to a wide array of problems.
Let's talk about SOLID:
Single responsibility. A class should have only one responsibility. That means that for example, a Person class should only worry about the domain problem regarding the person itself, and not for example, its persistence in the database. For that, you may want to use a PersonDAO for example. A Person class may want to keep its responsibilities the shortest it can. If a class is using too many external dependencies (that is, other classes), that's a symptom that the class is having too many responsibilities. This problem often comes when developers try to model the real world using objects and take it too far. Loosely coupled applications often are not very easy to navigate and do not exactly model how the real world works.
Open Closed. Classes should be extendible, but not modifiable. That means that adding a new field to a class is fine, but changing existing things are not. Other components on the program may depend on said field.
Liskov substitution. A class that expects an object of type animal should work if a subclass dog and a subclass cat are passed. That means that Animal should NOT have a method called bark for example, since subclasses of type cat won't be able to bark. Classes that use the Animal class, also shouldn't depend on methods that belong to a class Dog. Don't do things like "If this animal is a dog, then (casts animal to dog) bark. If animal is a cat then (casts animal to cat) meow".
Interface segregation principle. Keep your interfaces the smallest you can. A teacher that also is a student should implement both the IStudent and ITeacher interfaces, instead of a single big interface called IStudentAndTeacher.
Dependency inversion principle. Objects should not instantiate their dependencies, but they should be passed to them. For example, a Car that has an Engine object inside should not do engine = new DieselEngine(), but rather said engine should be passed to it on the constructor. This way the car class will not be coupled to the DieselEngine class.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have two buttons that each can perform two different implementations (whether selected or not), so that's 4 possible implementations in total. After coding it all out, I noticed I had 20+ lines of code for each implementation and only 1 or 2 variables were different in each. I decided I want to clean this up and have each implementation call separate, smaller methods and pass the inconsistent variables as parameters.
I figure this is a better practice b/c I'm reusing code. However, in one of my methods I have to pass 5 different arguments implement the method with correct conditions.
Is having this many parameters in a method a bad practice?
Having many parameters is not necessary a bad thing.
There are patterns that create a class to group all the parameters into one object that may seem cleaner to you. Another alternative is to use a dictionary for with all the parameters as the single configuration parameter. Some of Apples classes does this (for example title font configuration in the navigation bar).
I personally would say that code repetition is worse than many methods calling each other and having multiple parameters.
If it allow you to remove many duplicate lines, I don't see any problem to do it this way.
If it's to remove 1 or 2 lines then it might not worth the effort.
In fact you can pass as many arguments as needed. There might be other ways to do what you what to achieve but without the code your 5 arguments seems valid at first glance.
There is no specific number of parameters that is generally "bad practice". A method should have as many parameters as it needs. That said, there are cases where having a large number of parameters may indicate that a better design might be possible. For example, there are cases where you may realize an object should be tracking some value in a member variable instead of having the value passed into its methods every time.
I think it's okay to use 5 params because some objective-c default method are also having 4 params like
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateConvMenu:)
notificationName:#"NSConvertersChanged"
object:converterArray];
What we can do to make it more clear is giving a better format to your code
disclaimer: I know zilch about objective c
It is difficult to say without seeing the code in question, and it completely depends on what you are doing. To say that having a method with five parameters is bad practice right off the bat is a bit presumptive, although it is certainly good practice to keep the number of method parameters as small as possible.
The fact that this method sounds like an internal 'helper' method (and not a publicly exposed component of an API) gives you more lee-way then you might otherwise have, but typically you do not want to be in a situation where a method is doing different things based on some arcane combination of parameters.
When I run into methods with uncomfortably long signatures that cannot be restructured without creating redundant code, I typically do one of the following:
wrap the offensive method with several more concise methods. You might create, as an example, a method for each of your 'implementations', with a good name indicating its purpose that accepts only the arguments needed for that purpose. It would then delegate to the internal, smellier method. The smelly method would only ever be used in your 'implementation specific' wrappers instead of being scattered throughout your code. Using the well named wrappers in its stead, developers will understand your intent without having to decipher the meaning of the parameters.
Create a Class that encapsulates the data needed by the method. If what the method does depends on the state of some system or subsystem, then encapsulate that state! I do this often with 'XXContext' type classes. Now your method can inspect and analyze this contextual data and take the appropriate actions. This is good for refactoring as well. If the method in the future needs more information to accomplish its tasks or implement new functionality, you can add this data to the argument object, instead of having to change every bit of code that uses the method. Only code that needs to make use of the changes will have to supply the the appropriate values to the contextual data.
This is one of those subjective questions that's really hard to answer definitively.
I don't mind a number of parameters in an Objective C method as it can make the API that's being called more clear (and the parameters can be nice & type safe, too).
If you can distill those many functions down to a smaller number of functions (or a "base" function which is called from all the other functions), that's probably also makes for cleaner code that's easier to follow and read. Plus if you make an update to that "base" function, the functionality change will be picked up by all the ways you call your action (that's can also be a good or bad thing, of course).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
You are writing a Tetris program in Java. How would you set up your class design with regards to the following aspects?
Piece class: Have one Piece class, with an internal array which determines the shape of the piece, versus having seven Piece classes, one for each of the pieces. They are all subclasses of one generic Piece class.
Piece class representation: Have an array of 4 instances of Block, representing one square of a piece, and each Block contains its location on the Board (in graphical coordinates) vs. having a 4x4 array where null means there is no block there, and location is determined by the shape of the array.
Location: Each Block in the Piece array or on the Board array stores its location vs. the Piece and the Board know the locations of the Blocks that comprise them.
Generating a Piece: Have a static method of the Piece class getRandomPiece, or have a PieceFactory which you make one instance of that has the genRandomPiece method on the instance.
Manipulating the current piece: Use the Proxy pattern, so that everything that needs access to it just uses the proxy, or have a getCurrentPiece method on the Board class and call that any time you want to do something with the current piece.
This is not homework. I'm just at odds with what the intro CS course teaches at my college and I want to see what people in general believe. What would be thought of as "good" OOP design? Ignore the fact that it's for an intro course - how would you do it?
Firstly, I wouldn't subclass the Piece class because it's unnecessary. The Piece class should be capable of describing any shape without using inheritance. IMHO, this isn't what inheritance was made for and it just complicates things.
Secondly, I wouldn't store the x/y coordinates in the Block objects because it allows two blocks to exist in the same place. The Piece classes would keep a grid (i.e. 2D array) holding the block objects. The x/y coordinates would be the indexes of the 2D array.
As for the static method vs factory object for getting a random piece, I'd go with the factory object for the simple fact that the factory object can be mocked for testing.
I would treat the board as one large Piece object. The Board class would keep the large Piece object as a member variable, and might keep other Piece objects such as the current piece being played, and the next piece to be played. This is done using composition to avoid inheritance.
All these classes and stuff... it might be making the problem way too abstract for what it really is. Many different ways to represent tetris pieces (stackoverflow.com/questions/233850/…) and many different ways to manipulate them. If it's for an intro course I wouldn't worry about OOP. Just my opinion, not a real answer to your question.
Having said that, one could suffice with simply a Board and Piece class.
Board class: Encapsulates a simple 2d array of rectangles. Properties like currentpiece, nextpiece. Routines like draw(), fullrows(), drop(), etc.. which manipulate the current piece and the filled in board squares.
Piece class: Encapsulates an array of unsigned 16 bit numbers encoding the pieces in their various rotations. You would track color, current location, and rotation. Perhaps one routine, rotate() would be necessary.
The rest, would be, depending on the environment, handling keyboard events etc...
I've found that placing too much emphasis on design tends to make people forget that what they really need to do is to get something running. I'm not saying don't design, I'm saying that more often than not, there is more value in getting something going, giving you traction and motivation to keep going.
I would say, to the class, you have X hours to make a design for a tetris game. Then they would need to turn in that design. Then I would say, you have X days, to get something running based on the design you turned in or even not based on the design.
One Piece interface, with seven classes that implement that interface for the individual pieces (which would also enable the OOP course to discuss interfaces) (EDIT: One Piece class. See comments)
I would have a BlockGrid class that can be used for any map of blocks - both the board, and the individual pieces. BlockGrid should have methods to detect intersections - for example, boolean intersects(Block block2, Point location) - as well as to rotate a grid (interesting discussion point for the course: If the Board doesn't need to rotate, should a rotate() method be in BlockGrid?). For a Piece, BlockGrid would represent be a 4x4 grid.
I would create a PieceFactory with a method getRandomShape() to get an instance of one of the seven shapes
For manipulating the piece, I'd get into a Model-View-Controller architecture. The Model is the Piece. The Controller is perhaps a PieceController, and would also allow or disallow legal/illegal moves. The thing that would show the Piece on the screen is a PieceView (hrm, or is it a BlockGridView that can show Piece.getBlockGrid()? Another discussion point!)
There are multiple legitimate ways to architect this. It would benefit the course to have discussions on the pro's and con's of different OOP principles applied to the problem. In fact, it might be interesting to compare and contrast this with a non-OOP implementation that just uses arrays to represent the board and pieces.
EDIT: Claudiu helped me realize that the BlockGrid would sufficiently differentiate pieces, so there is no need for a Piece interface with multiple subclasses; rather, an instance of a Piece class could differ from other instances based on its BlockGrid.
Piece class: I think that a single class for all the pieces is sufficient. The class functions shoudl be general enough to work for any piece, so there is no need to subclass.
Piece Class Representation: I believe that a 4x4 array is probably a better way as you will then find it much easier to rotate the piece.
Location: Location should definitely be stored by the board, not the piece as otherwise you would have to go through the entire set of blocks to ensure that no two blocks are in the same position.
Generating a Piece: Honestly for this one I do not feel that it will make too much of a difference. Having said that, I would prefer a static function as there is really not so much to this function that it warrants its own class.
Manipulating the Current Piece: I would just implement a getCurrent function as I feel that there is no need to overcomplicate the problem by adding in an extra class to serve as a proxy.
This is how I would do it, but there are many different ways, and at the end of the day, the thing to focus on is simply getting the program running.