การออกแบบที่เหมาะสมสำหรับชั้นเรียนด้วยวิธีการหนึ่งที่สามารถแตกต่างกันระหว่างลูกค้า


12

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

ฉันสามารถเขียนรหัสน่าเกลียดที่เปลี่ยนตาม customerID:

switch(customerID) {
 case 101:
  .. do calculations for customer 101
 case 102:
  .. do calculations for customer 102
 case 103:
  .. do calculations for customer 103
 etc
}

แต่สิ่งนี้ต้องการการสร้างคลาสใหม่ทุกครั้งที่เราได้ลูกค้าใหม่ อะไรคือวิธีที่ดีกว่า

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


[แก้ไข] ฉันตัดสินใจเลือกคำตอบอันดับต้น ๆ (สร้างคลาส "ลูกค้า" แยกต่างหากสำหรับลูกค้าแต่ละรายที่ใช้อินเทอร์เฟซมาตรฐาน) ด้วยเหตุผลดังต่อไปนี้:

  1. ความสอดคล้อง: ฉันสามารถสร้างอินเทอร์เฟซที่สร้างความมั่นใจว่าลูกค้าทุกระดับจะได้รับและส่งคืนผลลัพธ์เดียวกันแม้ว่าจะสร้างโดยนักพัฒนาคนอื่น

  2. การบำรุงรักษา: รหัสทั้งหมดจะถูกเขียนในภาษาเดียวกัน (Java) ดังนั้นจึงไม่จำเป็นต้องให้คนอื่นเรียนรู้ภาษาการเข้ารหัสที่แยกต่างหากเพื่อรักษาสิ่งที่ควรจะเป็นคุณลักษณะที่ง่ายตาย

  3. การใช้ซ้ำ: ในกรณีที่เกิดปัญหาที่คล้ายกันในรหัสฉันสามารถใช้คลาสลูกค้าเพื่อเก็บวิธีการใด ๆ เพื่อใช้ตรรกะ "กำหนดเอง"

  4. ความคุ้นเคย: ฉันรู้วิธีการทำสิ่งนี้อยู่แล้วดังนั้นฉันจึงสามารถทำมันได้อย่างรวดเร็วและไปยังประเด็นอื่นที่เร่งด่วนกว่า

ข้อเสีย:

  1. ลูกค้าใหม่แต่ละรายต้องการการรวบรวมคลาสลูกค้าใหม่ซึ่งอาจเพิ่มความซับซ้อนให้กับวิธีการที่เรารวบรวมและปรับใช้การเปลี่ยนแปลง

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

  3. มันจะขยายขนาดไม่ได้หากเราเพิ่มลูกค้าใหม่จำนวนมาก สิ่งนี้ไม่ได้คาดหวัง แต่ถ้ามันเกิดขึ้นเราจะต้องคิดใหม่อีกหลายส่วนของรหัสเช่นนี้

สำหรับผู้ที่คุณสนใจคุณสามารถใช้ Java Reflection เพื่อโทรหาชั้นเรียนตามชื่อ:

Payment payment = getPaymentFromSomewhere();

try {
    String nameOfCustomClass = propertiesFile.get("customClassName");
    Class<?> cpp = Class.forName(nameOfCustomClass);
    CustomPaymentProcess pp = (CustomPaymentProcess) cpp.newInstance();

    payment = pp.processPayment(payment);
} catch (Exception e) {
    //handle the various exceptions
} 

doSomethingElseWithThePayment(payment);

1
บางทีคุณควรอธิบายรายละเอียดเกี่ยวกับประเภทของการคำนวณ มันเป็นเพียงการคืนเงินที่ถูกคำนวณหรือเป็นกระบวนการทำงานที่แตกต่างกันหรือไม่?
qwerty_so

@ThomasKilian มันเป็นเพียงตัวอย่าง ลองนึกภาพวัตถุการชำระเงินและการคำนวณสามารถเป็นเช่น "ทวีคูณการชำระเงินเปอร์เซ็นต์โดย Payment.total - แต่ไม่ใช่ถ้า Payment.id เริ่มต้นด้วย" R " มีความละเอียดเท่าไร ลูกค้าทุกคนมีกฎของตัวเอง
แอนดรู


