อินเตอร์เฟสที่เปิดเผย async ทำหน้าที่เป็นนามธรรมหรือไม่?


13

ฉันกำลังอ่านหนังสือหลักการพึ่งพาวิธีปฏิบัติและรูปแบบการพึ่งพาหนังสือและฉันอ่านเกี่ยวกับแนวคิดของสิ่งที่เป็นนามธรรมซึ่งอธิบายไว้ในหนังสือ

วันนี้ฉันกำลังสร้างฐานรหัส C # ขึ้นใหม่โดยใช้การฉีดอ้างอิงเพื่อให้มีการใช้การโทรแบบ async แทนการบล็อก การทำเช่นนี้ฉันกำลังพิจารณาอินเทอร์เฟซบางตัวที่เป็นนามธรรมในรหัสฐานของฉันและต้องได้รับการออกแบบใหม่เพื่อให้สามารถใช้การโทรแบบ async ได้

เป็นตัวอย่างให้พิจารณาอินเตอร์เฟสต่อไปนี้ที่แสดงถึงที่เก็บสำหรับผู้ใช้แอ็พพลิเคชัน:

public interface IUserRepository 
{
  Task<IEnumerable<User>> GetAllAsync();
}

ตามคำนิยามของหนังสือสิ่งที่เป็นนามธรรมคือสิ่งที่เป็นนามธรรมที่ได้รับการออกแบบมาโดยเฉพาะในใจนามธรรมเพื่อให้รายละเอียดของการดำเนินการ "รั่ว" ผ่านสิ่งที่เป็นนามธรรมเอง

คำถามของฉันมีดังต่อไปนี้: เราสามารถพิจารณาอินเทอร์เฟซที่ออกแบบโดยคำนึงถึง async เช่น IUserRepository เป็นตัวอย่างของ Leaky Abstraction ได้หรือไม่?

แน่นอนว่าการใช้งานที่เป็นไปไม่ได้ทั้งหมดมีบางอย่างที่เกี่ยวข้องกับ asynchrony: มีเพียงการติดตั้งแบบไม่ใช้กระบวนการ (เช่นการใช้ SQL) แต่การเก็บข้อมูลในหน่วยความจำไม่จำเป็นต้องใช้แบบอะซิงโครนัส ยากถ้าอินเทอร์เฟซถูกเปิดเผยเมธอด async ตัวอย่างเช่นคุณอาจต้องส่งคืนสิ่งที่ต้องการเช่น Task.CompletedTask หรือ Task.FromResult (ผู้ใช้) ในการประยุกต์ใช้เมธอด)

คุณคิดยังไงเกี่ยวกับที่ ?


@ ไม่มีฉันอาจได้รับจุด อินเทอร์เฟซที่เปิดเผยวิธีการส่งคืนงานหรืองาน <T> ไม่ใช่สิ่งที่เป็นนามธรรมรั่วไหลต่อ se เป็นเพียงสัญญาที่มีลายเซ็นที่เกี่ยวข้องกับงาน วิธีการส่งคืนงานหรืองาน <T> ไม่ได้หมายความว่ามีการใช้งาน async (ตัวอย่างเช่นถ้าฉันสร้างงานที่เสร็จสมบูรณ์โดยใช้ Task.CompletedTask ฉันไม่ได้ใช้งาน async) ในทางกลับกันการใช้งาน async ใน C # กำหนดว่าประเภทการส่งคืนของวิธีการซิงค์จะต้องเป็นประเภทงานหรืองาน <T> ใส่อีกวิธีหนึ่งที่ "รั่วไหล" กว้างยาวของอินเทอร์เฟซของฉันคือส่วนต่อท้ายแบบ async ในชื่อ
Enrico Massone

@Neil จริงๆแล้วมีแนวทางการตั้งชื่อซึ่งระบุว่าวิธีการ async ทั้งหมดควรมีชื่อลงท้ายด้วย "Async" แต่นี่ไม่ได้หมายความว่าวิธีการส่งคืนภารกิจหรือภารกิจ <T> จะต้องตั้งชื่อด้วยส่วนต่อท้าย Async เพราะสามารถนำไปใช้งานได้โดยไม่ต้องใช้การโทรแบบ async
Enrico Massone

6
ฉันจะยืนยันว่า 'asyncness Taskของวิธีการที่จะแสดงโดยข้อเท็จจริงที่ว่ามันส่งกลับ แนวทางสำหรับการซิงโครไนซ์วิธี async ด้วยคำว่า async คือการแยกแยะระหว่างการเรียก API ที่เหมือนกัน ที่ บริษัท ของเราเราทิ้งมันทั้งหมดไว้ด้วยกัน
richzilla

