มุมมองที่แตกต่างกันสำหรับบันทึก erlang เดียวกัน

สมมติว่าฉันมีบันทึก

-record(expense, {uuid, amount, tags}).

ฉันต้องการให้บันทึกเวอร์ชันที่แสดงได้ ฟิลด์แท็กมีรหัสเฉพาะของแท็ก ฉันต้องการแสดงชื่อแท็กในแบบฟอร์มแทนรหัสเฉพาะ คุณจะทำอย่างไรใน Erlang? โดยปกติแล้ว ในภาษา OOP คุณจะต้องทำ ViewModel เพื่อให้มีเวอร์ชันที่แตกต่างกันของออบเจ็กต์เดียวกันที่สามารถแสดงผลได้

ตัวเลือกที่ 1 ใช้บันทึกเดียวกันกับรูปแบบข้อมูลที่แตกต่างกัน แต่ฉันคิดว่ามันจะทำให้สัญญาอินเทอร์เฟซเสียหาย เราจะไม่สามารถรู้ได้ว่ามีบันทึกเวอร์ชันใด

ตัวเลือกที่ 2 สร้างบันทึกอื่น

-record(expense_view1, {uuid, amount, tags}).

แต่มันจะสร้างบันทึกที่ซ้ำซ้อนมากมาย

ตัวเลือกที่ 3 ใช้สิ่งอันดับหรือแผนที่ Tuple นั้นรักษาได้ยากหากฉันเพิ่มฟิลด์ลงในบันทึก และแผนที่ไม่รับประกันความปลอดภัยของชื่อฟิลด์


person user2187032    schedule 15.02.2021    source แหล่งที่มา


คำตอบ (2)


ฟิลด์แท็กมีรหัสเฉพาะของแท็ก ฉันต้องการแสดงชื่อแท็กในแบบฟอร์มแทนรหัสเฉพาะ

เป็นอย่างไรบ้าง:

-module(a).
-compile(export_all).

-record(expense, {uuid, amount, tags}).

show_action(#expense{uuid=UUID, amount=Amount, tags={A, B, C} }) ->
    TagConversions= #{1 => "Joe", 2 => "Tammy", 3 => "Bob"},
    A_Conv = maps:get(A, TagConversions, "Nathan"),
    B_Conv = maps:get(B, TagConversions, "Nathan"),
    C_Conv = maps:get(C, TagConversions, "Nathan"),
    io:format("~w, ~w, {~s,~s,~s}~n", 
              [UUID, Amount, A_Conv, B_Conv, C_Conv]).


go() ->
    Expense1 = #expense{uuid=1, amount=10, tags={1,2,3} },
    show_action(Expense1).

ในเปลือก:

12> c(a).  
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

13> a:go().
1, 10, {Joe,Tammy,Bob}
ok

ฉันต้องการให้บันทึกเวอร์ชันที่แสดงได้ แต่มันจะสร้างบันทึกที่ซ้ำซ้อนมากมาย

ใช่ แต่ใน OOP คุณไม่มีการแพร่กระจายของออบเจ็กต์ View ที่มีข้อมูลทั้งหมดหรือชุดย่อยในออบเจ็กต์ Model ใช่หรือไม่

ตัวเลือกที่ 1 ใช้บันทึกเดียวกันกับรูปแบบข้อมูลที่แตกต่างกัน แต่ฉันคิดว่ามันจะทำให้สัญญาอินเทอร์เฟซเสียหาย เราจะไม่สามารถรู้ได้ว่ามีบันทึกเวอร์ชันใด

คุณสามารถจัดโครงสร้างเรคคอร์ดโดยเว้นจุดว่างไว้สำหรับชื่อแท็กที่สอดคล้องกับรหัสแท็ก จากนั้นกรอกชื่อแท็กเมื่อคุณสามารถ:

-module(a).
-compile(export_all).

-record(tag, {id, name=""}).
-record(expense, {uuid, amount, tags}).

show_action(Expense = #expense{uuid=UUID, amount=Amount, tags={A, B, C} }) ->
    TagConversions= #{1 => "Joe", 2 => "Tammy", 3 => "Bob"},
    A_Conv = maps:get(A#tag.id, TagConversions, "Nathan"),
    B_Conv = maps:get(B#tag.id, TagConversions, "Nathan"),
    C_Conv = maps:get(C#tag.id, TagConversions, "Nathan"),
    io:format("~w, ~w, {~s,~s,~s}~n", 
              [UUID, Amount, A_Conv, B_Conv, C_Conv]),

    Expense#expense{tags={
                      A#tag{name=A_Conv},
                      B#tag{name=B_Conv},
                      C#tag{name=C_Conv}
                     }}.
go() ->

    Expense1 = #expense{uuid=1, amount=10, 
                        tags={#tag{id=1},
                              #tag{id=2},
                              #tag{id=3} }
                       },

    show_action(Expense1).

ในเปลือก:

5> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

6> a:go().
1, 10, {Joe,Tammy,Bob}
{expense,1,10,{{tag,1,"Joe"},{tag,2,"Tammy"},{tag,3,"Bob"}}}
person 7stud    schedule 15.02.2021

คุณสามารถเลือกโหมดมุมมองในฟังก์ชันการเข้าถึง:

-module (tuple).

-export ([get/1,get/2,start/0,stop/0]).


-record(expense, {uuid, amount, tags}).

%%%%%%%%% Interfaces %%%%%%%%%

% start the server with a static map
start() ->
    Pid =spawn(fun() -> loop(#{1 => one, 2 => two, 3 => three}) end),
    register(server, Pid).

stop() ->
    server ! stop.

% By default for "external users" get the view with value
get(T) ->
    get(T,value).

% for "internal usage" it is possible to choose either the id view or the value view
get(T,value) ->
    Values = lists:map(fun get_value/1, T#expense.tags),
    T#expense{tags = Values};
get(T,id) ->
    T.

%%%%%%%%% server %%%%%%%%%%
% the server is in charge to store the id => value association
% it could be also stored in an ETS, a database ...
loop(Ids) ->
    receive
        stop ->
            done;
        {From, get_value, Id} ->
            % the choice is made to do not crash if the id does not exist
            From ! {ok,maps:get(Id, Ids, undefined)},
            loop(Ids)
    end.

%%%%%%%%% private %%%%%%%%%

get_value(Id) ->
    server ! {self(), get_value, Id},
    receive
        {ok,Value} ->
            Value
    end.

ซึ่งให้ในเปลือก:

1> c(tuple).                                                  
{ok,tuple}
2> rr(tuple).                                                 
[expense]
3> T = #expense{uuid = 12345, amount = 20000, tags = [1,3,4]}.
#expense{uuid = 12345,amount = 20000,tags = [1,3,4]}
4> tuple:start().                                             
true
5> tuple:get(T).                                              
#expense{uuid = 12345,amount = 20000,
         tags = [one,three,undefined]}
6> tuple:get(T,value).
#expense{uuid = 12345,amount = 20000,
         tags = [one,three,undefined]}
7> tuple:get(T,id).   
#expense{uuid = 12345,amount = 20000,tags = [1,3,4]}
8> tuple:stop().
stop
person Pascal    schedule 16.02.2021