Erlang OTP: Distributed & Fault-Tolerant Systems Programming · บทเรียน

พฤติกรรม OTP แบบกำหนดเอง

ทำความเข้าใจโครงสร้างของพฤติกรรม OTP และวิธีสร้างพฤติกรรมทั่วไปแบบกำหนดเองเพื่อห่อหุ้มรูปแบบการทำงานที่ใช้ร่วมกัน

บทเรียน 3 จาก 411 ขั้นตอน

พฤติกรรม OTP แบบกำหนดเอง เป็นบทเรียน Erlang OTP: Distributed & Fault-Tolerant Systems Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Erlang OTP: Distributed & Fault-Tolerant Systems Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Erlang OTP: Distributed & Fault-Tolerant Systems Programming มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

Intro: What are OTP Behaviors?

You've learned about OTP behaviors like GenServer and GenStatem. They provide a standard way to build robust, fault-tolerant components.

But what if you have a recurring pattern that isn't perfectly covered by existing behaviors? This is where custom OTP behaviors come in handy!

They let you define your own generic component structure.

Why Custom Behaviors?

Creating custom behaviors offers several key advantages:

  • Code Reuse: Encapsulate common logic once and reuse it across many modules.
  • Consistency: Ensure all components following your behavior adhere to a specific interface and structure.
  • Abstraction: Hide complex internal details, exposing a simpler API to users.
  • Maintainability: Changes to the core logic only need to happen in one place.

Anatomy of a Behavior

An OTP behavior typically consists of two main parts:

  • The Behavior Module: This module defines the public interface (functions users call) and often provides helper functions for the callback module. It uses the -behaviour(gen_server) or similar attribute to link to a generic server.
  • The Callback Module: This is where the actual logic lives. It implements the callback functions (like init/1, handle_call/3) required by the behavior module.

Think of it as a contract between the two.

Behavior Module: Interface

The "behavior module" is what other modules -behaviour(...) against. For custom behaviors, you'll often define a module that wraps an existing generic behavior (like gen_server) but adds your specific API.

It acts as the client-side interface for users of your custom behavior.

Key aspects:

  • Defines the public functions (e.g., start_link/0, my_action/1).
  • These functions typically call gen_server:start_link/3 or gen_server:call/2 internally.
  • It specifies the callback module using the -callback attribute.

Callback Module: Logic

The "callback module" is where the core functionality of your custom behavior resides. It's the module that actually implements the required functions defined by the underlying generic behavior (like gen_server or gen_statem).

  • It must implement functions like init/1, handle_call/3, handle_cast/2, etc.
  • These functions manage the state and respond to messages.
  • This module is what the behavior module (e.g., gen_server) calls directly.

Counter Behavior: Start

Let's create a simple custom counter behavior. We'll wrap a gen_server to manage an integer count.

First, define the behavior module, which acts as the client API and starts the underlying gen_server.

-module(my_counter).
-behaviour(gen_server). % We wrap gen_server

-export([start_link/0, get_count/0, increment/0, decrement/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

% Public API for starting the counter
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

% --- gen_server callbacks (for *this* module acting as callback) ---
% This is where the initial state is set
init([]) ->
    {ok, 0}. % Initial count is 0

Counter Behavior: Functions

Now, let's add the public functions to interact with our counter (increment, decrement, get_count) and implement their corresponding handle_call logic.

These public functions will use gen_server:call/2 to send requests to the actual counter process.

-module(my_counter).
-behaviour(gen_server).

-export([start_link/0, get_count/0, increment/0, decrement/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

% Public API for interacting with the counter
get_count() ->
    gen_server:call(?MODULE, get_count).

increment() ->
    gen_server:call(?MODULE, increment).

drcrement() ->
    gen_server:call(?MODULE, decrement).

% --- gen_server callbacks ---
init([]) ->
    {ok, 0}.

handle_call(get_count, _From, State) ->
    {reply, State, State};
handle_call(increment, _From, State) ->
    NewState = State + 1,
    {reply, NewState, NewState};
handle_call(decrement, _From, State) ->
    NewState = State - 1,
    {reply, NewState, NewState};
handle_call(_Request, _From, State) ->
    {reply, {error, unknown_request}, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

Using the Custom Counter

With our my_counter behavior defined, we can now easily use it from an Erlang shell or another module. Notice how simple the client-side code is!

You don't need to know the gen_server details; you just use the custom behavior's API.

-module(counter_app).
-export([run/0]).

run() ->
    % Start our custom counter behavior
    io:format("Starting counter...~n"),
    my_counter:start_link(),

    io:format("Current count: ~p~n", [my_counter:get_count()]),

    io:format("Incrementing...~n"),
    my_counter:increment(),
    io:format("Current count: ~p~n", [my_counter:get_count()]),

    io:format("Decrementing...~n"),
    my_counter:decrement(),
    io:format("Current count: ~p~n", [my_counter:get_count()]),

    % Stop the counter (optional, usually supervisors handle this)
    gen_server:stop(my_counter),
    io:format("Counter stopped.~n").

When to Use Custom Behaviors

Custom OTP behaviors are powerful, but not every component needs one. Consider creating a custom behavior when:

  • You find yourself writing similar gen_server or gen_statem boilerplate repeatedly.
  • You want to enforce a specific pattern or interface across multiple components.
  • You need to provide a simpler, higher-level API for a complex underlying process.
  • You are building a reusable library or framework component.

Quick Check

You've learned about custom OTP behaviors. Let's test your understanding.

Recap & Next Steps

You've explored the world of custom OTP behaviors!

  • We saw that custom behaviors allow you to encapsulate common patterns.
  • They typically consist of a **behavior module** (public API) and a **callback module** (logic).
  • By wrapping existing behaviors like gen_server, you can create powerful, reusable components.

Mastering custom behaviors empowers you to build highly modular and consistent Erlang applications.

เริ่มต้นได้ฟรี

เรียนรู้ Erlang ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
12
บทเรียน
48

คำถามที่พบบ่อย

บทเรียน “พฤติกรรม OTP แบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “พฤติกรรม OTP แบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Erlang OTP: Distributed & Fault-Tolerant Systems Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Erlang OTP: Distributed & Fault-Tolerant Systems Programming มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “พฤติกรรม OTP แบบกำหนดเอง”

ทำความเข้าใจโครงสร้างของพฤติกรรม OTP และวิธีสร้างพฤติกรรมทั่วไปแบบกำหนดเองเพื่อห่อหุ้มรูปแบบการทำงานที่ใช้ร่วมกัน คุณปฏิบัติ Erlang OTP: Distributed & Fault-Tolerant Systems Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Erlang OTP: Distributed & Fault-Tolerant Systems Programming หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Erlang OTP: Distributed & Fault-Tolerant Systems Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “พฤติกรรม OTP แบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Erlang OTP: Distributed & Fault-Tolerant Systems Programming นี้ได้ไหม

ได้ บทเรียน Erlang OTP: Distributed & Fault-Tolerant Systems Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. GenStatem สำหรับการจัดการสถานะ
  2. GenEvent สำหรับการจัดการเหตุการณ์
  3. พฤติกรรม OTP แบบกำหนดเอง
  4. การสลับโค้ดแบบร้อนและการอัปเกรดขณะทำงาน
← กลับไปที่ Erlang OTP: Distributed & Fault-Tolerant Systems Programming