มีจำนวนคำตอบและความคิดเห็นที่อธิบายว่าทำไมธรรมชาติของวิธีการแบบอะซิงโครนัสจึงเป็นส่วนหนึ่งของสิ่งที่เป็นนามธรรม คำถามที่น่าสนใจมากขึ้นก็คือภาษาหรือการเขียนโปรแกรม API สามารถแยกการทำงานของวิธีการจากวิธีการดำเนินการไปยังจุดที่เราไม่ต้องการค่างานคืนหรือเครื่องหมาย async อีกต่อไป? คนเขียนโปรแกรมที่ใช้งานได้ดูเหมือนจะคิดได้ดีกว่านี้ พิจารณาว่ามีการกำหนดวิธีการแบบอะซิงโครนัสในภาษา F # และภาษาอื่น ๆ อย่างไร
Frank Hileman

2
:-) -> "คนเขียนโปรแกรมที่ใช้งานได้" ฮ่า Async ไม่รั่วไหลมากกว่าแบบซิงโครนัสดูเหมือนเป็นเช่นนั้นเพราะเราคุ้นเคยกับการเขียนรหัสการซิงค์โดยค่าเริ่มต้น หากเราทุกคนเข้ารหัส async โดยค่าเริ่มต้นฟังก์ชั่นซิงโครนัสอาจดูเหมือนรั่ว
StarTrekRedneck

คำตอบ:


8

แน่นอนหนึ่งสามารถเรียกใช้กฎหมายของ abstractions รั่วแต่นั่นไม่น่าสนใจโดยเฉพาะอย่างยิ่งเพราะมัน posits ว่า abstractions ทั้งหมดมีการรั่วไหล หนึ่งสามารถยืนยันและต่อต้านการคาดเดาว่า แต่มันก็ไม่ได้ช่วยถ้าเราไม่แบ่งปันความเข้าใจในสิ่งที่เราหมายถึงโดยที่เป็นนามธรรมและสิ่งที่เราหมายถึงโดยรั่ว ดังนั้นก่อนอื่นฉันจะพยายามอธิบายวิธีที่ฉันดูแต่ละคำเหล่านี้:

นามธรรม

คำนิยามที่ชื่นชอบของabstractionsมาจากAPPPของ Robert C. Martin :

"สิ่งที่เป็นนามธรรมคือการขยายความสำคัญและการกำจัดสิ่งที่ไม่เกี่ยวข้อง"

ดังนั้นการเชื่อมต่อไม่ได้ในตัวเองนามธรรม พวกเขาเป็นเพียงนามธรรมถ้าพวกเขานำสิ่งที่สำคัญและซ่อนส่วนที่เหลือ

รั่ว

หนังสือหลักการการพึ่งพาการพึ่งพารูปแบบและวิธีปฏิบัติในการกำหนดคำศัพท์ที่เป็นนามธรรมรั่วในบริบทของการพึ่งพาการฉีด (DI) ความแตกต่างและหลักการ SOLID มีบทบาทสำคัญในบริบทนี้

จากหลักการผกผันอ้างอิง (DIP) หลักการดังต่อไปนี้อ้าง APPP อีกครั้งว่า:

"ลูกค้า [... ] เป็นเจ้าของอินเทอร์เฟซแบบนามธรรม"

สิ่งนี้หมายถึงว่าลูกค้า (รหัสโทร) กำหนด abstractions ที่พวกเขาต้องการแล้วคุณไปและใช้นามธรรมที่

นามธรรมรั่วในมุมมองของฉันเป็นนามธรรมที่ละเมิดทรัพย์สินทางปัญญาโดยการอย่างใดรวมทั้งฟังก์ชั่นบางอย่างที่ลูกค้าไม่ได้เป็นความจำเป็น

การพึ่งพาแบบซิงโครนัส

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

พิจารณาวัตถุโดเมนที่จัดการคำขอจองร้านอาหาร:

public class MaîtreD : IMaîtreD
{
    public MaîtreD(int capacity, IReservationsRepository repository)
    {
        Capacity = capacity;
        Repository = repository;
    }

    public int Capacity { get; }
    public IReservationsRepository Repository { get; }

    public int? TryAccept(Reservation reservation)
    {
        var reservations = Repository.ReadReservations(reservation.Date);
        int reservedSeats = reservations.Sum(r => r.Quantity);

        if (Capacity < reservedSeats + reservation.Quantity)
            return null;

        reservation.IsAccepted = true;
        return Repository.Create(reservation);
    }
}

