Reprinted please indicate the source: http://blog.csdn.net/guolin_blog/article/details/8868758
This is a copy version of Java Design Pattern dialysis, which is specially provided for Ruby lovers. If you are not familiar with Ruby syntax, please refer:
Java Design Pattern Analysis-singleton)
When writing software, you often need to use the log printing function, which can help you debug and locate problems. After the project is launched, it can also help you analyze data, however, Ruby's native puts method is rarely used in real project development.
Why is puts, a newbie to Ruby, deprecated in real project development? In fact, as long as you analyze it carefully, you will find many drawbacks. For example, if it is not controllable, all logs will be printed as usual after the project is launched, reducing the running efficiency. Or, you cannot record the logs to local files. Once the printing is cleared, logs can no longer be retrieved; or the printed content is not differentiated by tags. It is difficult to identify the class in which the log is printed.
Your leader is not a fool, and he knows the drawbacks of puts. Therefore, his task today is to create a log tool class to provide better log functions. However, your leader is not bad. It didn't enable you to implement a powerful log tool class with various functions at the beginning. You only need a log tool that can control the printing level.
This requirement is not difficult for you. You started to write it immediately and completed the first version soon:
class LoggerDEBUG = 0INFO = 1ERROR = 2NOTHING = 3LEVEL = DEBUGdef debug msgputs msg if DEBUG >= LEVELenddef info msgputs msg if INFO >= LEVELenddef error msgputs msg if ERROR >= LEVELendend
By using this class to print logs, you only need to control the level to freely control the printed content. For example, if the project is in the development stage, set level to debug, so that all log information is printed. If the project is launched, you can set the level to info, so that you can only see the log printing of info and above. If you only want to see the error log, you can set level to error. If the project you are developing is a client version and you do not want to print any logs, you can set level to nothing. When printing, you only need to call:
logger = Logger.newlogger.debug("Hello World")
You can't wait to introduce this tool to your leader. After hearing your introduction, your leader said, "well, you will use this tool to print logs in the future !"
It wasn't long before your leader found you to report the problem. He said that although this tool is easy to use, it does not differentiate objects to print such a thing. Here, every time you need to print logs, you need to create a new logger, which occupies too much memory, we hope you can change this tool to the singleton mode.
You think what your leader says makes sense, and you want to take this opportunity to practice the design pattern, so you wrote the following code:
class Loggerprivate_class_method :newDEBUG = 0INFO = 1ERROR = 2NOTHING = 3LEVEL = DEBUG@@instance = nildef debug msgputs msg if DEBUG >= LEVELenddef info msgputs msg if INFO >= LEVELenddef error msgputs msg if ERROR >= LEVELenddef self.instance@@instance = new unless @@instanceendend
UsePrivate_class_methodNewThe method is private, so it cannot passNewMethod To create a logger instance. Then use a static variable@ InstanceTo save the instance, and provide a public instance method for obtaining the logger instance. In this method, determine if@ InstanceFor nilNewGenerates a new logger instance. Otherwise, the system returns@ Instance. This ensures that only one logger instance exists in the memory. The Singleton mode is complete! The log printing code needs to be changed to the following method:
logger = Logger.instancelogger.debug("Hello World")
You showed this version to your leader. He smiled and said, "Well, it's good. The function is implemented. But there are still simpler implementation methods in Ruby ."
He typed the keyboard skillfully to show you a simpler Singleton implementation method (based on the initial code ).
Require 'singleton' class loggerinclude Singleton # omitting the remaining code end
First introduce the singleton. RB file from the System Configuration path, and then introduce the singleton module in the logger class. OK. Everything is finished!
"What ?!" You simply don't believe in your own eyes. Simply adding two lines of code completes the singleton mode. "But where does the instance method come from ?"
Your leader tells you that Ruby has a module mechanism. After a module is introduced into a class, this class can access the defined methods in the module. The instance method is defined in the singleton module, and then introduced to this module at runtime. Then, the logger class can access the instance method in singleton.
Singleton: ensure that a class has only one instance, and provide a global access point to access it.