คุณเคยลองสิ่งนี้ไหม การตั้งค่าสูตรที่แตกต่างกันสำหรับลูกค้าแต่ละราย
2559

1
ปลั๊กอินที่แนะนำจากคำตอบที่หลากหลายจะใช้งานได้เฉพาะเมื่อคุณมีผลิตภัณฑ์เฉพาะสำหรับลูกค้าเท่านั้น หากคุณมีโซลูชันเซิร์ฟเวอร์ที่คุณตรวจสอบรหัสลูกค้าแบบไดนามิกมันจะไม่ทำงาน ดังนั้นสภาพแวดล้อมของคุณคืออะไร?
qwerty_so

คำตอบ:


14

ฉันมีชั้นเรียนที่ใช้ในการประมวลผลการชำระเงินของลูกค้า ทั้งหมดยกเว้นหนึ่งในวิธีการของคลาสนี้จะเหมือนกันสำหรับลูกค้าทุกคนยกเว้นวิธีที่คำนวณ (ตัวอย่าง) จำนวนผู้ใช้ของลูกค้าที่ค้างชำระ

สองทางเลือกที่อยู่ในใจของฉัน

ตัวเลือกที่ 1: ทำให้คลาสของคุณเป็นคลาสนามธรรมซึ่งวิธีที่แตกต่างกันระหว่างลูกค้าเป็นวิธีนามธรรม จากนั้นสร้างคลาสย่อยสำหรับลูกค้าแต่ละราย

ตัวเลือก 2: สร้างCustomerคลาสหรือICustomerอินเทอร์เฟซที่ประกอบด้วยตรรกะทั้งหมดขึ้นอยู่กับลูกค้า แทนที่จะให้คลาสประมวลผลการชำระเงินของคุณยอมรับรหัสลูกค้าให้ยอมรับCustomerหรือICustomerคัดค้าน เมื่อใดก็ตามที่มันจำเป็นต้องทำบางสิ่งบางอย่างขึ้นอยู่กับลูกค้าก็จะเรียกวิธีการที่เหมาะสม


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

10

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


ขอบคุณ ปลั๊กอินทำงานอย่างไรในการพูดถึงสภาพแวดล้อมของ Java? ตัวอย่างเช่นฉันต้องการเขียนสูตร "result = if (Payment.id.startsWith (" R "))? Payment.percentage * Payment.total: Payment.otherValue" บันทึกว่าเป็นคุณสมบัติสำหรับลูกค้าและแทรก ในวิธีการที่เหมาะสมหรือไม่
แอนดรู

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

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

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

4

ฉันจะไปกับชุดกฎเพื่ออธิบายการคำนวณ สามารถเก็บไว้ในที่เก็บข้อมูลใด ๆ และแก้ไขแบบไดนามิก

ทางเลือกอื่นพิจารณาสิ่งนี้:

customerOps = [oper1, oper2, ..., operN]; // array with customer specific operations
index = customerOpsIndex(customer);
customerOps[index](parms);

customerOpsIndexคำนวณดัชนีการทำงานที่ถูกต้องที่ไหน(คุณทราบว่าลูกค้าต้องการการรักษาแบบใด)


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

คุณสามารถจัดเก็บการดำเนินงานที่จะเรียกลูกค้าในอาร์เรย์และใช้รหัสลูกค้าเพื่อจัดทำดัชนี
qwerty_so

ที่ดูมีแนวโน้มมากขึ้น :)
แอนดรู

3

สิ่งที่ต้องการด้านล่าง:

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

public interface ICustomer
{
    int Calculate();
}
public class CustomerLogic101 : ICustomer
{
    public int Calculate() { return 101; }
}
public class CustomerLogic102 : ICustomer
{
    public int Calculate() { return 102; }
}

