<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="https://publishpress.com/"
	>

<channel>
	<title>Design Patterns Archives - Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/tag/design-patterns/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/tag/design-patterns/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Tue, 05 Mar 2024 06:19:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.tomosia.com.vn/wp-content/uploads/2023/09/cropped-icon-32x32.png</url>
	<title>Design Patterns Archives - Tomoshare</title>
	<link>https://blog.tomosia.com.vn/tag/design-patterns/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Dependency Injection (DI) framework &#8211; Google Guice</title>
		<link>https://blog.tomosia.com.vn/dependency-injection-di-framework-google-guice/</link>
					<comments>https://blog.tomosia.com.vn/dependency-injection-di-framework-google-guice/#comments</comments>
		
		<dc:creator><![CDATA[admin_tomosia]]></dc:creator>
		<pubDate>Tue, 05 Mar 2024 06:19:13 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Guice]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=3189</guid>

					<description><![CDATA[<p>Trong bài trước, chúng ta đã được đi tìm hiểu Dependency Injection là gì. Tiếp tục chuỗi thông&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/dependency-injection-di-framework-google-guice/">Dependency Injection (DI) framework &#8211; Google Guice</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="font-size:16px">Trong bài trước, chúng ta đã được đi tìm hiểu <strong><a href="http://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/">Dependency Injection</a></strong> là gì. Tiếp tục chuỗi thông não, chúng ta cùng nhau làm tý &#8220;inova&#8221; với cái thằng Google Guice này nhé.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="332" height="456" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/03/1_OXaU46Rv8B3MV7YuaAanaA.png" alt="" class="wp-image-3190" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/03/1_OXaU46Rv8B3MV7YuaAanaA.png 332w, https://blog.tomosia.com.vn/wp-content/uploads/2024/03/1_OXaU46Rv8B3MV7YuaAanaA-218x300.png 218w" sizes="(max-width: 332px) 100vw, 332px" /></figure>
</div>


<h2 id="1-google-guice-la-gi" class="wp-block-heading" style="font-size:30px"><strong>1. Google Guice là gì?</strong></h2>



<p style="font-size:16px"><strong>Google Guice</strong> là một framework DI gọn nhẹ, mã nguồn mở giúp chúng ta phát triển các ứng dụng dạng module được phát triển và quản lý bởi Google. Guice hỗ trợ từ Java 6 trở lên nhé anh em.</p>



<p style="font-size:16px">Trong Guice, annotation&nbsp;<strong>@Inject</strong>&nbsp;được sử dụng để tiêm phụ thuộc. Nó cho phép chúng ta inject sự phụ thuộc tại các constructor, field hoặc method. Sử dụng Guice, chúng ta có thể xác định scope của instance đối tượng phụ thuộc. Nó cũng có các tính năng để tích hợp với Spring và&nbsp;<a href="https://github.com/google/guice/wiki/AOP">Aspect Oriented Programming (AOP)</a>.</p>



<h2 id="2-cai-dat-google-guice" class="wp-block-heading" style="font-size:30px"><strong>2. Cài đặt&nbsp;Google Guice</strong></h2>



<p style="font-size:16px">Để sử dụng<strong> Google Guice</strong>, anh em thêm thư viện Guice vào trong file <em>pom.xml</em> như sau:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="&lt;!-- https://mvnrepository.com/artifact/com.google.inject/guice --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.google.inject&lt;/groupId&gt;
    &lt;artifactId&gt;guice&lt;/artifactId&gt;
    &lt;version&gt;4.2.2&lt;/version&gt;
&lt;/dependency&gt;" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">&lt;!--</span><span style="color: #F6F6F4"> https</span><span style="color: #F286C4">:</span><span style="color: #7B7F8B">//mvnrepository.com/artifact/com.google.inject/guice --&gt;</span></span>
<span class="line"><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4">dependency</span><span style="color: #F286C4">&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4">groupId</span><span style="color: #F286C4">&gt;</span><span style="color: #F6F6F4">com.google.inject</span><span style="color: #F286C4">&lt;/</span><span style="color: #F6F6F4">groupId</span><span style="color: #F286C4">&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4">artifactId</span><span style="color: #F286C4">&gt;</span><span style="color: #F6F6F4">guice</span><span style="color: #F286C4">&lt;/</span><span style="color: #F6F6F4">artifactId</span><span style="color: #F286C4">&gt;</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">&lt;</span><span style="color: #F6F6F4">version</span><span style="color: #F286C4">&gt;</span><span style="color: #BF9EEE">4.2</span><span style="color: #F6F6F4">.</span><span style="color: #EE6666; font-style: italic; text-decoration: underline">2</span><span style="color: #F286C4">&lt;/</span><span style="color: #F6F6F4">version</span><span style="color: #F286C4">&gt;</span></span>
<span class="line"><span style="color: #F286C4">&lt;/</span><span style="color: #F6F6F4">dependency</span><span style="color: #F286C4">&gt;</span></span></code></pre></div>



<p style="font-size:16px">Hoặc muốn sử dụng các version khác thì anh em có thể truy cập vào 👉 <a href="https://mvnrepository.com/artifact/com.google.inject/guice">đây</a> 👈. Cứ version nào nhiều người sử dụng mà &#8220;phang&#8221; thôi =))). </p>



<h2 id="3-vi-du-co-ban-ve-dependency-injection-voi-google-guice" class="wp-block-heading" style="font-size:30px"><strong>3. Ví dụ cơ bản về Dependency Injection với Google Guice</strong></h2>



<p style="font-size:16px">Để sử dụng Guice cần nhớ 2 thông tin quan trọng sau:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Nói với Guice cái gì cần được inject với annotation&nbsp;<strong>@Inject</strong>.</li>



<li style="font-size:16px">Nói với Guice cách inject mô-đun:&nbsp;implement&nbsp;<strong>Asbstract Module</strong>, bind các interface với các implementation mong muốn.</li>
</ul>



<p style="font-size:16px">Quay trở lại với ví dụ em gái Eimi Fukada trong bài <a href="http://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/">trước</a> lần này tôi sẽ sử dụng Guice nha:</p>



<p style="font-size:16px">GuiceModule.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.blogtms;

import com.google.inject.AbstractModule;

public class GuiceModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Outfit.class).to(Bikini.class);
        bind(Accessories.class).to(GucciAccessories.class);
        bind(HairStyle.class).to(KoreanHairStyle.class);
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.blogtms</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> com.google.inject.AbstractModule;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">GuiceModule</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">extends</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">AbstractModule</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Override</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">protected</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">configure</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">bind</span><span style="color: #F6F6F4">(Outfit.class).</span><span style="color: #62E884">to</span><span style="color: #F6F6F4">(Bikini.class);</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">bind</span><span style="color: #F6F6F4">(Accessories.class).</span><span style="color: #62E884">to</span><span style="color: #F6F6F4">(GucciAccessories.class);</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #62E884">bind</span><span style="color: #F6F6F4">(HairStyle.class).</span><span style="color: #62E884">to</span><span style="color: #F6F6F4">(KoreanHairStyle.class);</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Girl.java thêm @Inject</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.blogtms;

import com.google.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//@Component
public class Girl {

    @Autowired
    Outfit outfit;

    @Autowired
    Accessories accessories;

    @Autowired
    HairStyle hairStyle;

    @Inject
    public Girl(Outfit outfit, Accessories accessories, HairStyle hairStyle) {
        this.outfit = outfit;
        this.accessories = accessories;
        this.hairStyle = hairStyle;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.blogtms</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> com.google.inject.Inject;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.beans.factory.annotation.Autowired;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.stereotype.Component;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B">//@Component</span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Girl</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Autowired</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4"> outfit;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Autowired</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">Accessories</span><span style="color: #F6F6F4"> accessories;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Autowired</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">HairStyle</span><span style="color: #F6F6F4"> hairStyle;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Inject</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Girl</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4"> </span><span style="color: #FFB86C; font-style: italic">outfit</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">Accessories</span><span style="color: #F6F6F4"> </span><span style="color: #FFB86C; font-style: italic">accessories</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">HairStyle</span><span style="color: #F6F6F4"> </span><span style="color: #FFB86C; font-style: italic">hairStyle</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #BF9EEE; font-style: italic">this</span><span style="color: #F6F6F4">.outfit </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> outfit;</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #BF9EEE; font-style: italic">this</span><span style="color: #F6F6F4">.accessories </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> accessories;</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #BF9EEE; font-style: italic">this</span><span style="color: #F6F6F4">.hairStyle </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> hairStyle;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Main.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.blogtms;

import com.google.inject.Guice;
import com.google.inject.Injector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

//@SpringBootApplication
public class Main {
    public static void main(String[] args) {
//        ApplicationContext context = SpringApplication.run(Main.class, args);
//
//        Girl girl = context.getBean(Girl.class);

        Injector injector = Guice.createInjector(new GuiceModule());

        Girl girl = injector.getInstance(Girl.class);
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.blogtms</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> com.google.inject.Guice;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> com.google.inject.Injector;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.boot.SpringApplication;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.boot.autoconfigure.SpringBootApplication;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.context.ApplicationContext;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #7B7F8B">//@SpringBootApplication</span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Main</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #7B7F8B">//        ApplicationContext context = SpringApplication.run(Main.class, args);</span></span>
<span class="line"><span style="color: #7B7F8B">//</span></span>
<span class="line"><span style="color: #7B7F8B">//        Girl girl = context.getBean(Girl.class);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">Injector</span><span style="color: #F6F6F4"> injector </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> Guice.</span><span style="color: #62E884">createInjector</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">GuiceModule</span><span style="color: #F6F6F4">());</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">Girl</span><span style="color: #F6F6F4"> girl </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> injector.</span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">(Girl.class);</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Thế là xong rồi =))) </p>



<p style="font-size:16px">Trong ví dụ trên, chúng ta thấy một số phần thay đổi so với ví dụ ở bài trước:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Tạo một class extends từ&nbsp;<strong>AbstractModule</strong>, lớp này được sử dụng để định nghĩa cách mà một class/ interface sẽ được inject bởi một implement cụ thể nào. Trong ví dụ này, <em>Outfit</em> sẽ được inject bởi implement&nbsp;<em>Bikini</em>.</li>



<li style="font-size:16px">Lớp <em>Girl</em> có dependency với&nbsp;<em>Outfit</em>. Trong ví dụ này, chúng ta sử dụng&nbsp;@Inject tại hàm xây dựng (constructor) để inject đối tượng&nbsp;<em>Outfit</em>.</li>



<li style="font-size:16px">Khởi tạo Guice Injector với config.</li>



<li style="font-size:16px">Lấy thể hiện đối tượng với các dependency để sử dụng.</li>
</ul>



<h2 id="4-scope-trong-google-guice" class="wp-block-heading" style="font-size:30px"><strong>4. Scope trong&nbsp;Google Guice</strong></h2>



<p style="font-size:16px">Theo mặc định, Guice trả về một instance mới mỗi lần nó cần cung cấp một giá trị. Hành vi này có thể cấu hình thông qua phạm vi (<a href="https://github.com/google/guice/wiki/Scopes">scope</a>). Scope cho phép chúng ta tái sử dụng instance.</p>



<p style="font-size:16px">Các loại Scope được hỗ trợ bởi&nbsp;Google Guice:</p>



<ul class="wp-block-list">
<li style="font-size:16px"><strong>@Singleton</strong>&nbsp;: một instance duy nhất được sử dụng trong toàn bộ ứng dụng.</li>



<li style="font-size:16px"><strong>@SessionScoped</strong>&nbsp;: mỗi session sẽ có một instance khác nhau.</li>



<li style="font-size:16px"><strong>@RequestScoped</strong>&nbsp;: mỗi request sẽ có một instance khác nhau.</li>
</ul>



<p style="font-size:16px">Trên đây là giới thiệu cơ bản về Google Guice.&nbsp;Nó cung cấp một cách tiếp cận mới cho&nbsp;<a href="http://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/"><strong>Dependency Injection</strong></a>, tận dụng thế mạnh của&nbsp;<strong>Annotation</strong>&nbsp;và&nbsp;<strong>Generic</strong>&nbsp;để giúp chúng ta dễ dàng hơn trong việc quản lý và sử dụng các Dependency, cũng như dễ dàng phát triển các ứng dụng dạng module.</p>



<p style="font-size:16px"><strong>Tài liệu tham khảo:</strong></p>



<ul class="wp-block-list">
<li style="font-size:16px"><a href="https://github.com/google/guice">https://github.com/google/guice</a></li>



<li style="font-size:16px"><a href="https://www.tutorialspoint.com/guice/index.htm">https://www.tutorialspoint.com/guice/index.htm</a></li>
</ul>



<p style="font-size:16px">Cảm ơn anh em đã theo dõi bài viết 🙋‍♂️. Vẫn như mọi khi, <a href="https://github.com/chienhnc/di">đây là source code</a></p>
<p>The post <a href="https://blog.tomosia.com.vn/dependency-injection-di-framework-google-guice/">Dependency Injection (DI) framework &#8211; Google Guice</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/dependency-injection-di-framework-google-guice/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Thông não Dependency Injection bằng Eimi Fukada</title>
		<link>https://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/</link>
					<comments>https://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/#comments</comments>
		
		<dc:creator><![CDATA[admin_tomosia]]></dc:creator>
		<pubDate>Fri, 01 Mar 2024 02:39:09 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=3173</guid>

					<description><![CDATA[<p>Hello what&#8217;s up, dạo này anh em còn bị chửi code như shit nữa không nhờ. Tôi thì&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/">Thông não Dependency Injection bằng Eimi Fukada</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="font-size:16px">Hello what&#8217;s up, dạo này anh em còn bị chửi code như shit nữa không nhờ. Tôi thì vẫn thế =)))), vẫn như shit nhưng hôm nay tôi muốn giới thiệu đến anh em một kỹ thuật mới là <strong>Dependency Injection</strong> để code của anh em đỡ bốc mùi hơn một chút nhé, vào việc.</p>



<h2 id="1-dependency-injection-la-gi" class="wp-block-heading" style="font-size:30px"><strong>1. Dependency Injection là gì?</strong></h2>



<p>Theo tài liệu thì:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p style="font-size:16px">Dependency Injection is a design pattern, &#8230;</p>
</blockquote>



<p style="font-size:16px">Nôm na Dependency Injection (DI) là một kỹ thuật cho phép xóa bỏ sự phụ thuộc giữa các module, làm cho ứng dụng dễ dàng hơn trong việc thay đổi module, bảo trì code và&nbsp;testing.</p>



<p style="font-size:16px"><strong>DI</strong>&nbsp;cung cấp cho một đối tượng các thể hiện phụ thuộc (dependencies) của nó&nbsp;từ bên ngoài truyền vào mà không phải khởi tạo trực tiếp từ trong class sử dụng.</p>



<h2 id="2-nhiem-vu-cua-dependency-injection" class="wp-block-heading" style="font-size:30px"><strong>2. Nhiệm vụ của dependency injection</strong></h2>



<ul class="wp-block-list">
<li style="font-size:16px">Tạo các đối tượng.</li>



<li style="font-size:16px">Quản lý sự phụ thuộc (dependencies) giữa các đối tượng.</li>



<li style="font-size:16px">Cung cấp (inject) các phụ thuộc được yêu cầu cho đối tượng (được truyền từ bên ngoài đối tượng).</li>
</ul>



<h2 id="3-nguyen-tac-hoat-dong-cua-di" class="wp-block-heading" style="font-size:30px"><strong>3. Nguyên tắc hoạt động của&nbsp;DI</strong></h2>



<ul class="wp-block-list">
<li style="font-size:16px">Các module không giao tiếp trực tiếp với nhau, mà thông qua interface. Module cấp thấp sẽ implement interface, module cấp cao sẽ gọi module cấp thấp thông qua interface.</li>



<li style="font-size:16px">Việc khởi tạo các module cấp thấp sẽ do DI Container/ IoC Container thực hiện.</li>



<li style="font-size:16px">Việc Module nào gắn với interface nào sẽ được config trong file properties, trong file XML hoặc thông qua Annotation. Annotation là một cách thường được sử dụng trong các Framework, chẳng hạn như @Inject với&nbsp;<a href="http://www.cdi-spec.org/">CDI</a>, @Autowired với&nbsp;<a href="https://spring.io/">Spring</a>&nbsp;hay @ManagedProperty với&nbsp;<a href="https://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html">JSF</a>.</li>
</ul>



<h2 id="4-cac-dang-dependency-injection" class="wp-block-heading" style="font-size:30px"><strong>4. Các dạng Dependency Injection</strong></h2>



<ul class="wp-block-list">
<li style="font-size:16px"><strong>Constructor Injection</strong>: Các dependency sẽ được container&nbsp;truyền vào (inject vào)&nbsp;1 class thông qua constructor của class đó. Đây là cách thông dụng nhất.</li>



<li style="font-size:16px"><strong>Setter Injection</strong>: Các dependency sẽ được truyền vào 1 class thông qua các hàm Setter.</li>



<li style="font-size:16px"><strong>Fields/ properties</strong>: Các dependency sẽ được truyền vào 1 class một cách trực tiếp vào các field.</li>



<li style="font-size:16px"><strong>Interface Injection</strong>: Class cần inject sẽ implement 1 interface. Interface này chứa 1 hàm tên&nbsp;Inject. Container sẽ injection dependency vào 1 class thông qua việc gọi hàm&nbsp;Inject&nbsp;của interface đó. Đây là cách rườm rà và cũng ít được sử dụng.</li>



<li style="font-size:16px"><strong>Service Locator</strong>: nó hoạt động như một mapper, cho phép thay đổi code tại thời điểm run-time mà không cần biên dịch lại ứng dụng hoặc phải khởi động lại.</li>
</ul>



<p style="font-size:16px">Anh em đọc đến đây đã hiểu <strong>Dependency Injection</strong> là gì chưa? Anh em nào đã thông não thì có thể bỏ qua, anh em nào vẫn lơ tơ mơ thì tiếp tục, full hd không che phía dưới =)))).</p>



<h2 id="5-vi-du-su-dung-dependency-injection" class="wp-block-heading" style="font-size:30px"><strong>5. Ví dụ sử dụng Dependency Injection.</strong></h2>



<p style="font-size:16px">Bikini.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public class Bikini {
    public void wear() {
        System.out.println(&quot;Đã mặc bikini&quot;);
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Bikini</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">wear</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Đã mặc bikini</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">);</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Girl.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public class Girl {

    private Bikini outfit = new Bikini();
    
    public void result() {
        outfit.wear();
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Girl</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Bikini</span><span style="color: #F6F6F4"> outfit </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Bikini</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">    </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">result</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        outfit.</span><span style="color: #62E884">wear</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Ví dụ anh em tạo 1 <strong>Girl</strong>, anh em sẽ tạo ra thêm 1 bộ&nbsp;<strong>Bikini</strong>&nbsp;đi kèm với cô gái đó. Lúc này,&nbsp;<code>Bikini</code>&nbsp;tồn tại mang ý nghĩa là&nbsp;<strong>dependency</strong>&nbsp;(phụ thuộc) của&nbsp;<strong>Girl</strong>.</p>



<p style="font-size:16px">Khi khởi tạo thuộc tính như này, vô tình tạo ra một điểm thắt nút trong chương trình, giả sử,&nbsp;<strong>Girl</strong>&nbsp;muốn mặc một bộ&nbsp;<em>Quần Jeans + áo hai dây</em> thì anh em sẽ phải thay class&nbsp;<strong>Bikini</strong>&nbsp;thành&nbsp;<strong>JeansWithTshirt</strong>(quần jeans với áo T-shirt) ư?</p>



<p style="font-size:16px">Hay nguy hiểm hơn, bộ đồ&nbsp;<strong>Bikini</strong>&nbsp;bị hỏng? (code lớp&nbsp;<strong>Bikini</strong>&nbsp;không hoạt động?) nó sẽ ảnh hưởng trực tiếp tới&nbsp;<strong>Girl</strong>.</p>



<p style="font-size:16px">Vấn đề là ở đó, chúng ta cùng đọc lại nguyên tắc D của <strong><a href="http://blog.tomosia.com.vn/solid-principles/">SOLID</a></strong>:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Các mô-đun cấp cao không được nhập bất cứ thứ gì từ các mô-đun cấp thấp. Cả hai nên phụ thuộc vào sự trừu tượng</li>
</ul>



<p style="font-size:16px">Bây giờ chúng ta sẽ áp dụng <strong>Dependency Injection</strong> để giải quyết vấn đề trên.</p>



<p style="font-size:16px">Girl.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public class Girl {

    private final Outfit anything;

    public Girl(Outfit anything) {
        this.anything = anything;
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Girl</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4"> anything;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Girl</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4"> </span><span style="color: #FFB86C; font-style: italic">anything</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #BF9EEE; font-style: italic">this</span><span style="color: #F6F6F4">.anything </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> anything;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Bikini.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public class Bikini implements Outfit{
   @Override
    public void wear() {
        System.out.println(&quot;Đã mặc bikini&quot;);
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Bikini</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">implements</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4">{</span></span>
<span class="line"><span style="color: #F6F6F4">   @</span><span style="color: #97E1F1; font-style: italic">Override</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">wear</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Đã mặc bikini</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">);</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Outfit.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public interface Outfit {
    public void wear();
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">interface</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Outfit</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">wear</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Main.java</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public class Main {
    public static void main(String[] args) {
        Outfit bikini = new Bikini();

        Girl fukada = new Girl(bikini);
        //Vậy là đã lấy được đối tượng Girl nha
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Main</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4"> bikini </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Bikini</span><span style="color: #F6F6F4">();</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">Girl</span><span style="color: #F6F6F4"> fukada </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Girl</span><span style="color: #F6F6F4">(bikini);</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">//Vậy là đã lấy được đối tượng Girl nha</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Với đoạn code ở trên, chúng ta đã&nbsp;<em>gần như</em>&nbsp;tách được&nbsp;<strong>Bikini</strong>&nbsp;ra hoàn toàn khỏi&nbsp;<strong>Girl</strong>. điều này làm giảm sự phụ thuộc giữa&nbsp;<strong>Girl</strong>&nbsp;và&nbsp;<strong>Bikini</strong>. Mà tăng tính tùy biến, linh hoạt cho&nbsp;<code>code</code>.</p>



<p style="font-size:16px">Bây giờ&nbsp;<strong>Girl</strong>&nbsp;sẽ hoạt động với&nbsp;<strong>Outfit</strong>&nbsp;mà thôi. Và&nbsp;<strong>Outfit</strong>&nbsp;ở đâu ra? Chúng ta&nbsp;<strong>tạo ra</strong>&nbsp;và&nbsp;<strong>đưa nó vào</strong>&nbsp;<code>(Inject)</code>&nbsp;cô gái&nbsp;<strong>Girl</strong>.</p>



<p style="font-size:16px">Khái niệm&nbsp;<code>Dependency Injection</code>&nbsp;từ đây mà ra: <br><em><mark style="background-color:#e9ecef" class="has-inline-color has-black-color"><strong>Dependency Injection là việc các&nbsp;Object&nbsp;nên phụ thuộc vào các&nbsp;Abstract Class&nbsp;và thể hiện chi tiết của nó sẽ được&nbsp;Inject&nbsp;vào đối tượng lúc runtime.</strong></mark></em></p>



<p style="font-size:16px">Bây giờ muốn&nbsp;<strong>Girl</strong>&nbsp;mặc gì khác, anh em chỉ cần tạo một Class kế thừa&nbsp;<strong>Outfit</strong>&nbsp;và&nbsp;<em>Inject</em>&nbsp;nó vào&nbsp;<strong>Girl</strong>&nbsp;là xong!</p>



<p style="font-size:16px"><strong>Dependency Injection</strong>&nbsp;giúp chúng ta dễ dàng mở rộng&nbsp;<code>code</code>&nbsp;và giảm sự phụ thuộc giữa các dependency với nhau. Tuy nhiên, lúc này, khi code bạn sẽ phải kiêm thêm nhiệm vụ&nbsp;<strong>Inject dependency (tiêm sự phụ thuộc)</strong>. Thử tưởng tượng một&nbsp;<code>Class</code>&nbsp;có hàng chục dependency thì bạn sẽ phải tự tay inject từng ý cái. Việc này lại dẫn tới khó khăn trong việc code, quản lý code và dependency</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

public class Main {
    public static void main(String[] args) {
       Outfit bikini = new Bikini();
       Accessories gucci = new GucciAccessories();
       HairStyle hair = new KoreanHairStyle();
       Girl fukada = new Girl(bikini, gucci, hair);
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Main</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">       </span><span style="color: #97E1F1; font-style: italic">Outfit</span><span style="color: #F6F6F4"> bikini </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Bikini</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">       </span><span style="color: #97E1F1; font-style: italic">Accessories</span><span style="color: #F6F6F4"> gucci </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">GucciAccessories</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">       </span><span style="color: #97E1F1; font-style: italic">HairStyle</span><span style="color: #F6F6F4"> hair </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">KoreanHairStyle</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">       </span><span style="color: #97E1F1; font-style: italic">Girl</span><span style="color: #F6F6F4"> fukada </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Girl</span><span style="color: #F6F6F4">(bikini, gucci, hair);</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Vãi chưởng nhỉ, lúc này có thằng nào làm hộ được chúng ta việc này thì tốt biết mấy =))).</p>



<p style="font-size:16px">Bây giờ giả sử, chúng ta định nghĩa trước toàn bộ các&nbsp;<em>dependency</em>&nbsp;có trong Project, mô tả nó và tống nó vào 1 cái&nbsp;<code>kho</code>&nbsp;và giao cho một thằng tên là&nbsp;<code>framework</code>&nbsp;quản lý. Bất kỳ các&nbsp;<code>Class</code>&nbsp;nào khi khởi tạo, nó cần dependency gì, thì cái&nbsp;<code>framework</code>&nbsp;này sẽ tự tìm trong&nbsp;<code>kho</code>&nbsp;rồi&nbsp;<em>inject</em>&nbsp;vào đối tượng thay chúng ta. sẽ tiện hơn phải không?</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1020" height="1024" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-1020x1024.png" alt="" class="wp-image-3185" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-1020x1024.png 1020w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-300x300.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-150x150.png 150w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-768x771.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-1530x1536.png 1530w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-80x80.png 80w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-380x381.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-800x803.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02-1160x1164.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Screenshot-2024-02-27-at-11.27.02.png 1590w" sizes="(max-width: 1020px) 100vw, 1020px" /></figure>



<p style="font-size:16px">Úi dời ơi, tuyệt chứ nhỉ, đó cũng chính là nguyên lý chính của&nbsp;<strong>Inversion of Control (IOC)&nbsp;&#8211;&nbsp;Đảo chiều sự điều khiển</strong></p>



<p style="font-size:16px">Nguyên văn Wiki:</p>



<ul class="wp-block-list">
<li style="font-size:16px"><span style="color: rgb(55, 53, 47); font-family: Inter, Inter-fallback, Helvetica, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, NotoColorEmoji, &quot;Noto Color Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Android Emoji&quot;, EmojiSymbols, -apple-system, &quot;system-ui&quot;, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, &quot;Noto Sans&quot;, sans-serif; font-size: 19.2px; letter-spacing: -0.1px; background-color: rgb(251, 251, 253);">Inversion of Control is a programming principle. flow of control within the application is not controlled by the application itself, but rather by the underlying framework.</span></li>
</ul>



<p style="font-size:16px">Khi đó, code chúng ta sẽ chỉ cần như này, để lấy ra đối tượng <strong>Girl</strong>, còn trong <strong>Girl.java</strong> anh em tiêm chích <strong>Accessories</strong> và <strong>HairStyle</strong> như <strong>Outfit</strong> nha:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.di;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Main.class, args);

        Girl girl = context.getBean(Girl.class);
        // Anh em muốn lấy gì từ Girl thì cứ chấm mút ra nha =))
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.di</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.boot.SpringApplication;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.boot.autoconfigure.SpringBootApplication;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.springframework.context.ApplicationContext;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">@</span><span style="color: #97E1F1; font-style: italic">SpringBootApplication</span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Main</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">ApplicationContext</span><span style="color: #F6F6F4"> context </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> SpringApplication.</span><span style="color: #62E884">run</span><span style="color: #F6F6F4">(Main.class, args);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">Girl</span><span style="color: #F6F6F4"> girl </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> context.</span><span style="color: #62E884">getBean</span><span style="color: #F6F6F4">(Girl.class);</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">// Anh em muốn lấy gì từ Girl thì cứ chấm mút ra nha =))</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px"><strong>Lời kết:</strong></p>



<p style="font-size:16px"><strong>Dependency Injection</strong> và <strong>IoC container </strong>là những khái niệm rất quan trọng, hầu hết các ứng dụng, framework hiện tại đều sử dụng nó. Chúng ta cần tìm hiểu để biết rõ DI và IoC được ứng dụng trong trường hợp nào. Nếu áp dụng hợp lý code của chúng ta sẽ ít kết dính hơn (loose coupling), dễ bảo trì, dễ test hơn, tổ chức ứng dụng hợp lý và gọn gàng hơn.</p>



<p>Source Code tham khảo tại <a href="https://github.com/chienhnc/di">đây</a>: </p>
<p>The post <a href="https://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/">Thông não Dependency Injection bằng Eimi Fukada</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/thong-nao-dependency-injection-bang-eimi-fukada/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Hướng dẫn Java Design Pattern – Factory Method</title>
		<link>https://blog.tomosia.com.vn/huong-dan-java-design-pattern-factory-method/</link>
					<comments>https://blog.tomosia.com.vn/huong-dan-java-design-pattern-factory-method/#comments</comments>
		
		<dc:creator><![CDATA[admin_tomosia]]></dc:creator>
		<pubDate>Fri, 01 Mar 2024 02:38:28 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Factory Method]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=3166</guid>

					<description><![CDATA[<p>Trong bài trước chúng ta đã tìm hiểu về&#160;Singleton Design Pattern.&#160;Để tiếp tục series về Design Pattern hôm&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/huong-dan-java-design-pattern-factory-method/">Hướng dẫn Java Design Pattern – Factory Method</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="font-size:16px">Trong bài trước chúng ta đã tìm hiểu về&nbsp;<a href="http://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/">Singleton Design Pattern</a>.&nbsp;Để tiếp tục series về <strong>Design Pattern</strong> hôm nay chúng ta sẽ tiếp tục tìm hiểu một Pattern khác trong nhóm&nbsp;<strong>Creational Design Pattern</strong>&nbsp;là&nbsp;<strong>Factory Method Design Pattern</strong>.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="719" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-1024x719.png" alt="" class="wp-image-3169" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-1024x719.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-300x211.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-768x539.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-200x140.png 200w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-380x267.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-800x562.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q-1160x814.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/1_OrtMdN8PgLN7SwrEnhjA_Q.png 1400w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="1-factory-method-pattern-la-gi" class="wp-block-heading" style="font-size:30px"><strong>1. Factory Method Pattern là gì?</strong></h2>



<p style="font-size:16px"><strong>Factory Method Design Pattern&nbsp;</strong>hay gọi ngắn gọn là&nbsp;<strong>Factory Pattern</strong>&nbsp;là một trong những Pattern thuộc nhóm&nbsp;<strong>Creational Design Pattern</strong>. Nhiệm vụ của Factory Pattern là quản lý và trả về các đối tượng theo yêu cầu, giúp cho việc khởi tạo đổi tượng một cách linh hoạt hơn.</p>



<p style="font-size:16px">Trong Factory Pattern, chúng ta tạo đối tượng mà không để lộ logic tạo đối tượng ở phía người dùng và tham chiếu đến đối tượng mới được tạo ra bằng cách sử dụng một interface chung.</p>



<p style="font-size:16px">Factory Pattern được sử dụng khi có một class cha (super-class) với nhiều class con (sub-class), dựa trên đầu vào và phải trả về 1 trong những class con đó.</p>



<h2 id="2-cai-dat-factory-pattern-nhu-the-nao" class="wp-block-heading" style="font-size:30px"><strong>2. Cài đặt Factory Pattern như thế nào?</strong></h2>



<p style="font-size:16px">Một Factory Pattern bao gồm các thành phần cơ bản sau:</p>



<ul class="wp-block-list">
<li style="font-size:16px"><strong>Super Class</strong>: môt supper class trong Factory Pattern có thể là một&nbsp;<strong>interface</strong>,&nbsp;<strong>abstract class</strong>&nbsp;hay một&nbsp;<strong>class</strong>&nbsp;thông thường.</li>



<li style="font-size:16px"><strong>Sub Classes</strong>: các sub class sẽ implement các phương thức của&nbsp;<strong>supper class</strong>&nbsp;theo nghiệp vụ riêng của nó.</li>



<li style="font-size:16px"><strong>Factory Class</strong>: một class chịu tránh nhiệm khởi tạo các đối tượng&nbsp;<strong>sub class</strong>&nbsp;dựa theo tham số đầu vào. Lưu ý: lớp này là&nbsp;<a href="http://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/"><strong>Singleton</strong>&nbsp;</a>hoặc cung cấp một&nbsp;<strong>public&nbsp;static method</strong>&nbsp;cho việc truy xuất và khởi tạo đối tượng.&nbsp;Factory class sử dụng if-else hoặc switch-case để xác định class con đầu ra.</li>
</ul>



<p style="font-size:16px">Ví dụ: Tất cả hệ thống Football Club có cung cấp API để truy cập đến hệ thống của họ. Team được giao nhiệm vụ thiết kế một API để client có thể sử dụng dịch vụ của một CLB bất kỳ. Hiện tại, phía client chỉ cần sử dụng dịch vụ của 1 số đội bóng như Becamex Bình Dương, Hoàng Anh Gia Lai, Hà Nội, &#8230; Tuy nhiên để dễ mở rộng sau này, và phía client mong muốn không cần phải thay đổi code của họ khi cần sử dụng thêm dịch vụ của đội bóng khác. Với yêu cầu như vậy, chúng ta có thể sử dụng một Pattern phù hợp là Factory Method Pattern.</p>



<p style="font-size:16px">Hệ thống được minh họa như sau:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="801" height="421" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/02/Untitled1.drawio-1.png" alt="" class="wp-image-3168" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Untitled1.drawio-1.png 801w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Untitled1.drawio-1-300x158.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Untitled1.drawio-1-768x404.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/Untitled1.drawio-1-380x200.png 380w" sizes="auto, (max-width: 801px) 100vw, 801px" /></figure>



<p style="font-size:16px">Chương trình được cài đặt theo Factory Pattern như sau:</p>



<p style="font-size:16px">Supper Class:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.factorymethod;

public interface FC {
    String getFCName();
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.factorymethod</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">interface</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">FC</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getFCName</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Sub Classes:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.factorymethod;
 
public class BECAMEXBinhDuong implements FC {
 
    @Override
    public String getFCName() {
        return &quot;Becamex Binh Duong&quot;;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.factorymethod</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">BECAMEXBinhDuong</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">implements</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">FC</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Override</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getFCName</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Becamex Binh Duong</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.factorymethod;
 
public class HAGL implements FC {
 
    @Override
    public String getFCName() {
        return &quot;Hoang Anh Gia Lai&quot;;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.factorymethod</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">HAGL</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">implements</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">FC</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Override</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getFCName</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Hoang Anh Gia Lai</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.factorymethod;
 
public class Hanoi implements FC {
 
    @Override
    public String getFCName() {
        return &quot;Ha Noi&quot;;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.factorymethod</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Hanoi</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">implements</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">FC</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    @</span><span style="color: #97E1F1; font-style: italic">Override</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getFCName</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Ha Noi</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Factory class:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.creational.factorymethod;

import org.tmsblog.enums.FCType;

public class FCFactory {
    public FCFactory() {
    }

    public static final FC getFC(FCType fcType) {
        switch (fcType) {
            case BECAMEX_BD:
                return new BECAMEXBinhDuong();
            case HAGL:
                return new HAGL();
            case HANOI:
                return new Hanoi();
            default:
                throw new IllegalArgumentException(&quot;This fc type is unsupported&quot;);
        }
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.creational.factorymethod</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.tmsblog.enums.FCType;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">FCFactory</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">FCFactory</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">FC</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getFC</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">FCType</span><span style="color: #F6F6F4"> </span><span style="color: #FFB86C; font-style: italic">fcType</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">switch</span><span style="color: #F6F6F4"> (fcType) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">case</span><span style="color: #F6F6F4"> BECAMEX_BD</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">BECAMEXBinhDuong</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">case</span><span style="color: #F6F6F4"> HAGL</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">HAGL</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">case</span><span style="color: #F6F6F4"> HANOI</span><span style="color: #F286C4">:</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">Hanoi</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">default:</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">throw</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">IllegalArgumentException</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">This fc type is unsupported</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">);</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">FC type:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.enums;

public enum FCType {
    BECAMEX_BD, HAGL, HANOI
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.enums</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">enum</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">FCType</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">BECAMEX_BD</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">HAGL</span><span style="color: #F6F6F4">, </span><span style="color: #BF9EEE">HANOI</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p style="font-size:16px">Client:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package org.tmsblog.patterns.creational.factorymethod;

import org.tmsblog.enums.FCType;

public class Client {
    public static void main(String[] args) {
        FC fc = FCFactory.getFC(FCType.HANOI);
        System.out.println(fc.getFCName());
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">org.tmsblog.patterns.creational.factorymethod</span><span style="color: #F6F6F4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> org.tmsblog.enums.FCType;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">Client</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">FC</span><span style="color: #F6F6F4"> fc </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> FCFactory.</span><span style="color: #62E884">getFC</span><span style="color: #F6F6F4">(FCType.HANOI);</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(fc.</span><span style="color: #62E884">getFCName</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Như anh em thấy, phía client chỉ cần gọi duy nhất một phương thức&nbsp;<strong>FCFactory.getFC()</strong>&nbsp;là có thể sử dụng được dịch vụ của một CLB bất kỳ.</p>



<p style="font-size:16px">Khi hệ thống muốn cung cấp thêm dịch vụ của một CLB khác, chẳng hạn Viettel, thì cần tạo thêm một class mới implement từ interface FC, và thêm vào logic khởi tạo FC trong Factory là xong. Nó không làm ảnh hưởng đến code ở phía Client.</p>



<h2 id="3-su-dung-factory-pattern-khi-nao" class="wp-block-heading" style="font-size:30px"><strong>3. Sử dụng Factory Pattern khi nào?</strong></h2>



<p style="font-size:16px">Factory Pattern được sử dụng khi:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Chúng ta có một super class với nhiều class con và dựa trên đầu vào, chúng ta cần trả về một class con. Mô hình này giúp chúng ta đưa trách nhiệm của việc khởi tạo một lớp từ phía người dùng (client) sang lớp Factory.</li>



<li style="font-size:16px">Chúng ta không biết sau này sẽ cần đến những lớp con nào nữa. Khi cần mở rộng, hãy tạo ra sub class và implement thêm vào factory method cho việc khởi tạo sub class này.</li>
</ul>



<h2 id="4-loi-ich-cua-factory-pattern-la-gi" class="wp-block-heading" style="font-size:30px"><strong>4. Lợi ích của Factory Pattern là gì?</strong></h2>



<p style="font-size:16px">Lợi ích của Factory Pattern:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Factory Pattern giúp giảm sự phụ thuộc giữa các module (loose coupling): cung cấp 1 hướng tiếp cận với Interface thay vì các implement. Giúp chuơng trình độc lập với những lớp cụ thể mà chúng ta cần tạo 1 đối tượng, code ở phía client không bị ảnh hưởng khi thay đổi logic ở factory hay sub class.</li>



<li style="font-size:16px">Mở rộng code dễ dàng hơn: khi cần mở rộng, chỉ việc tạo ra sub class và implement thêm vào factory method.</li>



<li style="font-size:16px">Khởi tạo các Objects mà che giấu đi xử lí logic của việc khởi tạo đấy. Người dùng không biết logic thực sực được khởi tạo bên dưới phương thức factory.</li>



<li style="font-size:16px">Dễ dàng quản lý life cycle của các Object được tạo bởi Factory Pattern.</li>



<li style="font-size:16px">Thống nhất về&nbsp;naming convention: giúp cho các&nbsp;developer có thể hiểu về cấu trúc source code.</li>
</ul>



<p style="font-size:16px">Anh em có thể thấy Factory Pattern được áp dụng trong:</p>



<ul class="wp-block-list">
<li style="font-size:16px">JDK:&nbsp;java.util.Calendar, ResourceBundle, NumberFormat, …</li>



<li style="font-size:16px">BeanFactory trong Spring Framework.</li>



<li style="font-size:16px">SessionFactory trong Hibernate Framework.</li>
</ul>



<p style="font-size:16px">Như vậy tôi đã giới thiệu xong về Factory Method Pattern, hy vọng bài viết sẽ giúp ích cho anh em trong quá trình xây dựng và phát triển ứng dụng. Hẹn gặp lại ở các bài viết tiếp theo.</p>



<p style="font-size:16px"><strong>Tài liệu tham khảo:</strong></p>



<ul class="wp-block-list">
<li style="font-size:16px"><a href="https://refactoring.guru/design-patterns/factory-method">https://refactoring.guru/design-patterns/factory-method</a></li>



<li style="font-size:16px"><a href="https://sourcemaking.com/design_patterns/factory_method">https://sourcemaking.com/design_patterns/factory_method</a></li>



<li style="font-size:16px"><a href="https://www.tutorialspoint.com/design_pattern/factory_pattern.htm">https://www.tutorialspoint.com/design_pattern/factory_pattern.htm</a></li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/huong-dan-java-design-pattern-factory-method/">Hướng dẫn Java Design Pattern – Factory Method</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/huong-dan-java-design-pattern-factory-method/feed/</wfw:commentRss>
			<slash:comments>340</slash:comments>
		
		
			</item>
		<item>
		<title>Hướng dẫn Java Design Pattern – Singleton</title>
		<link>https://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/</link>
					<comments>https://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/#comments</comments>
		
		<dc:creator><![CDATA[admin_tomosia]]></dc:creator>
		<pubDate>Tue, 20 Feb 2024 08:21:39 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=3157</guid>

					<description><![CDATA[<p>Hi các đồng dâm, tôi lại quay trở lại rồi đây, trong bài trước tôi đã giới thiệu&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/">Hướng dẫn Java Design Pattern – Singleton</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="font-size:16px">Hi các đồng dâm, tôi lại quay trở lại rồi đây, trong bài trước tôi đã giới thiệu với anh em kiến thức cơ bản của <a href="http://blog.tomosia.com.vn/gioi-thieu-design-patterns/">Design Pattern</a>. Tiếp tục với series Design Patterns, đây sẽ là &#8220;<em>màn dạo đầu</em>&#8221; nhé =))))</p>



<p style="font-size:16px">Đôi khi, trong quá trình phân tích thiết kế một hệ thống, chúng ta mong muốn có những đối tượng cần tồn tại duy nhất và có thể truy xuất mọi lúc mọi nơi. Làm thế nào để hiện thực được một đối tượng như thế khi xây dựng mã nguồn? Chúng ta có thể nghĩ tới việc sử dụng một biến toàn cục (global variable : public static final). Tuy nhiên, việc sử dụng biến toàn cục nó phá vỡ quy tắc của&nbsp;<strong>OOP (encapsulation)</strong>. Để giải bài toán trên, người ta hướng đến một giải pháp là sử dụng&nbsp;<strong>Singleton pattern</strong>.</p>



<h2 id="1-singleton-pattern-la-gi" class="wp-block-heading" style="font-size:30px"><strong>1. Singleton Pattern là gì?</strong></h2>



<p style="font-size:16px"><strong>Singleton</strong>&nbsp;là 1 trong 5 design pattern của nhóm&nbsp;<strong>Creational Design Pattern</strong>.</p>



<p style="font-size:16px"><strong>Singleton</strong>&nbsp;đảm bảo chỉ duy nhất&nbsp;<strong>một thể hiện (instance)</strong>&nbsp;được tạo ra và nó sẽ cung cấp cho anh em một method để có thể truy xuất được thể hiện duy nhất đó mọi lúc mọi nơi trong chương trình.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" data-id="3162" src="http://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-1024x640.png" alt="" class="wp-image-3162" srcset="https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-1024x640.png 1024w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-300x188.png 300w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-768x480.png 768w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-1536x960.png 1536w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-380x238.png 380w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-800x500.png 800w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9-1160x725.png 1160w, https://blog.tomosia.com.vn/wp-content/uploads/2024/02/image-9.png 1920w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p style="font-size:16px">Sử dụng Singleton khi chúng ta muốn:</p>



<ul class="wp-block-list" style="font-size:16px">
<li>Đảm bảo rằng chỉ có một instance của lớp.</li>



<li>Việc quản lý việc truy cập tốt hơn vì chỉ có một thể hiện duy nhất.</li>



<li>Có thể quản lý số lượng thể hiện của một lớp trong giớn hạn chỉ định.</li>
</ul>



<h2 id="2-implement-singleton-pattern-nhu-the-nao" class="wp-block-heading" style="font-size:30px"><strong>2. Implement Singleton Pattern như thế nào?</strong></h2>



<p style="font-size:16px">Có rất nhiều cách để implement Singleton Pattern. Nhưng dù cho việc implement bằng cách nào đi nữa cũng dựa vào nguyên tắc dưới đây cơ bản dưới đây:</p>



<ul class="wp-block-list">
<li style="font-size:16px"><strong>private constructor</strong>&nbsp;để hạn chế truy cập từ class bên ngoài.</li>



<li style="font-size:16px">Đặt&nbsp;<strong>private static final variable</strong>&nbsp;đảm bảo biến chỉ được khởi tạo trong class.</li>



<li style="font-size:16px">Có một method&nbsp;<strong>public static</strong>&nbsp;để&nbsp;<strong>return instance</strong>&nbsp;được khởi tạo ở trên.</li>
</ul>



<h2 id="3-nhung-cach-nao-de-implement-singleton-pattern" class="wp-block-heading" style="font-size:30px"><strong>3. Những cách nào để implement Singleton Pattern</strong></h2>



<p style="font-size:16px">Dựa trên những nguyên tắc thiết kế Singleton ở trên, chúng ta có các cách implement singleton như sau:</p>



<p style="font-size:23px"><strong>3.1. Eager initialization</strong></p>



<p style="font-size:16px"><strong>Singleton</strong>&nbsp;Class được khởi tạo ngay khi được gọi đến.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
public class EagerInitializedSingleton {
 
    private static final EagerInitializedSingleton INSTANCE = new EagerInitializedSingleton();
 
    private EagerInitializedSingleton() {}
 
    public static EagerInitializedSingleton getInstance() {
        return INSTANCE;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">EagerInitializedSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">EagerInitializedSingleton</span><span style="color: #F6F6F4"> INSTANCE </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">EagerInitializedSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">EagerInitializedSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">EagerInitializedSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> INSTANCE;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Eager initialization là cách tiếp cận tốt, dễ cài đặt, tuy nhiên nó có một nhược điểm mặc dù instance đã được khởi tạo nhưng có thể sẽ không dùng tới và nó dễ dàng bị phá vỡ bởi Reflection.</p>



<p style="font-size:23px"><strong>3.2. Static block initialization</strong></p>



<p style="font-size:16px">Cách làm tương tự như&nbsp;<strong>Eager initialization</strong>&nbsp;chỉ khác phần&nbsp;<strong>static block</strong>&nbsp;cung cấp thêm lựa chọn cho việc handle exception hay các xử lý khác.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
public class StaticBlockSingleton {
 
    private static final StaticBlockSingleton INSTANCE;
 
    private StaticBlockSingleton() {}
 
    // Static block initialization for exception handling
    static {
        try {
            INSTANCE = new StaticBlockSingleton();
        } catch (Exception e) {
            throw new RuntimeException(&quot;Exception occured in creating singleton instance&quot;);
        }
    }
 
    public static StaticBlockSingleton getInstance() {
        return INSTANCE;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">StaticBlockSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">StaticBlockSingleton</span><span style="color: #F6F6F4"> INSTANCE;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">StaticBlockSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #7B7F8B">// Static block initialization for exception handling</span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">try</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">            INSTANCE </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">StaticBlockSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        } </span><span style="color: #F286C4">catch</span><span style="color: #F6F6F4"> (</span><span style="color: #97E1F1; font-style: italic">Exception</span><span style="color: #F6F6F4"> </span><span style="color: #FFB86C; font-style: italic">e</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">throw</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">RuntimeException</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">Exception occured in creating singleton instance</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">);</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">StaticBlockSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> INSTANCE;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:23px"><strong>3.3. Lazy Initialization</strong></p>



<p style="font-size:16px">Là một cách làm mang tính mở rộng hơn so với 2 cách làm trên và hoạt động tốt trong môi trường đơn luồng (single-thread).</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
public class LazyInitializedSingleton {
 
    private static LazyInitializedSingleton instance;
 
    private LazyInitializedSingleton() {}
 
    public static LazyInitializedSingleton getInstance() {
        if (instance == null) {
            instance = new LazyInitializedSingleton();
        }
        return instance;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">LazyInitializedSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">LazyInitializedSingleton</span><span style="color: #F6F6F4"> instance;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">LazyInitializedSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">LazyInitializedSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (instance </span><span style="color: #F286C4">==</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">            instance </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">LazyInitializedSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> instance;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Cách này đã khắc phục được nhược điểm của cách&nbsp;<strong>Eager initialization</strong>, chỉ khi nào&nbsp;<strong>getInstance()</strong>&nbsp;được gọi thì instance mới được khởi tạo. Tuy nhiên, cách này chỉ sử dụng tốt trong trường hợp đơn luồng (single-thread), trường hợp nếu có nhiều luồng (multi-thread) cùng chạy và cùng gọi hàm getInstance() tại cùng một thời điểm thì có thể có nhiều hơn 1 thể hiện của instance. Để khắc phục nhược điểm này chúng ta sử dụng&nbsp;<strong>Thread Safe Singleton</strong>.</p>



<p style="font-size:16px">Một nhược điểm nữa của&nbsp;<strong>Lazy Initialization</strong>&nbsp;cần quan tâm là: đối với thao tác create instance quá chậm thì người dùng có phải chờ lâu cho lần sử dụng đầu tiên.</p>



<p style="font-size:23px"><strong>3.4. Thread Safe Singleton</strong></p>



<p style="font-size:16px">Cách đơn giản nhất là chúng ta gọi phương thức&nbsp;<strong>synchronized</strong>&nbsp;của hàm&nbsp;<strong>getInstance()</strong>&nbsp;và như vậy hệ thống đảm bảo rằng tại cùng một thời điểm chỉ có thể có 1 luồng có thể truy cập vào hàm getInstance() và đảm bảo rằng chỉ có duy nhất 1 thể hiện của class.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
public class ThreadSafeLazyInitializedSingleton {
 
    private static volatile ThreadSafeLazyInitializedSingleton instance;
 
    private ThreadSafeLazyInitializedSingleton() {}
 
    public static synchronized ThreadSafeLazyInitializedSingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeLazyInitializedSingleton();
        }
        return instance;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">ThreadSafeLazyInitializedSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">volatile</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">ThreadSafeLazyInitializedSingleton</span><span style="color: #F6F6F4"> instance;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ThreadSafeLazyInitializedSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">synchronized</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">ThreadSafeLazyInitializedSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (instance </span><span style="color: #F286C4">==</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">            instance </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ThreadSafeLazyInitializedSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> instance;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<blockquote class="wp-block-quote is-style-default is-layout-flow wp-block-quote-is-layout-flow">
<p></p>
<cite>Biến&nbsp;<strong>volatile</strong>&nbsp;trong Java có tác dụng thông báo sự thay đổi giá trị của biến tới các thread khác&nbsp;nhau nếu biến này đang được sử dụng trong nhiều thread.</cite></blockquote>



<p style="font-size:16px">Cách này có nhược điểm là một phương thức&nbsp;<strong>synchronized</strong>&nbsp;sẽ chạy rất chậm và tốn hiệu năng, bất kỳ Thread nào gọi đến đều phải chờ nếu có một Thread khác đang sử dụng. Có những tác vụ xử lý trước và sau khi tạo thể hiện không cần thiết phải block. Vì vậy chúng ta cần cải tiến nó đi 1 chút với&nbsp;<strong>Double Check Locking Singleton</strong>.</p>



<p style="font-size:23px"><strong>3.5. Double Check Locking Singleton</strong></p>



<p style="font-size:16px">Để implement theo cách này, chúng ta sẽ kiểm tra sự tồn tại thể hiện của lớp, với sự hỗ trợ của đồng bộ hóa, hai lần trước khi khởi tạo. Phải khai báo&nbsp;<strong>volatile</strong>&nbsp;cho instance để tránh lớp làm việc không chính xác do quá trình tối ưu hóa của trình biên dịch.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
public class DoubleCheckLockingSingleton {
 
    private static volatile DoubleCheckLockingSingleton instance;
 
    private DoubleCheckLockingSingleton() {}
 
    public static DoubleCheckLockingSingleton getInstance() {
        // Do something before get instance ...
        if (instance == null) {
            // Do the task too long before create instance ...
            // Block so other threads cannot come into while initialize
            synchronized (DoubleCheckLockingSingleton.class) {
                // Re-check again. Maybe another thread has initialized before
                if (instance == null) {
                    instance = new DoubleCheckLockingSingleton();
                }
            }
        }
        // Do something after get instance ...
        return instance;
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">DoubleCheckLockingSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">volatile</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">DoubleCheckLockingSingleton</span><span style="color: #F6F6F4"> instance;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">DoubleCheckLockingSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">DoubleCheckLockingSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">// Do something before get instance ...</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (instance </span><span style="color: #F286C4">==</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #7B7F8B">// Do the task too long before create instance ...</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #7B7F8B">// Block so other threads cannot come into while initialize</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">synchronized</span><span style="color: #F6F6F4"> (DoubleCheckLockingSingleton.class) {</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #7B7F8B">// Re-check again. Maybe another thread has initialized before</span></span>
<span class="line"><span style="color: #F6F6F4">                </span><span style="color: #F286C4">if</span><span style="color: #F6F6F4"> (instance </span><span style="color: #F286C4">==</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">) {</span></span>
<span class="line"><span style="color: #F6F6F4">                    instance </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">DoubleCheckLockingSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">                }</span></span>
<span class="line"><span style="color: #F6F6F4">            }</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">// Do something after get instance ...</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> instance;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:23px"><strong>3.6. Bill Pugh Singleton Implementation</strong></p>



<p style="font-size:16px">Với cách làm này bạn sẽ tạo ra&nbsp;<strong>static nested class</strong>&nbsp;với vai trò 1 Helper khi muốn tách biệt chức năng cho 1 class function rõ ràng hơn. Đây là cách thường hay được sử dụng và có hiệu suất tốt (theo các chuyên gia đánh giá :v).</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
public class BillPughSingleton {
 
    private BillPughSingleton() {}
 
    public static BillPughSingleton getInstance() {
        return SingletonHelper.INSTANCE;
    }
 
    private static class SingletonHelper {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">BillPughSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">BillPughSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">BillPughSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> SingletonHelper.INSTANCE;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">SingletonHelper</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">BillPughSingleton</span><span style="color: #F6F6F4"> INSTANCE </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">BillPughSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Khi Singleton được tải vào bộ nhớ thì SingletonHelper chưa được tải vào. Nó chỉ được tải khi và chỉ khi phương thức getInstance() được gọi. Với cách này tránh được lỗi cơ chế khởi tạo instance của Singleton trong Multi-Thread, performance cao do tách biệt được quá trình xử lý. Do đó, cách làm này được đánh giá là cách triển khai Singleton nhanh và hiệu quả nhất.</p>



<p style="font-size:23px"><strong>3.7. Phá vỡ cấu trúc Singleton Pattern bằng Reflection</strong></p>



<p style="font-size:16px"><strong>Reflection</strong>&nbsp;có thể được dùng để phá vỡ Pattern của&nbsp;<strong>Eager Initialization</strong>&nbsp;ở trên.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
 
public class ReflectionBreakSingleton {
 
    public static void main(String[] args)
            throws InstantiationException, IllegalAccessException, InvocationTargetException {
         
        EagerInitializedSingleton instanceOne = EagerInitializedSingleton.getInstance();
        EagerInitializedSingleton instanceTwo = null;
 
        Constructor&lt;?&gt;[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
        for (Constructor&lt;?&gt; constructor : constructors) {
            constructor.setAccessible(true);
            instanceTwo = (EagerInitializedSingleton) constructor.newInstance();
        }
 
        System.out.println(instanceOne.hashCode());
        System.out.println(instanceTwo.hashCode());
    }
}
" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.lang.reflect.Constructor;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.lang.reflect.InvocationTargetException;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">ReflectionBreakSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">)</span></span>
<span class="line"><span style="color: #F6F6F4">            </span><span style="color: #F286C4">throws</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">InstantiationException</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">IllegalAccessException</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">InvocationTargetException</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">         </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">EagerInitializedSingleton</span><span style="color: #F6F6F4"> instanceOne </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> EagerInitializedSingleton.</span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">EagerInitializedSingleton</span><span style="color: #F6F6F4"> instanceTwo </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">null</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">Constructor</span><span style="color: #F6F6F4">&lt;</span><span style="color: #97E1F1; font-style: italic">?</span><span style="color: #F6F6F4">&gt;[] constructors </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> EagerInitializedSingleton.class.</span><span style="color: #62E884">getDeclaredConstructors</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">for</span><span style="color: #F6F6F4"> (</span><span style="color: #97E1F1; font-style: italic">Constructor</span><span style="color: #F6F6F4">&lt;</span><span style="color: #97E1F1; font-style: italic">?</span><span style="color: #F6F6F4">&gt; constructor </span><span style="color: #F286C4">:</span><span style="color: #F6F6F4"> constructors) {</span></span>
<span class="line"><span style="color: #F6F6F4">            constructor.</span><span style="color: #62E884">setAccessible</span><span style="color: #F6F6F4">(</span><span style="color: #BF9EEE">true</span><span style="color: #F6F6F4">);</span></span>
<span class="line"><span style="color: #F6F6F4">            instanceTwo </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (EagerInitializedSingleton) constructor.</span><span style="color: #62E884">newInstance</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        }</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(instanceOne.</span><span style="color: #62E884">hashCode</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(instanceTwo.</span><span style="color: #62E884">hashCode</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span>
<span class="line"></span></code></pre></div>



<p>Output của chương trình:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="2018699554
1311053135" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #BF9EEE">2018699554</span></span>
<span class="line"><span style="color: #BF9EEE">1311053135</span></span></code></pre></div>



<p style="font-size:16px">Tương tự&nbsp;<strong>Eager Initialization</strong>, implement theo&nbsp;<strong>Bill Pugh Singleton</strong>&nbsp;cũng bị break bởi Reflection.</p>



<p style="font-size:23px"><strong>3.8. Enum Singleton</strong></p>



<p style="font-size:16px">Khi dùng&nbsp;<strong>enum</strong>&nbsp;thì các params chỉ được khởi tạo 1 lần duy nhất, đây cũng là cách giúp anh em tạo ra Singleton instance.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
/**
 * Singleton implementation using enum initialization
 */
public enum EnumSingleton {
 
    INSTANCE;
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #7B7F8B">/**</span></span>
<span class="line"><span style="color: #7B7F8B"> * Singleton implementation using enum initialization</span></span>
<span class="line"><span style="color: #7B7F8B"> */</span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">enum</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">EnumSingleton</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #BF9EEE">INSTANCE</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Lưu ý:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Enum có thể sử dụng như một Singleton, nhưng nó có nhược điểm là không thể extends từ một lớp được, nên khi sử dụng cần xem xét vấn đề này.</li>



<li style="font-size:16px">Hàm&nbsp;<strong>constructor</strong>&nbsp;của&nbsp;<strong>enum</strong>&nbsp;là&nbsp;<strong>lazy</strong>, nghĩa là khi được sử dụng mới chạy hàm khởi tạo và nó chỉ chạy duy nhất một lần. Nếu muốn sử dụng như một eager singleton thì cần gọi thực thi trong một&nbsp;<strong>static block</strong>&nbsp;khi start chương trình.</li>
</ul>



<p style="font-size:16px">So sánh giữa 2 cách sử dụng&nbsp;<strong>enum initialization</strong>&nbsp;và&nbsp;<strong>static block initialization</strong>&nbsp;<strong>method</strong>, enum có một điểm rất mạnh khi giải quyết về vấn đề&nbsp;<strong>Serialization/ Deserialization</strong>.</p>



<p style="font-size:23px"><strong>3.9. Serialization and Singleton</strong></p>



<p style="font-size:16px">Đôi khi trong các hệ thống phân tán (distributed system), chúng ta cần implement interface&nbsp;<strong>Serializable</strong>&nbsp;trong lớp Singleton để chúng ta có thể lưu trữ trạng thái của nó trong file hệ thống và truy xuất lại nó sau.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
import java.io.ObjectStreamException;
import java.io.Serializable;
 
public class SerializedSingleton implements Serializable {
 
    private static final long serialVersionUID = 1741825395699241705L;
 
    private SerializedSingleton() {}
 
    private static class SingletonHelper {
        private static final SerializedSingleton instance = new SerializedSingleton();
    }
 
    public static SerializedSingleton getInstance() {
        return SingletonHelper.instance;
    }
     
    /**
     * Special hook provided by serialization where developer can control what object needs to sent.
     * However this method is invoked on the new object instance created by de serialization process.
     *
     * @return
     * @throws ObjectStreamException
     */
//    private Object readResolve() throws ObjectStreamException {
//        return SingletonHelper.instance;
//    }
 
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.ObjectStreamException;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.Serializable;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">SerializedSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">implements</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">Serializable</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">long</span><span style="color: #F6F6F4"> serialVersionUID </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #BF9EEE">1741825395699241705L</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">SerializedSingleton</span><span style="color: #F6F6F4">() {}</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">SingletonHelper</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">private</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">final</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">SerializedSingleton</span><span style="color: #F6F6F4"> instance </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">SerializedSingleton</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">SerializedSingleton</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">() {</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #F286C4">return</span><span style="color: #F6F6F4"> SingletonHelper.instance;</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">     </span></span>
<span class="line"><span style="color: #7B7F8B">    /**</span></span>
<span class="line"><span style="color: #7B7F8B">     * Special hook provided by serialization where developer can control what object needs to sent.</span></span>
<span class="line"><span style="color: #7B7F8B">     * However this method is invoked on the new object instance created by de serialization process.</span></span>
<span class="line"><span style="color: #7B7F8B">     *</span></span>
<span class="line"><span style="color: #7B7F8B">     * </span><span style="color: #F286C4">@return</span></span>
<span class="line"><span style="color: #7B7F8B">     * </span><span style="color: #F286C4">@throws</span><span style="color: #7B7F8B"> </span><span style="color: #97E1F1">ObjectStreamException</span></span>
<span class="line"><span style="color: #7B7F8B">     */</span></span>
<span class="line"><span style="color: #7B7F8B">//    private Object readResolve() throws ObjectStreamException {</span></span>
<span class="line"><span style="color: #7B7F8B">//        return SingletonHelper.instance;</span></span>
<span class="line"><span style="color: #7B7F8B">//    }</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Đoạn code test quá trình Serialize/ Deserialize:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:16.859375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="package com.tmsblog.patterns.creational.singleton;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
 
public class SingletonSerializedTest {
 
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
 
        SerializedSingleton serializedSingleton1 = SerializedSingleton.getInstance();
        EnumSingleton enumSingleton1 = EnumSingleton.INSTANCE;
 
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(&quot;SingletonSerializedTest.txt&quot;));
        out.writeObject(serializedSingleton1);
        out.writeObject(enumSingleton1);
        out.close();
 
        // De-serialize from file to object
        ObjectInput in = new ObjectInputStream(new FileInputStream(&quot;SingletonSerializedTest.txt&quot;));
        SerializedSingleton serializedSingleton2 = (SerializedSingleton) in.readObject();
        EnumSingleton enumSingleton2 = (EnumSingleton) in.readObject();
        in.close();
 
        System.out.println(&quot;serializedSingleton1 hashCode=&quot; + serializedSingleton1.hashCode());
        System.out.println(&quot;serializedSingleton2 hashCode=&quot; + serializedSingleton2.hashCode());
        System.out.println(&quot;enumSingleton1 hashCode=&quot; + enumSingleton1.hashCode());
        System.out.println(&quot;enumSingleton2 hashCode=&quot; + enumSingleton2.hashCode());
    }
}" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F286C4">package</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">com.tmsblog.patterns.creational.singleton</span><span style="color: #F6F6F4">;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.FileInputStream;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.FileNotFoundException;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.FileOutputStream;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.IOException;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.ObjectInput;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.ObjectInputStream;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.ObjectOutput;</span></span>
<span class="line"><span style="color: #F286C4">import</span><span style="color: #F6F6F4"> java.io.ObjectOutputStream;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">class</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1">SingletonSerializedTest</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">    </span><span style="color: #F286C4">public</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">static</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">void</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">main</span><span style="color: #F6F6F4">(</span><span style="color: #97E1F1; font-style: italic">String</span><span style="color: #F6F6F4">[] </span><span style="color: #FFB86C; font-style: italic">args</span><span style="color: #F6F6F4">) </span><span style="color: #F286C4">throws</span><span style="color: #F6F6F4"> </span><span style="color: #97E1F1; font-style: italic">FileNotFoundException</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">IOException</span><span style="color: #F6F6F4">, </span><span style="color: #97E1F1; font-style: italic">ClassNotFoundException</span><span style="color: #F6F6F4"> {</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">SerializedSingleton</span><span style="color: #F6F6F4"> serializedSingleton1 </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> SerializedSingleton.</span><span style="color: #62E884">getInstance</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">EnumSingleton</span><span style="color: #F6F6F4"> enumSingleton1 </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> EnumSingleton.INSTANCE;</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">ObjectOutput</span><span style="color: #F6F6F4"> out </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ObjectOutputStream</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">FileOutputStream</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">SingletonSerializedTest.txt</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">));</span></span>
<span class="line"><span style="color: #F6F6F4">        out.</span><span style="color: #62E884">writeObject</span><span style="color: #F6F6F4">(serializedSingleton1);</span></span>
<span class="line"><span style="color: #F6F6F4">        out.</span><span style="color: #62E884">writeObject</span><span style="color: #F6F6F4">(enumSingleton1);</span></span>
<span class="line"><span style="color: #F6F6F4">        out.</span><span style="color: #62E884">close</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #7B7F8B">// De-serialize from file to object</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">ObjectInput</span><span style="color: #F6F6F4"> in </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">ObjectInputStream</span><span style="color: #F6F6F4">(</span><span style="color: #F286C4; font-weight: bold">new</span><span style="color: #F6F6F4"> </span><span style="color: #62E884">FileInputStream</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">SingletonSerializedTest.txt</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4">));</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">SerializedSingleton</span><span style="color: #F6F6F4"> serializedSingleton2 </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (SerializedSingleton) in.</span><span style="color: #62E884">readObject</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        </span><span style="color: #97E1F1; font-style: italic">EnumSingleton</span><span style="color: #F6F6F4"> enumSingleton2 </span><span style="color: #F286C4">=</span><span style="color: #F6F6F4"> (EnumSingleton) in.</span><span style="color: #62E884">readObject</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4">        in.</span><span style="color: #62E884">close</span><span style="color: #F6F6F4">();</span></span>
<span class="line"><span style="color: #F6F6F4"> </span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">serializedSingleton1 hashCode=</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> serializedSingleton1.</span><span style="color: #62E884">hashCode</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">serializedSingleton2 hashCode=</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> serializedSingleton2.</span><span style="color: #62E884">hashCode</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">enumSingleton1 hashCode=</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> enumSingleton1.</span><span style="color: #62E884">hashCode</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">        System.out.</span><span style="color: #62E884">println</span><span style="color: #F6F6F4">(</span><span style="color: #DEE492">&quot;</span><span style="color: #E7EE98">enumSingleton2 hashCode=</span><span style="color: #DEE492">&quot;</span><span style="color: #F6F6F4"> </span><span style="color: #F286C4">+</span><span style="color: #F6F6F4"> enumSingleton2.</span><span style="color: #62E884">hashCode</span><span style="color: #F6F6F4">());</span></span>
<span class="line"><span style="color: #F6F6F4">    }</span></span>
<span class="line"><span style="color: #F6F6F4">}</span></span></code></pre></div>



<p style="font-size:16px">Output của chương trình:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#f6f6f4;--cbp-line-number-width:8.4375px;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#333545;color:#ebebe6">Java</span><span role="button" tabindex="0" data-code="serializedSingleton1 hashCode=1028566121
serializedSingleton2 hashCode=1747585824
enumSingleton1 hashCode=1118140819
enumSingleton2 hashCode=1118140819" style="color:#f6f6f4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula-soft" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F6F6F4">serializedSingleton1 hashCode</span><span style="color: #F286C4">=</span><span style="color: #BF9EEE">1028566121</span></span>
<span class="line"><span style="color: #F6F6F4">serializedSingleton2 hashCode</span><span style="color: #F286C4">=</span><span style="color: #BF9EEE">1747585824</span></span>
<span class="line"><span style="color: #F6F6F4">enumSingleton1 hashCode</span><span style="color: #F286C4">=</span><span style="color: #BF9EEE">1118140819</span></span>
<span class="line"><span style="color: #F6F6F4">enumSingleton2 hashCode</span><span style="color: #F286C4">=</span><span style="color: #BF9EEE">1118140819</span></span></code></pre></div>



<p style="font-size:16px">Như trong ví dụ trên,&nbsp;<strong>Deserialize</strong>&nbsp;đối tượng của&nbsp;<strong>SerializedSingleton</strong>&nbsp;khác với đối tượng gốc. Tuy nhiên vấn đề này không xảy ra khi sử dụng&nbsp;<strong>enum</strong>.</p>



<p style="font-size:16px">Thực tế thì vẫn có cách khắc phục khi sử dụng class SerializedSingleton là implement một phương thức&nbsp;<strong>readResolve()</strong>. Nhưng khi chúng ta thật sự gặp vấn đề và cần sử dụng Serialize/ Deserialize, thì nên sử dụng&nbsp;<strong>enum</strong>&nbsp;sẽ đơn giản hơn.</p>



<h2 id="4-su-dung-singleton-pattern-khi-nao" class="wp-block-heading" style="font-size:30px"><strong>4. Sử dụng Singleton Pattern khi nào?</strong></h2>



<p style="font-size:16px">Dưới đây là một số trường hợp sử dụng của Singleton Pattern thường gặp:</p>



<ul class="wp-block-list">
<li style="font-size:16px">Vì class dùng Singleton chỉ tồn tại 1 Instance (thể hiện) nên nó thường được dùng cho các trường hợp giải quyết các bài toán cần truy cập vào các ứng dụng như: Shared resource, Logger, Configuration, Caching, Thread pool, …</li>



<li style="font-size:16px">Một số design pattern khác cũng sử dụng Singleton để triển khai: Abstract Factory, Builder, Prototype, Facade,…</li>



<li style="font-size:16px">Đã được sử dụng trong một số class của core java như:&nbsp;java.lang.Runtime, java.awt.Desktop.</li>
</ul>



<h2 id="5-tong-ket" class="wp-block-heading" style="font-size:30px"><strong>5. Tổng kết</strong></h2>



<p style="font-size:16px">Có rất nhiều cách implement cho Singleton, anh em có thể sử dụng&nbsp;<strong>BillPughSingleton</strong>&nbsp;vì có hiệu suất cao, sử dụng&nbsp;<strong>LazyInitializedSingleton</strong>&nbsp;cho những ứng dụng chỉ làm việc với ứng dụng&nbsp;<strong>single-thread</strong>&nbsp;và sử dụng&nbsp;<strong>DoubleCheckLockingSingleton</strong>&nbsp;khi làm việc với ứng dụng&nbsp;<strong>multi-thread</strong>. Tùy theo trường hợp cụ thể, anh em hãy chọn cho mình cách implement phù hợp nhé.</p>



<p style="font-size:16px"><strong>Tài liệu tham khảo:</strong></p>



<ul class="wp-block-list">
<li style="font-size:16px"><a href="https://community.oracle.com/docs/DOC-918906">https://community.oracle.com/docs/DOC-918906</a></li>



<li style="font-size:16px"><a href="https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples">https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples</a></li>



<li style="font-size:16px"><a href="http://www.javacreed.com/the-broken-singleton/">http://www.javacreed.com/the-broken-singleton/</a></li>



<li style="font-size:16px"><a href="https://www.geeksforgeeks.org/prevent-singleton-pattern-reflection-serialization-cloning/">https://www.geeksforgeeks.org/prevent-singleton-pattern-reflection-serialization-cloning/</a></li>



<li style="font-size:16px"><a href="http://www.java67.com/2015/09/thread-safe-singleton-in-java-using-double-checked-locking-pattern.html">http://www.java67.com/2015/09/thread-safe-singleton-in-java-using-double-checked-locking-pattern.html</a></li>
</ul>
<p>The post <a href="https://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/">Hướng dẫn Java Design Pattern – Singleton</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/huong-dan-java-design-pattern-singleton/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