นี่IReservationsRepositoryพึ่งพาจะถูกกำหนดโดยเฉพาะโดยลูกค้าที่MaîtreDระดับ:

public interface IReservationsRepository
{
    Reservation[] ReadReservations(DateTimeOffset date);
    int Create(Reservation reservation);
}

อินเทอร์เฟซนี้จะซิงโครนัสทั้งหมดเนื่องจากMaîtreDคลาสไม่ต้องการให้เป็นแบบอะซิงโครนัส

การพึ่งพาแบบอะซิงโครนัส

คุณสามารถเปลี่ยนอินเตอร์เฟสเป็นแบบอะซิงโครนัสได้อย่างง่ายดาย:

public interface IReservationsRepository
{
    Task<Reservation[]> ReadReservations(DateTimeOffset date);
    Task<int> Create(Reservation reservation);
}

อย่างไรก็ตามMaîtreDคลาสไม่ต้องการวิธีการเหล่านั้นแบบอะซิงโครนัสดังนั้นตอนนี้กรมทรัพย์สินทางปัญญาถูกละเมิด ฉันถือว่าสิ่งนี้เป็นนามธรรมที่ไม่น่าเชื่อเพราะรายละเอียดการใช้งานบังคับให้ลูกค้าเปลี่ยน TryAcceptวิธีการในขณะนี้นอกจากนี้ยังมีที่จะกลายเป็นไม่ตรงกัน:

public async Task<int?> TryAccept(Reservation reservation)
{
    var reservations =
        await Repository.ReadReservations(reservation.Date);
    int reservedSeats = reservations.Sum(r => r.Quantity);

    if (Capacity < reservedSeats + reservation.Quantity)
        return null;

    reservation.IsAccepted = true;
    return await Repository.Create(reservation);
}

ไม่มีเหตุผลโดยธรรมชาติสำหรับตรรกะโดเมนที่จะไม่ตรงกัน แต่เพื่อสนับสนุนการไม่ตรงกันของการดำเนินการนี้จำเป็นต้องใช้ในขณะนี้

ตัวเลือกที่ดีกว่า

ที่ NDC Sydney 2018 ฉันได้พูดคุยในหัวข้อนี้ ในนั้นฉันยังร่างทางเลือกที่ไม่รั่วไหล ฉันจะให้พูดคุยในที่ประชุมในหลาย 2019 เช่นกัน แต่ตอนนี้แบรนที่มีชื่อใหม่ของการฉีด Async

ฉันวางแผนที่จะเผยแพร่โพสต์ในบล็อกหลายชุดเพื่อติดตามการพูดคุยด้วย บทความเหล่านี้เขียนแล้วและนั่งอยู่ในคิวบทความของฉันรอการเผยแพร่ดังนั้นคอยติดตาม


ในใจของฉันนี่เป็นเรื่องของความตั้งใจ หากสิ่งที่เป็นนามธรรมของฉันปรากฏขึ้นราวกับว่ามันควรทำตัวแบบเดียว แต่รายละเอียดหรือข้อ จำกัด บางอย่างทำให้สิ่งที่เป็นนามธรรมดังที่แสดงนั่นเป็นสิ่งที่เป็นนามธรรม แต่ในกรณีนี้ฉันแสดงให้คุณเห็นอย่างชัดเจนว่าการดำเนินการแบบอะซิงโครนัส - นั่นไม่ใช่สิ่งที่ฉันพยายามสรุป ที่แตกต่างในใจของฉันจากตัวอย่างของคุณที่ฉัน (อย่างชาญฉลาดหรือไม่) พยายามสรุปความจริงที่ว่ามีฐานข้อมูล SQL และฉันยังเปิดเผยสตริงการเชื่อมต่อ อาจเป็นเรื่องของความหมาย / มุมมอง
Ant P

ดังนั้นเราจึงสามารถพูดได้ว่าสิ่งที่เป็นนามธรรมไม่เคยรั่ว "ต่อ se" แต่มันก็เป็นสิ่งที่รั่วถ้ารายละเอียดของการใช้งานเฉพาะอย่างใดอย่างหนึ่งรั่วไหลออกมาจากสมาชิกที่เปิดเผยและ จำกัด ผู้บริโภคให้เปลี่ยนการใช้งานของมัน .
Enrico Massone