public class CustomerRepo
{
    public ICustomer GetCustomerById(
        string id)
    {
        var data;//get data from db
        if (data.logicType == "101")
        {
            return new CustomerLogic101();
        }
        if (data.logicType == "102")
        {
            return new CustomerLogic102();
        }
    }
}
public class Calculator
{
    public int CalculateCustomer(string custId)
    {
        CustomerRepo repo = new CustomerRepo();
        var cust = repo.GetCustomerById(custId);
        return cust.Calculate();
    }
}

2

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

ลองภาษาสคริปต์ฝังตัว

ตัวอย่างเช่นหากระบบของคุณอยู่ใน Java คุณสามารถฝัง JRuby จากนั้นสำหรับลูกค้าแต่ละรายจะจัดเก็บข้อมูลโค้ด Ruby ที่สอดคล้องกัน จะเป็นการดีที่บางแห่งภายใต้การควบคุมเวอร์ชันไม่ว่าจะในแบบเดียวกันหรือใน repo git ที่แยกต่างหาก จากนั้นประเมินตัวอย่างข้อมูลนั้นในบริบทของแอปพลิเคชัน Java ของคุณ JRuby สามารถเรียกใช้ฟังก์ชัน Java ใด ๆ และเข้าถึงวัตถุ Java ใด ๆ

package com.example;

import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.ScriptingContainer;

public class Main {

    private ScriptingContainer ruby;

    public static void main(String[] args) {
        new Main().run();
    }

    public void run() {
        ruby = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);
        // Assign the Java objects that you want to share
        ruby.put("main", this);
        // Execute a script (can be of any length, and taken from a file)
        Object result = ruby.runScriptlet("main.hello_world");
        // Use the result as if it were a Java object
        System.out.println(result);
    }

    public String getHelloWorld() {
        return "Hello, worlds!";
    }

}

นี่เป็นรูปแบบที่ธรรมดามาก ตัวอย่างเช่นเกมคอมพิวเตอร์จำนวนมากเขียนด้วยภาษา C ++ แต่ใช้สคริปต์ Lua แบบฝังเพื่อกำหนดพฤติกรรมของลูกค้าของคู่ต่อสู้แต่ละรายในเกม

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

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

นี่คือรหัสหลอกบางอย่าง

strategy = strategies.find { |strategy| strategy.match(customer) }
strategy.apply(customer, ...)

2
ฉันจะหลีกเลี่ยงวิธีการนี้ แนวโน้มที่จะทำให้ตัวอย่างสคริปต์เหล่านั้นทั้งหมดอยู่ใน db แล้วคุณจะสูญเสียการควบคุมแหล่งการกำหนดรุ่นและการทดสอบ
Ewan

ยุติธรรมพอสมควร พวกเขาเก็บไว้ใน repo คอมไพล์ที่ดีที่สุดหรือที่ใดก็ได้ อัปเดตคำตอบของฉันเพื่อบอกว่าตัวอย่างควรอยู่ภายใต้การควบคุมเวอร์ชัน
akuhn

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

2

ฉันจะว่ายน้ำกับปัจจุบัน

ผมจะพยายามดำเนินภาษาแสดงออกของตัวเองกับANTLR

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

ดังนั้นด้วย Antlr ความคิดคือการกำหนดภาษาของคุณเอง ที่คุณสามารถอนุญาตให้ผู้ใช้ (หรือ devs) เขียนกฎธุรกิจในภาษาดังกล่าว

การแสดงความคิดเห็นของคุณเป็นตัวอย่าง:

ฉันต้องการเขียนสูตร "result = if (Payment.id.startsWith (" R ")) หรือไม่การชำระเงินเปอร์เซ็นต์ * Payment.total: Payment.otherValue"

ด้วย EL ของคุณคุณควรระบุประโยคเช่น:

If paymentID startWith 'R' then (paymentPercentage / paymentTotal) else paymentOther

จากนั้น ...

บันทึกว่าเป็นคุณสมบัติสำหรับลูกค้าและใส่ในวิธีการที่เหมาะสมหรือไม่

คุณทำได้ มันเป็นสตริงคุณสามารถบันทึกเป็นคุณสมบัติหรือคุณสมบัติ

ฉันจะไม่โกหก มันค่อนข้างซับซ้อนและยาก มันยิ่งยากขึ้นถ้ากฎทางธุรกิจมีความซับซ้อนเช่นกัน

