Is there a pattern similar to Singleton?

Asked

Viewed 141 times

3

It’s really frustrating, a little interesting maybe, but frustrating above all, just yesterday I figured out how and why to use the pattern Singleton, And today, as I was about to finish a little improvement on a project, I saw the true face of the pattern. Let’s just say I’m a little lost at the moment, because I made the system based on that pattern, and that’s about 10 classes, each containing an average of 6~7 methods, not counting the properties. I don’t know the other patterns because I never had a chance to try them out and see how they work, or how far they go.

Let’s say I have this script:

# instancia para retornar todos os valores no banco de dados
$database = Database::getInstance()->get(false,array('nickname','like','',true));

# teste, para a mensagem da sessão
if(Session::exists('sucesso')):
    print Session::pop('sucesso');
    print "<br/>";
endif;

# teste, para a sessão
if(Session::exists(Config::get('session@session_name'))){
    //print Session::get(Config::get('session@session_name')) . "<br/>";
    print Hash::decode(Session::get(Config::get('session@session_name'))) . "<br/>";
}

# teste, para o login
# classe faz o uso de Database::getInstance()
$usuario = new User();
if($usuario->logado()){
    print "Logado";
} else {
    print "Logue primeiro";
}

# Iterar o objecto e imprimir os respectivos valores
if($database){
    print "<p><b>(".$database->count().") Resultados Encontrados</b></p>";
    $campo_s = Config::get('mysql_fetch@campo_s');
    $campo_n = Config::get('mysql_fetch@campo_n');
    foreach($database->results() as $key=>$object){
        print $object->$campo_s . ' - ' . $object->$campo_n. "<br/>";
    }
} else {
    print Database::error();
    print "Consulta não efetuada";
}

# teste, para a hora
print "<p>Data:\r<b>".Config::dateTime()."</b></p>";

Right in the first line of this code script, I have an instance of my connection, and I also passed some parameters to make a query, for now everything is fine.

Somewhere around the middle of script, create a class instance User which perhaps also makes use of the connection class, and sets parameters for an authentication search.

In the loop foreach I was supposed to be able to print all the values corresponding to my first query in the database, but that’s not what happens, I get only 1 single result, which refers to the authenticated user. I soon got to thinking, what I’m doing wrong, after 35~40s I realized it was the pattern I’m currently using, that is, if a base of operation is set right at the top, and suddenly another instruction comes up in the middle, the rest of the block acts according to these instructions, even if it involves rewriting the search.

At bottom it’s just a linear operation, where all the instructions are processed in line, as if it were a thin pipe.

Here’s the pattern, used:

private function __construct(){

}
// Singleton initialization
public static function getInstance(){
    if(is_null(self::$_instance)){
        self::$_instance = new Database();
    }
    return self::$_instance;
    # Desta forma funciona, mas viola o principio do padrão aplicado
    # Procurar possível solução (encontrada).
    /*
    self::$_instance = new Database();
    return self::$_instance;
    */
}

At first I did tests to see if it was really because of the pattern, so I started at the core of this pattern, where I removed the condition responsible for creating unique instances, and I did the following:

self::$_instance = new Database();
return self::$_instance;

I passed the test and it worked, so I had to return the method as it was, because this way I would be violating the pattern, and do "I don’t know what", that somehow had solved my problem.

Then I thought, because they are linear instructions and processed one by one, why not move the first instance to the end of the first block? So that’s what I did.

$database = Database::getInstance()->get(false,array('nickname','like','',true));

I moved this instance to after the first, I did the test and it worked normally.

I can say that at the moment I found no problems in using the pattern in this project, but what I would really like to know is:

What is the pattern with the most resemblance to the Singleton, that allows me to use public methods without prior instance?

Or, what is the alternative method that can be easily implemented in a project in half or almost at the end? Taking into account that it would rewrite only the connection instance in the connection class, keeping the structure in the scripts or Clases that make use of it.

1 answer

7


I will not answer anything from the beginning that is not very relevant because it would take a lot of time and deep down you will not want the solution I have, but it is all wrong. It’s not a pattern problem, it’s the lack of it as it was conceived. This would not happen if it had developed in a simple way using techniques that dominates.

There is no similar pattern. Actually the closest is not to use this pattern. Or it uses a totally static class, without needing to create an instance or even the class creates, it does everything "procedural". Or leave it the way it is because the problem is different. This would be the best, since it started to do so. It would be difficult to change without rethinking the whole project.

I think you’ve fallen into the syndrome of Pattern design. Which is very common. You’ve heard so much about the PD that you thought you had to use it somewhere. Can you say any real advantage to your code obtained by using it? Be compared to a static class, or no class at all.

I feel like you just wanted to take a trip and had to learn mechanics and assemble the engine to get what you wanted. Obviously, the first set-ups will go wrong, so when you start putting it together you’ll realize you didn’t have to do this.

Experienced programmers - and not stubborn ones - have learned (or by having made a mistake, or by having read good publications, or by self-perception) that it is easier just to make the trip.

  • You’re partly right, that maybe it’s all wrong, and that I got caught up in the syndrome, and on the other hand I have to say you’re wrong, because before I started improve/update this project I already knew, and yet I started to wonder which of the ways should proceed, knowing that sometimes doing things using the techniques we best master is better than trying new techniques with which we have no practice ...

  • And I simply decided to implement the standard in order to standardize or parameterize the connection using say techniques "recommended", because you should also know that sometimes it is preferable to make use of methods tested and approved by a community, because they have already passed the tests of "pros/cons", but that’s not what was intended at all, let’s say I wanted to make an improvement, while doing tests, these tests based on standards ...

  • Still in one of my questions I said I am not provided with much knowledge in POO, so I try to learn the most diverse existing practices for this type of programming. Above all I thank you for your constructive and sincere reply. I can see what solution you have ?

  • Experimentation is not done in code that goes into production. These "recommendations" are problematic, because they do not contextualize and people think it is worth anything. Then you make use of something approved for something else. Changing a comma may not be approved anymore. The solution you have to give, unless I do everything for you. In the other answer I gave on the subject I talk more about the inadequacy of this type of solution. But each one does what he thinks best, because it is each one who will bear the consequences of his choices.

  • The production itself is a test, that’s basically it. I’m currently reading the other answer, then analyzing the content in it better.

  • if you could edit your answer, leaving only the second paragraph would be much more direct and rewarding.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.