2
น่าสนใจพอประเด็นที่คุณเน้นไว้ในคำอธิบายของคุณเป็นหนึ่งในจุดที่เข้าใจผิดมากที่สุดของเรื่องราวการฉีดพึ่งพาทั้งหมด บางครั้งนักพัฒนาก็ลืมหลักการผกผันของการพึ่งพาและพยายามออกแบบสิ่งที่เป็นนามธรรมก่อนแล้วจึงปรับการออกแบบผู้บริโภคเพื่อรับมือกับสิ่งที่เป็นนามธรรม กระบวนการควรทำในลำดับกลับกันแทน
Enrico Massone

11

มันไม่ใช่สิ่งที่เป็นนามธรรมรั่วไหลเลย

การอะซิงโครนัสเป็นการเปลี่ยนแปลงพื้นฐานของคำจำกัดความของฟังก์ชั่น - หมายถึงงานไม่เสร็จสิ้นเมื่อการโทรกลับมา แต่ก็หมายความว่าการไหลของโปรแกรมของคุณจะดำเนินต่อไปเกือบจะทันทีโดยไม่ล่าช้า ฟังก์ชันแบบอะซิงโครนัสและซิงโครนัสที่ทำหน้าที่เดียวกันนั้นเป็นฟังก์ชั่นที่แตกต่างกัน การเป็นแบบอะซิงโครนัสไม่ใช่รายละเอียดการใช้งาน มันเป็นส่วนหนึ่งของนิยามของฟังก์ชั่น

หากฟังก์ชั่นเปิดเผยวิธีการทำงานของอะซิงโครนัสนั้นจะรั่ว คุณ (ไม่ต้อง / ไม่ควร) สนใจว่าจะใช้งานอย่างไร


5

asyncแอตทริบิวต์ของวิธีการเป็นแท็กที่บ่งชี้ว่าการดูแลโดยเฉพาะและการจัดการที่ถูกต้อง เช่นนี้จะต้องรั่วไหลออกสู่โลก การดำเนินการแบบอะซิงโครนัสนั้นยากมากในการเขียนอย่างถูกต้องดังนั้นการให้ผู้ใช้ API จึงเป็นสิ่งสำคัญ

หากห้องสมุดของคุณจัดการกิจกรรมอะซิงโครนัสทั้งหมดภายในตัวเองอย่างถูกต้องคุณอาจไม่สามารถasync" ปล่อย" ออกจาก API

ซอฟต์แวร์มีสี่มิติของความยาก: ข้อมูลการควบคุมพื้นที่และเวลา การทำงานแบบอะซิงโครนัสครอบคลุมทั้งสี่มิติดังนั้นจึงจำเป็นต้องได้รับการดูแลมากที่สุด


ฉันเห็นด้วยกับความรู้สึกของคุณ แต่ "การรั่วไหล" หมายถึงสิ่งที่ไม่ดีซึ่งเป็นเจตนาของคำว่า "การรั่วซึมนามธรรม" - สิ่งที่ไม่พึงประสงค์ในสิ่งที่เป็นนามธรรม ในกรณีของการซิงค์กับซิงค์ไม่มีการรั่วไหล
StarTrekRedneck

2

สิ่งที่เป็นนามธรรมคือสิ่งที่เป็นนามธรรมที่ได้รับการออกแบบมาโดยเฉพาะในใจนามธรรมเพื่อให้รายละเอียดการดำเนินการ "รั่ว" ผ่านสิ่งที่เป็นนามธรรม

ไม่มาก นามธรรมเป็นสิ่งที่มีแนวคิดที่จะไม่สนใจองค์ประกอบบางอย่างของสิ่งที่เป็นรูปธรรมหรือปัญหาที่ซับซ้อนมากขึ้น เช่นนี้มันจำเป็นต้องแตกต่างจากสิ่งที่เป็นปัญหาจริงและดังนั้นจึงจะรั่วในบางส่วนของกรณี (กล่าวคือ abstractions ทั้งหมดจะรั่วคำถามเดียวคือขอบเขต - ความหมายซึ่งในกรณีที่เป็นนามธรรม มีประโยชน์สำหรับเราโดเมนของความเกี่ยวข้องคืออะไร)

