If you think the article is good, please follow, like and share!
Continue to share technical blog posts, pay attention to WeChat public account 👉🏻 Front-end LeBron
Concise and elegant solutions to specific problems in object-oriented software design - Design Patterns Design Patterns Principle: "Find where changes in the program are and encapsulate the changes"
Why learn design patterns?
I have been in a development position for more than a year. I have seen old projects and built a project from zero to one. With the continuous expansion of the project and business, if the code written is not designed, it will gradually become an emm... x mountain. No matter how you write it, you will think about refactoring.
The reason why people can go to the top of the food chain is because they can learn, summarize, and use "names" and "tools". The design pattern is not invented out of thin air, it is the best practice of programming in a certain business scenario, summed up after a lot of project practice, the summed up solution, and give it a name, it becomes a design pattern. Just like the tactics on the basketball court, the point guard often calls out the number of tactics to play, rather than directing them one by one. Concise code names are often more elegant than complicated descriptions. It's possible that you often write a program in a way that can be described, but you don't know what it's called, it may be a design pattern. So in the process of learning, we often have this feeling: ooooo! ! I often use this thing, often write it like this, it turns out that this is the xx mode!
Finally, why learn design patterns? Although sometimes design patterns will increase the complexity of the code and increase the cost of development, it greatly reduces the maintenance cost. It is like looking for a needle in a haystack if the books in the library are scattered in various corners in a disorderly manner; however, if they are numbered, categorized and placed in an orderly manner on the designated bookshelf, it will be much easier to find. Imagine a scene, one day, you point to a piece of code and start scolding, who wrote this x mountain! Move the mouse up, the git modification record shows, oh! I wrote it, that's fine. Hurry up to learn design patterns, and elegantly write concise, reusable, and easy-to-maintain programs~
singleton pattern
1. Ensure that a class has only one instance and provide a global access point to it
2. Mainly solve the problem that a globally used class is frequently created and destroyed, occupying memory
Implement the singleton pattern
It is not complicated to implement a concise singleton pattern. It is nothing more than saving the instance object, and the next time you get/create an object, return the previously created instance directly.
Simplest case pattern
- Closure implementation
- ES6 implementation
// 利用闭包实现
var Singleton = (function () {
var instance;
function Instance() {}
return function () {
if (!instance) {
instance = new Instance();
}
return instance;
};
})();
var single1 = Singleton();
var single2 = Singleton();
console.log(single1 === single2); // true
// ES6实现
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
}
const single1 = new Singleton();
const single2 = new Singleton();
console.log(single1 === single2); // true
lazy singleton
Lazy singleton: No instance creation is performed during initialization, and instance creation is performed when an instance is obtained, similar to the front-end resource lazy loading idea
// 非惰性单例
class Tool{}
class SingleTon{
constructor (name,...args) {
this.name = name
if(!SingleTon.instance){
SingleTon.instance = new Tool(args)
}
}
getName(){
return this.name;
}
static getInstance(){
return this.instance;
}
}
// 惰性单例
class Tool{}
class SingleTon{
constructor (name) {
this.name = name
}
getName(){
return this.name;
}
static getInstance(){
if(!this.instance){
this.instance = new Tool(arguments)
}
return this.instance;
}
}
Transparent singletons and proxy singletons
transparent singleton
- Encapsulates instance creation and method execution into a class
- Not in line with the "single responsibility principle", the code is not easy to read and change
proxy singleton
- Proxy mode: separate instance creation and method, delegate out
- Person as a normal class can create object instances
- createPerson creates a proxy as a singleton, you can create a singleton
- In line with the "single responsibility principle", the code is easy to read and change
// 透明 单例
class createPerson{
constructor (name) {
if(createPerson.instance){
return createPerson.instance;
}
this.name = name;
this.init();
return createPerson.instance = this;
}
init(){
console.log('My name is ',this.name)
}
}
const p1 = new createPerson('lebron')
const p2 = new createPerson('james')
p1.init(); // My name is lebron
p2.init(); // My name is lebron
// 代理单例
class Person{
constructor (name) {
this.name = name;
}
init(){
console.log('My name is ',this.name)
}
}
class createPerson{
constructor (name) {
if(!createPerson.instance){
createPerson.instance = new Person(name)
}
return createPerson.instance;
}
}
const p1 = new createPerson('lebron')
const p2 = new createPerson('james')
p1.init(); // My name is lebron
p2.init(); // My name is lebron
final version
Every time the singleton pattern of a class is implemented, the template code that is repeated by CV is not in line with expectations.
Therefore, we can "find out where the program changes and encapsulate the changes" according to the principles of design patterns
Can be modified as follows
class SingleTon{
constructor (fn) {
let singleInstance;
function singleConstructor(...args){
// 第一次实例化
if(!singleInstance){
singleInstance = new fn(...args);
}
// 多次实例化直接返回
return singleInstance;
}
singleConstructor.prototype = Object.create(fn.prototype);
return singleConstructor;
}
}
class Person{
constructor (name) {
this.name = name;
}
init(){
console.log('My name is ',this.name)
}
}
const createPerson = new SingleTon(Person);
const p1 = new createPerson('lebron');
const p2 = new createPerson('james');
p1.init(); // My name is lebron
p2.init(); // My name is lebron
console.log(p1 === p2) // true
class Tool{
constructor (number) {
this.number = number;
}
init(){
console.log('This is tool ', this.number)
}
}
const createTool = new SingleTon(Tool);
const t1 = new createTool(1);
const t2 = new createTool(2);
t1.init(); // This is tool 1
t2.init(); // This is tool 1
console.log(t1 === t2); // true
Application scenarios of the singleton pattern
login window
The login window is very common in our software, and it is also very suitable to be created using the singleton pattern (globally unique, frequently used)
Using the singleton pattern to create can avoid multiple node creation and destruction
class Login {
constructor() {
this.element = document.createElement('div');
this.element.innerHTML = `
用户名 <input name="username"/>
密码 <input name="password"/>
<input type="submit" value="登录"/>
`;
this.element.style.cssText = `width:100px;height:100px;position:absolute;left:50%;top:50%;margin-top:-50px;margin-left:-50px;display:none`;
document.body.appendChild(this.element);
}
show() {
this.element.style.display = 'block';
console.log('show');
}
hide() {
this.element.style.display = 'none';
console.log('hide');
}
}
// 采用上文最终版本创建单例代码
const createLogin = new SingleTon(Login);
const loginInstance = createLogin();
document.getElementById('show-btn').addEventListener('click', function () {
loginInstance.show();
});
document.getElementById('hide-btn').addEventListener('click', function () {
loginInstance.hide();
});
Store
Global state management, globally unique instance like Vuex/Redux/Mobx
// 已省略一些无关代码
if (!Vue && typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
function install (_Vue) {
if (Vue && _Vue === Vue) {
console.error('[vuex] already installed. Vue.use(Vuex) should be called only once.')
return
}
Vue = _Vue
}
Jquery
Jquery is also the singleton mode of the application, although it has gradually faded out of our sight 😂
if(window.jQuery!=null){
return window.jQuery;
}else{
//init~~~~~~~
}
Summarize
scenes to be used
- Guarantees only one instance of a class and provides a global access point to it
advantage
- There is only one instance in memory, which reduces memory overhead, especially when instances are created and destroyed frequently
- Avoid multiple occupation of resources
chat
In the first half of the year, I have been busy with graduation, and then I took a break for a while. I have not written technical articles for more than half a year.
Recently, I officially joined the company and began to gradually adjust to a better learning and working state. Make some study plans and resume updating the article (I haven't written it for a long time or I'm not used to it haha
The first article of the first series "Design Patterns" took a long time to ink, but it was finally produced. The follow-up will continue to update, the update frequency and progress will depend on the free time haha, welcome to pay attention~
A front-end engineer who is still working hard, keep going!
Continue to share technical blog posts, welcome to pay attention!
- Nuggets: Front-end LeBron
- Knowing: Front-end LeBron
Continue to share technical blog posts, pay attention to WeChat public account👇🏻
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。