ต่อไปนี้เป็นคำถาม SO ที่อาจเป็นที่สนใจของคุณ:


หมายเหตุ: ANTLR สร้างรหัสสำหรับ Python และ Javascript ด้วย นั่นอาจช่วยในการเขียนบทพิสูจน์แนวคิดโดยไม่มีค่าใช้จ่ายมากเกินไป

หากคุณพบว่า Antlr นั้นยากเกินไปคุณสามารถลองกับ libs เช่น Expr4J, JEval, Parsii สิ่งเหล่านี้ทำงานได้ในระดับที่สูงขึ้นของสิ่งที่เป็นนามธรรม


มันเป็นความคิดที่ดี แต่การบำรุงรักษาปวดหัวสำหรับคนต่อไปที่ลงมา แต่ฉันจะไม่ทิ้งความคิดใด ๆ จนกว่าฉันจะประเมินและชั่งน้ำหนักตัวแปรทั้งหมด
แอนดรู

1
ตัวเลือกมากมายที่คุณมีดีกว่า ฉันแค่ต้องการให้อีกหนึ่ง
Laiv

ไม่มีการปฏิเสธว่านี่เป็นวิธีการที่ถูกต้องเพียงแค่ดูที่ websphere หรือระบบอื่น ๆ ของชั้นวางขององค์กรที่ 'ผู้ใช้ปลายทางสามารถปรับแต่งได้' แต่เช่นเดียวกับ @akuhn คำตอบข้อเสียคือตอนนี้คุณกำลังเขียนโปรแกรมใน 2 ภาษา / source control / control control
Ewan

@Ewan ขอโทษฉันกลัวว่าฉันไม่เข้าใจข้อโต้แย้งของคุณ ตัวอธิบายภาษาและคลาสที่สร้างอัตโนมัติสามารถเป็นส่วนหนึ่งของโครงการได้หรือไม่ แต่ในกรณีใด ๆ ฉันไม่เห็นว่าทำไมฉันอาจสูญเสียการจัดการเวอร์ชัน / รหัสต้นฉบับ ในอีกทางหนึ่งอาจดูเหมือนว่ามี 2 ภาษาที่แตกต่างกัน แต่นั่นก็ชั่วคราว เมื่อภาษาเสร็จสิ้นคุณจะตั้งค่าสตริงเท่านั้น เหมือนการแสดงออกของ Cron ในระยะยาวมีอะไรที่กังวลน้อยกว่า
Laiv

"หากการชำระเงินIDเริ่มต้นด้วย 'R' ดังนั้น (การชำระเงินต่อยอด / การชำระเงินรวม) การชำระเงินอื่นอื่น ๆ " คุณเก็บไว้ที่ไหน รุ่นใด มันเขียนด้วยภาษาอะไร คุณได้รับการทดสอบหน่วยแบบใด
Ewan

1

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

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

วัตถุ StrategyFactory จะสร้างตัวชี้ StrategyIntf (หรือการอ้างอิง) ตาม CustomerID โรงงานสามารถส่งคืนการใช้งานเริ่มต้นสำหรับลูกค้าที่ไม่ได้เป็นพิเศษ

ระดับลูกค้าต้องขอเพียงโรงงานจากกลยุทธ์ที่ถูกต้องแล้วเรียกมันว่า

นี่คือหลอกสั้น ๆ C ++ เพื่อแสดงสิ่งที่ฉันหมายถึง

class Customer
{
public:

    void doCalculations()
    {
        CalculationsStrategyIntf& strategy = CalculationsStrategyFactory::instance().getStrategy(*this);
        strategy.doCalculations();
    }
};


class CalculationsStrategyIntf
{
public:
    virtual void doCalculations() = 0;
};

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


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

-1

สร้างอินเตอร์เฟสด้วยเมธอดเดียวและใช้ lamdas ในแต่ละคลาสการนำไปปฏิบัติ หรือคุณสามารถคลาสที่ไม่ระบุชื่อเพื่อใช้วิธีการสำหรับไคลเอนต์ที่แตกต่างกัน

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