เมื่อกล่าวถึงซอฟต์แวร์นามธรรมบางครั้ง (หรืออาจจะเพียงพอหรือไม่) รายละเอียดที่เราเลือกที่จะเพิกเฉยไม่สามารถเพิกเฉยได้จริงเพราะมันส่งผลกระทบต่อบางแง่มุมของซอฟต์แวร์ที่มีความสำคัญต่อเรา (ประสิทธิภาพการบำรุงรักษา ... ) . ดังนั้นสิ่งที่เป็นนามธรรมคือสิ่งที่เป็นนามธรรมถูกออกแบบมาเพื่อละเว้นรายละเอียด (ภายใต้สมมติฐานว่ามันเป็นไปได้และมีประโยชน์ที่จะทำ) แต่แล้วมันกลับกลายเป็นว่ารายละเอียดเหล่านั้นมีความสำคัญในทางปฏิบัติ (พวกเขาไม่สามารถเพิกเฉย "รั่วไหล").

ดังนั้นอินเทอร์เฟซที่เปิดเผยรายละเอียดของการใช้งานจะไม่รั่วไหลต่อ (หรือมากกว่านั้นอินเทอร์เฟซที่ดูในการแยกไม่ได้อยู่ในตัวของมันเองนามธรรมรั่ว); แทนสิ่งที่รั่วนั้นขึ้นอยู่กับรหัสที่ใช้อินเทอร์เฟซ (มันสามารถรองรับสิ่งที่เป็นนามธรรมแทนโดยอินเทอร์เฟซ) และบนสมมติฐานที่ทำโดยรหัสลูกค้า (ซึ่งเป็นจำนวนนามธรรมแนวคิดที่เติมเต็มหนึ่งแสดงโดย อินเทอร์เฟซ แต่ไม่สามารถแสดงเป็นรหัสได้ (เช่นคุณสมบัติของภาษานั้นไม่สามารถแสดงออกได้เพียงพอดังนั้นเราอาจอธิบายได้ในเอกสาร ฯลฯ )


2

ลองพิจารณาตัวอย่างต่อไปนี้:

นี่คือวิธีการตั้งชื่อก่อนที่จะส่งคืน:

public void SetName(string name)
{
    _dataLayer.SetName(name);
}

นี่คือวิธีการที่ตั้งชื่อ ผู้เรียกไม่สามารถสันนิษฐานได้ว่าตั้งชื่อไว้จนกว่างานที่ส่งคืนจะเสร็จสมบูรณ์ ( IsCompleted= จริง):

public Task SetName(string name)
{
    return _dataLayer.SetNameAsync(name);
}

นี่คือวิธีการที่ตั้งชื่อ ผู้เรียกไม่สามารถสันนิษฐานได้ว่าตั้งชื่อไว้จนกว่างานที่ส่งคืนจะเสร็จสมบูรณ์ ( IsCompleted= จริง):

public async Task SetName(string name)
{
    await _dataLayer.SetNameAsync(name);
}

ถาม: อันไหนไม่ได้อยู่กับอีกสองอัน

ตอบ: วิธีการซิงค์ไม่ใช่วิธีเดียวที่ยืนอยู่คนเดียว คนที่ยืนอยู่คนเดียวเป็นวิธีการที่ส่งกลับเป็นโมฆะ

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

ดังนั้นไม่ฉันไม่คิดว่าการเปิดตัวของasyncรูปแบบเป็นนามธรรมที่น่าสนใจในตัวของมันเอง แต่คุณอาจต้องเปลี่ยนต้นแบบเพื่อส่งคืนภารกิจซึ่ง "รั่วไหล" โดยการเปลี่ยนอินเทอร์เฟซ (นามธรรม) และเนื่องจากเป็นส่วนหนึ่งของสิ่งที่เป็นนามธรรมจึงไม่ใช่การรั่วไหลตามคำจำกัดความ


0

นี่เป็นสิ่งที่เป็นนามธรรมหากคุณไม่ต้องการใช้คลาสทั้งหมดในการสร้างการโทรแบบอะซิงโครนัส คุณสามารถสร้างการใช้งานได้หลายแบบตัวอย่างเช่นประเภทหนึ่งสำหรับแต่ละประเภทฐานข้อมูลที่คุณสนับสนุนและนี่ก็ถือว่าโอเคอย่างสมบูรณ์ถ้าคุณไม่จำเป็นต้องรู้ว่ามีการใช้งานที่แน่นอนตลอดทั้งโปรแกรมของคุณ

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


0

นี่คือมุมมองของฝ่ายตรงข้าม

เราไม่ได้ไปกลับFooไปกลับมาTask<Foo>เพราะเราเริ่มต้นที่ต้องการแทนเพียงTask Fooจริงอยู่ที่บางครั้งเรามีปฏิสัมพันธ์กับแต่ในรหัสที่แท้จริงของโลกมากที่สุดที่เราไม่สนใจมันและเพียงแค่ใช้TaskFoo

ยิ่งไปกว่านั้นเรามักจะกำหนดอินเทอร์เฟซเพื่อสนับสนุนการทำงานแบบอะซิงโครนัสแม้ในขณะที่การนำไปใช้อาจไม่ตรงกัน

อินเทอร์เฟซที่ส่งกลับค่า a Task<Foo>จะบอกคุณว่าการใช้งานนั้นอาจไม่ตรงกันหรือไม่ก็ตามแม้ว่าคุณจะสนใจหรือไม่สนใจก็ตาม หากสิ่งที่เป็นนามธรรมบอกเรามากกว่าที่เราต้องรู้เกี่ยวกับการนำไปปฏิบัติมันก็รั่ว

หากการใช้งานของเราไม่เป็นแบบอะซิงโครนัสเราจะเปลี่ยนเป็นแบบอะซิงโครนัสจากนั้นเราต้องเปลี่ยนสิ่งที่เป็นนามธรรมและทุกอย่างที่ใช้มันเป็นสิ่งที่เป็นนามธรรมมาก

นั่นไม่ใช่การตัดสิน อย่างที่คนอื่น ๆ ชี้ไป abstractions ทั้งหมดรั่วไหล อันนี้มีผลกระทบมากขึ้นเพราะมันจำเป็นต้องมีผลกระทบระลอกคลื่นของ async / รอตลอดทั้งรหัสของเราเพียงเพราะที่ไหนสักแห่งในตอนท้ายของมันอาจมีบางสิ่งที่เป็นจริงไม่ตรงกัน

เสียงนั้นเป็นคำร้องเรียนหรือไม่? นั่นไม่ใช่ความตั้งใจของฉัน แต่ฉันคิดว่ามันเป็นการสังเกตที่แม่นยำ

จุดที่เกี่ยวข้องคือการยืนยันว่า "อินเทอร์เฟซไม่ใช่สิ่งที่เป็นนามธรรม" สิ่งที่ Mark Seeman กล่าวไว้อย่างชัดเจนนั้นถูกทารุณกรรมเพียงเล็กน้อย

คำจำกัดความของ "abstraction" ไม่ใช่ "interface" แม้ใน. NET บทคัดย่อสามารถมีได้หลายรูปแบบ อินเทอร์เฟซอาจเป็นนามธรรมที่ไม่ดีหรือมันสามารถสะท้อนการใช้งานของมันอย่างใกล้ชิดดังนั้นในแง่ที่มันแทบจะไม่เป็นนามธรรมเลย

แต่เราใช้อินเทอร์เฟซเพื่อสร้างบทคัดย่อ ดังนั้นการโยน "อินเทอร์เฟซไม่ใช่ abstractions" เนื่องจากคำถามที่กล่าวถึงอินเทอร์เฟซและ abstractions ไม่ได้ตรัสรู้


-2

อะซิงก์GetAllAsync()จริงหรือ ฉันหมายความว่า "async" อยู่ในชื่อ แต่สามารถลบออกได้ ดังนั้นฉันจึงถามอีกครั้ง ... เป็นไปไม่ได้ที่จะใช้ฟังก์ชั่นที่คืนค่าTask<IEnumerable<User>>ซึ่งแก้ไขพร้อมกันหรือไม่?

ฉันไม่ทราบประเภทเฉพาะของ. Net Taskแต่ถ้ามันเป็นไปไม่ได้ที่จะใช้ฟังก์ชั่นแบบซิงโครนัสให้แน่ใจว่ามันเป็นสิ่งที่เป็นนามธรรม (ด้วยวิธีนี้) แต่ไม่เช่นนั้น ผมไม่ทราบว่าถ้ามันเป็นIObservableมากกว่างานก็อาจจะดำเนินการอย่างใดอย่างหนึ่งพร้อมกันหรือ async ดังนั้นไม่มีอะไรนอกฟังก์ชันรู้และดังนั้นจึงไม่รั่วไหลที่ความเป็นจริงโดยเฉพาะอย่างยิ่ง


Task<T> หมายถึง async คุณได้รับภารกิจของวัตถุทันที แต่อาจต้องรอลำดับของผู้ใช้
Caleth

อาจต้องรอไม่ได้หมายความว่ามันจำเป็นต้องเป็นแบบซิงค์ จะรอจะหมายถึง async สันนิษฐานว่าหากงานพื้นฐานได้รับการทำงานแล้วคุณไม่ต้องรอ
Daniel T.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.