This might sound like a weird idea and I haven't thought it through properly yet.
Say you have an application that ends up requiring a certain number of singletons to do some I/O for example. You could write one singleton and basically reproduce the code as many times as needed.
However, as programmers we're supposed to come up with inventive solutions that avoid redundancy or repetition of any kind. What would be a solution to make multiple somethings that could each act as a singleton.
P.S: This is for a project where a framework such as Spring can't be used.
You could introduce an abstraction like this:
public abstract class Singleton<T> {
private T object;
public synchronized T get() {
if (object == null) {
object = create();
}
return object;
}
protected abstract T create();
}
Then for each singleton, you just need to write this:
public final Singleton<Database> database = new Singleton<Database>() {
#Override
protected Database create() {
// connect to the database, return the Database instance
}
};
public final Singleton<LogCluster> logs = new Singleton<LogCluster>() {
...
Then you can use the singletons by writing database.get(). If the singleton hasn't been created, it is created and initialized.
The reason people probably don't do this, and prefer to just repeatedly write something like this:
private Database database;
public synchronized Database getDatabase() {
if (database == null) {
// connect to the database, assign the database field
}
return database;
}
private LogCluster logs;
public synchronized LogCluster getLogs() {
...
Is because in the end it is only one more line of code for each singleton, and the chance of getting the initialize-singleton pattern wrong is pretty low.
However, as programmers we're supposed to come up with inventive solutions that avoid redundancy or repetition of any kind.
That is not correct. As programmers, we are supposed to come up with solutions that meet the following criteria:
meet the functional requirements; e.g. perform as required without bugs,
are delivered within the mandated timeframe,
are maintainable; e.g. the next developer can read and modify the code,
performs fast enough for the task in hand, and
can be reused in future tasks.
(These criteria are roughly ordered by decreasing priority, though different contexts may dictate a different order.)
Inventiveness is NOT a requirement, and "avoid[ing] redundancy or repetition of any kind" is not either. In fact both of these can be distinctly harmful ... if the programmer ignores the real criteria.
Bringing this back to your question. You should only be looking for alternative ways to do singletons if it is going to actually make the code more maintainable. Complicated "inventive" solutions may well return to bite you (or the people who have to maintain your code in the future), even if they succeed in reducing the number of lines of repeated code.
And as others have pointed out (e.g. #BalusC), current thinking is that the singleton pattern should be avoided in a lot of classes of application.
There does exist a multiton pattern. Regardless, I am 60% certain that the real solution to the original problem is a RDBMS.
#BalusC is right, but I will say it more strongly, Singletons are evil in all contexts.
Webapps, desktop apps, etc. Just don't do it.
All a singleton is in reality is a global wad of data. Global data is bad. It makes proper unit testing impossible. It makes tracing down weird bugs much, much harder.
The Gang of Four book is flat out wrong here. Or at least obsolete by a decade and a half.
If you want only one instance, have a factory that makes only one. Its easy.
How about passing a parameter to the function that creates the singleton (for example, it's name or specialization), that knows to create a singleton for each unique parameter?
I know you asked about Java, but here is a solution in PHP as an example:
abstract class Singleton
{
protected function __construct()
{
}
final public static function getInstance()
{
static $instances = array();
$calledClass = get_called_class();
if (!isset($instances[$calledClass]))
{
$instances[$calledClass] = new $calledClass();
}
return $instances[$calledClass];
}
final private function __clone()
{
}
}
Then you just write:
class Database extends Singleton {}
Related
Trying to understand the concept of encapsulation, I came across this definition "Combining the attributes and methods in the same entity in such a way as to hide what should be hidden and make visible what is intended to be visible".
But practicing the same, I am not sure which of the following code is more apt for OOP:
public class Square {
//private attribute
private int square;
//public interface
public int getSquare(int value) {
this.square = value * value;
return this.square;
}
}
or
public class Square {
//private attribute
private int square;
//public interface
public int getSquare(int value) {
this.square = calculateSquare(value);
return this.square;
}
//private implementation
private int calculateSquare(int value) {
return value * value;
}
}
Combining the attributes and methods in the same entity in such a way as to hide what should be hidden and make visible what is intended to be visible
This is a potentially misleading statement. You are NOT hiding anything from anyone. It is also not about methods or fields. Unfortunately this is the way things are worded in almost every place.
How
When writing any piece of program, (be it a function, class, module, or library) we think of the piece we are working on as my code, every other code as my client code. Now assume that all the client code is written by someone else, NOT you. You write just this code. Just assume this, even if you are the only one person working on the entire project.
Now the client code needs to interact with my code. So my code should be nice and decent to talk to. The concept of encapsulation says, that I partition my code in two parts, (1) that the client code should be bothered with, (2) that the client code should NOT be bothered with. The OO way of achieving encapsulation is by using keywords like public and private. The non OO way of achieving this is naming convention like leading underscores. Remember, you are not hiding, you are just marking it as none-of-your-business.
Why
So why should we encapsulate things? What should be organize my code into public and private regions? When someone uses my code, they are of-course using the whole thing, not just public thing, so how come private is something that is none-of-their-business? Note here words like someone and their could refer to yourself - but only while working on the other piece of code.
The answer is easy testability and maintainability. A complete project if tested exhaustively, can be quite a task. So at minimum, when you are done coding, you just test the public aspects of my code. You do not test any of the client code, you do not test any of the private aspects of my code. This reduces test effort while preserving sufficient coverage.
Another aspect is maintainability. My code will NEVER be perfect, it WILL need revisions. Either because of bugfix or enhancement, my code will need tinkering. So when a new version of my code is available, how much is client code impacted? None, if changes are in private regions. Also, while planning a change, we try to confine it as much as possible in private regions. So the change, from client's perspective becomes a no-impact. A change in public aspects of my code, will almost always require changes in client code, now that will need testing. While planning the big picture of my code, we try to maximize the area under private regions and minimize the area under public regions.
And more
The idea of encapsulating links with the idea of abstracting which in turn links with idea of polymorphism. None of these are strictly about OO. Even in non OO world like C or even Assembly, these apply. The way to achieve these differ. Even this applies to things beyond computers.
The process of sewage management, for example, is
encapsulated within the public interface of drains. The general public bothers only with the drains. The treatment, the disposal, the recycling are none of general public's business. Thus, the sewage management could be treated as an -
abstract entity - an interface with just the drains. Different government and companies implement this in their own way. Now an city may have a permanent system of sewage management, or it can periodically -
switch providers. In fifty years of government operation, the situation was bad, but once they contracted that BigCorp Inc, now people can breathe free. We just did polymorphism. We switched implementations, keeping the public interface same. Both government and the BigCorp Inc use the same drains, but their own processing facilities, which are encapsulated away and polymorphically switchable.
In your code
In both your codes you chose to encapsulate the storage, the field is made private. This is a nice approach and certainly OO way. In both of your codes, the algorithm is also encapsulated - i.e not visible to the client. Nice. In your second code, you went ahead and extracted the algorithm in a separate non-public method. This is commendable approach, although obviously an overkill for doing something trivial. Better OO none the less.
What you did in second code even has a name: the strategy pattern. Even though here it is useless (and overkill), it could be useful in a scenario when let say you are dealing with extremely large numbers, such that calculating their squares take very long time. In such a scenario, you could make your calculateSquare method protected, have a class FastButApproxSquare extends Square, and override the calculateSquare method with a different algo which calculates an approx value much faster. This way you could do Polymorphism. Whoever needs exact value will use the Square class. Whoever needs approx value will use FastButApproxSquare class.
Encapsulation is about hiding implementation and structure details from client code. In addition it is about coherence: keep things close together which are highly related to each other.
For example consider a class which manages players of a football team:
public class FootballTeam {
public final List<Player> players = new ArrayList<>();
}
Client code would have access to the list of players, to look them up, to add players and so on:
public class FootballManager {
private final FootballTeam team = new FootballTeam();
public void hirePlayer(Player player) {
team.players.add(player);
}
public void firePlayer(int jerseyNo) {
Optional<Player> player = team.players.stream()
.filter(p -> p.getJerseyNo() == jerseyNo)
.findFirst();
player.ifPresent(p -> team.players.remove(p));
}
}
Now, if someone decides to change the field FootballTeam.players into a Map<Integer, Player>, mapping the players jersey number to the player, the client code would break.
In addition the client code deals with aspects / features closely related to a player. To protect the client code and to ensure changeability of the FootballTeam implementation hide all implementation details, keep player related functionality close to the structure, representing the team and reduce the public interface surface:
public class FootballTeam {
private final Map<Integer, Player> players = new HashMap<>();
public void addPlayer(Player player) {
players.put(player.getJerseyNo(), player);
}
public Optional<Player> lookupPlayer(int jerseyNo) {
return Optional.ofNullable(players.get(jerseyNo));
}
public void remove(Player player) {
players.remove(player.getJerseyNo());
}
}
public class FootballManager {
private final FootballTeam team = new FootballTeam();
public void hirePlayer(Player player) {
team.addPlayer(player);
}
public void firePlayer(int jerseyNo) {
team.lookupPlayer(jerseyNo)
.ifPresent(player -> team.remove(player));
}
}
If any code serves the purpose of encapsulation then that code is correct. The purpose of encapsulation is to provide a process of hiding the variables from other classes (i.e. by making the variable as private) and also to provide a way for other classes to access and modify the variables. Both of your code serves this purpose correctly.
If you would have used "calculateSquare(int value)" method as "public" then there would have been a problem. Other class could call this method directly without using set/get method. So as far as your this method is "private" I think both the codes are all right.
In an e-commerce application, below are the high level API
interface Order{
public List<PaymentGroup> getPaymentGroups();
}
interface PaymentGroup{}
class PaymentGroupImpl implements PaymentGroup{}
class CreditCard extends PaymentGroupImpl{}
class GiftCard extends PaymentGroupImpl{}
class OrderManager{ //Manager component used to manipulate Order}
There is a need to add some utility methods like hasGiftCard(), hasCreditCard(), getGiftCards(), getCreditCards()
Two approaches -
1) Add these in Order. However, this would result in coupling between Order and PaymentGroup implementors (like CreditCard, GiftCard) Example -
interface Order {
public List<GiftCard> getGiftCards();
}
2) Move these to OrderManager.
class OrderManager{
public List<GiftCard> getGiftCards(Order order){}
}
I personally prefer 2), am just curious would there be any reason to choose 1) over 2)
I have two answers. One is what I'll call Old Skool OOP and the other I'll call New Skool OOP.
Let's tackle New Skool first. The GoF and Martin Fowler changed the way people look at OOP. Adding methods like hasGiftCard() leads to adding conditional logic/branching into the code. It might look something like this:
if (order.hasGiftCard()) {
//Do gift card stuff
} else {
//Do something else
}
Eventually this kind of code becomes brittle. On a big application, lots of developers will be writing predicate methods. Predicate methods assert something and return true or false. These methods usually start with the word "has", "is" or "contains". For example, isValid(), hasAddress(), or containsFood(). Still more developers write conditional logic that uses those predicate methods.
To avoid all of this conditional logic software engineers changed how they thought about object-orientation. Instead of predicate-methods-and-conditional-logic, they started using things like the strategy pattern, visitor pattern, and dependency injection. An example from your problem domain might look like this:
//Old Skool
if (this.hasCreditCard()) {
orderManager.processCreditCard(this.getCreditCards());
}
Here is another approach to solving the same problem:
//New Skool
for(PaymentItem each : getPaymentItems()){
each.process(this);
}
The New Skool approach turns the problem on its head. Instead of making the Order and OrderManager responsible for the heavy lifting the work is pushed out to the subordinate objects. These kind of patterns are slick because:
they eliminate a lot of "if" statements,
the code is more supple and it is easier to extend the application, and
instead of every developer making changes to Order and OrderManager, the work is spread out among more classes nd code merges are easier.
That's New Skool. Back in the day, I wrote a lot of Old Skool object-oriented code. If you want to go that route, here are my recommendations.
IMHO, you don't need both a PaymentGroup interface and a PaymentGroupImpl class. If all payment classes extend PaymentGroupImpl, then get rid of the interface and make PaymentGroup a class.
Add methods like isCreditCard(), isGiftCertificate() to the PaymentGroup class. Have them all return "false".
In the subclasses of PaymentGroup, override these methods to return true where appropriate. For example, in the CreditCard class, isCreditCard() should return "true".
In the Order class, create methods to filter the payments by type. Create methods like getCreditCards(), getGiftCertificates(), and so on. In traditional Java (no lambdas or helper libraries), these methods might look something like this
List getCreditCards() {
List list = new ArrayList();
for(PaymentGroup each : getPaymentGroups()){
if(each.isCreditCard()) {
list.add(each);
}
return list;
}
-In the Order class, create predicate methods like hasCreditCards(). If performance is not an issue, do this:
boolean hasCreditCards() {
return !getCreditCards().isEmpty();
}
If performance is an issue, do something more clever:
boolean hasCreditCards() {
for(PaymentGroup each : getPaymentGroups()){
if(each.isCreditCard()) {
return true;
}
return false;
}
}
Realize that if you add a new payment group, a code must be added in a lot of places in the Old Skool paradigm.
What is the correct way I should initialise my class in android, the class is called Compilation and it has all its values in the db.
I can do the following :
1
public Compilation(int id)
{
// get db singleton here and fill all values
// however I feel this is bad OO because nobody knows I am doing this
}
2
public Compilation(int id, SQLiteDatabase db)
{
// use the provided db to get the info
// however now all calling classes will have to get the db for me
}
3
// get all compilations at once
SQLiteDatabase db = DatabaseHelper.getInstance().getReadableDatabase();
Cursor c = db.rawQuery("SELECT * FROM Compilation", null);
while(c.moveToNext())
{
// get all params here
Compilation comp = new Compilation (a,b,c,d,e);
}
public Compilation(a,b,c,d,e)
{
// just assign all the values given to private vars
}
The problem I see with this is that now the Compilation class is no longer so self contained, it needs another class to initialise it.
Which one is the proper way to do it?
The general rule in software design tells us that we should create Classes which have the minimum dependency on other parts of the software system. This way we end up with Classes which are better reusable.
The first alternative you have proposed is the worst one because its create a very tight dependency on one specific data provider( sqlite ). Maintenance of such class can be a nightmare( Just imagine that the next release of Android will come with sqlite or mysql :) and you want to switch to mysql)
The second one is kinda better if you would replace the constructor parameter from a Class to an Interface and thus creating something that we call Dependency injection .However there are better ways of doing dependency injection on Android (check out for example Dagger)
The third one seems to me as the best fit, since you don't create any dependency. Perhaps to ease the creation of such classes (and to make the code a little bit more "enterprise"), you could create a factory class which would create the instances of Compilation Class (more about this here )
In the very end however this is not a question about Android best practices but about software design decisions which highly depend on what are you trying to do!
All your options are correct, but I think a factory based approach will work fine. I've used it in different occasions. I just wrote down a skeleton of such an alternative approach.
public class CompilationFactory
{
// DB instance and/or cache implementation (HashMap based or via 3rd party lib)
static
{
// DB init stuff here
// if your app logic allows it you can also cache Compilation to avoid
// reading the DB multiple times
}
public static Compilation compilationForId(int id)
{
// either read your Compilation from the DB or from the precomputed cache
}
}
I wouldn't do it this way, I'd use an empty constructor then use an Application (http://developer.android.com/reference/android/app/Application.html) and serve my self the DB from the Application so I don't have to keep instantiating. Might be too advanced if you're doing a school project but yeah..
This depends slightly on the implementation of your Database - if you're using content providers or not, etc.
All of the provided examples are "correct" from the standpoint that they will work. That said number 3 is a red flag to me. Without further code to clarify you run the risk of calling "getReadableDatabase" more than once, which is unescesary.
Beyond that point, it's difficult to know exactly what to recommend you here. There are fancy ways to do this, and they might be overkill for you depending on your projects nature.
I'm going to operate under the assumption that you have a Class which manages Compilations. Something like, and keepping it simple in this case would be the following:
public class CompliationManager() {
private ArrayList<Compilation> myCompilations = new ArrayList<Compilation>();
SQLiteDatabase db;
public CompilationManager() {
db = DatabaseHelper.getInstance().getReadableDatabase();
}
public void loadCompliations() {
Cursor c = db.rawQuery("SELECT * FROM Compilation", null);
while(c.moveToNext()) {
Compilation comp = new Compilation(c);
myCompilations.add(comp);
}
c.close();
}
}
public class Compilation() {
public Compilation(Cursor c) {
// do the actual retrival, setting of fields etc...
getCompilationFromCursor();
}
}
I'm currently currently working with a rather massive project with several classes of over 20, 000 lines. This is because it was someone's bright idea to mix in all the generated swing code for the UI with all of the functional code.
I was wondering if it would incur any extra cost in terms of memory or run time, to move most of the non-UI related functions into a separate class.
To provide an example, this is something along the lines of what I'm building.
public class Class1{
private Class1Util c1u;
List<String> infoItems;
...
public void Class1(){
c1u = new Class1Util(this);
}
public void btnAction(ActionListener al){
...
c1u.loadInfoFromDatabase();
}
}
public class Class1Util{
private Class1 c;
public void Class1Util(Class1 c){
this.c = c;
}
public void loadInfoFromDatabase(){
c.infoItems.add("blah");
}
}
Eventually, I'd also like to move some of the fields like infoItems over as well, which would result in a reverse relationship, with Class1 accessing c1u.infoItems.
no, separation of concerns is a good object oriented design practice. it will not cost you anything meaningful in terms of performance and will gain you many, many benefits in terms of maintenance, extensibility, etc.
You may get a tiny performance hit for an extra level of dereferencing, but it would not be noticeable in a UI code, and you will get so much extra clarity in return that you wouldn't regret it.
Eventually you may want to externalize state keeping into a third class, and then use that state from both your hand-written and generated code, or use the Generation Gap Pattern to manage complexity introduced by the need to integrate with the generated code.
I havent used a lot of static methods before, but just recently I tend to use more of them. For example if I want to set a boolean flag in a class, or acess one without the need to pass the actual object through classes.
For example:
public class MainLoop
{
private static volatile boolean finished = false;
public void run()
{
while ( !finished )
{
// Do stuff
}
}
// Can be used to shut the application down from other classes, without having the actual object
public static void endApplication()
{
MainLoop.finished = true;
}
}
Is this something I should avoid? Is it better to pass a object so you can use the objects methods? Does the boolean finished counts as a global now, or is it just as safe?
A problem with using a static variable in this case is that if you create two (or more) instances of MainLoop, writing code that looks like it is shutting down only one of the instances, will actually shut down both of them:
MainLoop mainLoop1 = new MainLoop();
MainLoop mainLoop2 = new MainLoop();
new Thread(mainLoop1).start();
new Thread(mainLoop2).start();
mainLoop1.finished = true; // static variable also shuts down mainLoop2
This is just one reason (amongst many) for choosing to not use static variables. Even if your program today only creates one MainLoop, it is possible that in the future you may have reason to create many of them: for unit testing, or to implement a cool new feature.
You may think "if that ever happens, I'll just refactor the program to use member variables instead of static variables." But it's generally more efficient to pay the cost up front, and bake modular design into the program from the start.
There's no question that statics often make a quick and dirty program easier to write. But for important / complex code that you intend to test, maintain, grow, share, and use for years to come, static variables are generally recommended against.
As other answers to this question have noted, a static variable is a kind of global variable. And there's lots of information about why (generally) global variables are bad.
Yes, passing objects around is better. Using a singleton or static methods makes OO programming look like procedural programming. A singleton is somewhat better because you can at least make it implement interfaces or extend an abstract class, but it's usually a design smell.
And mixing instance methods with static variables like you're doing is even more confusing: you could have several objects looping, but you stop all of them at once because they all stop when a static variable changes.
Is this something i should avoid?
In general, yes. Statics represent global state. Global state is hard to reason about, hard to test in isolation, and generally has higher thread-safety requirements.
If I want to test what happens to an object in a certain state, I can just create the object, put it into that state, perform my tests, and let it get garbage collected.
If I want to test what happens to global state, I need to make sure I reset it all at the end of my test (or possibly at the start of every test). The tests will now interfere with each other if I'm not careful about doing that.
Of course, if the static method doesn't need to affect any state - i.e. if it's pure - then it becomes somewhat better. At that point all you're losing is the ability to replace that method implementation, e.g. when testing something that calls it.
In general, by making finished static like that you create a situation where there can only be one instance of your MainLoop class executing run at any one time. If there is more than one instance then setting finished will end them all -- not what is usually desired.
However, in this particular scenario, where you want to "end application", presumably meaning you want to end all instances of MainLoop, the approach may be justified.
However, the number of situations where this approach may be merited are few, and a "cleaner" way to handle this scenario would be to keep a static list of instances and work through the list, setting the instance variable finished in each instance. This allows you to also end individual instances, gives you a natural count of existing instances, etc.