วิธีการทั่วไปที่รับพารามิเตอร์เฉพาะและส่งกลับพารามิเตอร์เฉพาะ Java

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

ie.

public returnObject1 myfunction( paramObject1 a, int a) {
returnObject1 = new returnObject1();
returnObject1.a = paramObject1.a;
return returnObject1;
}

public returnOject2 myfunction( paramObject2 a, int a){
 returnObject2 = new returnObject2();
 returnObject2.a = paramObject2.a;
 return returnObject2;
}

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

ฉันต้องการลดการเขียนฟังก์ชันต่างๆ ที่ทำงานเดียวกันให้เหลือน้อยที่สุด

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

paramObject และ returnObject โดยพื้นฐานแล้วเป็นสองคลาสที่มีตัวแปรต่างกัน พวกเขาไม่เกี่ยวข้องกัน

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

เป้าหมายของฉันคือการทำสิ่งนี้ (ถ้าเป็นไปได้):

public static < E > myfunction( T a, int a ) {
  // do work
}

ประเภทการส่งคืน E และอินพุต T สามารถเปลี่ยนแปลงได้


person ajroot    schedule 06.07.2017    source แหล่งที่มา
comment
หากไม่มีข้อมูลเฉพาะเจาะจงเพิ่มเติมว่า paramObject1 และ paramObject2 คืออะไร นี่เป็นเรื่องยากที่จะตอบ หากเป็นประเภทที่คล้ายกัน บางทีคุณควรเก็บวิธีสาธารณะทั้งสองไว้ ย้ายโค้ดทั่วไปไปยังวิธีส่วนตัวใหม่ และให้แต่ละวิธีเรียกวิธีส่วนตัวนั้น   -  person VGR    schedule 06.07.2017
comment
paramObject และ returnObject เชื่อมต่อกันอย่างไร   -  person Marvin    schedule 06.07.2017
comment
คุณหมายถึงว่าการรักษาเหมือนกันแต่ใช้วัตถุต่างกันใช่ไหม? หากเป็นเช่นนั้น และหากพวกเขาใช้ชื่อวิธีการเดียวกัน คุณก็อาจจะเขียนประมาณว่า public T myfunction(T param, int a) ได้   -  person Asew    schedule 06.07.2017
comment
บางที public Object[] myFunction(int a , Object... abstractObjectArray) อาจฟังดูมีประโยชน์เช่นกัน   -  person ShayHaned    schedule 06.07.2017
comment
คำถามใช้ถ้อยคำไม่ถูกต้องและไม่ได้ให้ความชัดเจน คุณต้องการหลายวิธี (โอเวอร์โหลด) หรือเพียงวิธีเดียวที่ประมวลผลแตกต่างกันตาม paramIObject ที่ส่งผ่านหรือไม่   -  person digidude    schedule 06.07.2017
comment
ไม่มีทางที่จะมีเมธอดเดียวที่ส่งคืนสิ่งต่าง ๆ โดยไม่ต้องมีอินเทอร์เฟซทั่วไปหรือคลาสนามธรรม และ (อาจ) ประกาศพารามิเตอร์ประเภทบน ReturnObject หรือ ParamObject ซึ่งอย่างหลังไม่น่าจะเป็นไปได้สูงที่จะเป็นความคิดที่ดีที่นี่ เมื่อถึงจุดนี้คุณควรพิจารณาการออกแบบของคุณใหม่ ฉันมีเพียงความคิดที่ค่อนข้างคลุมเครือเกี่ยวกับสิ่งที่คุณกำลังทำอยู่ แต่รูปแบบ Abstract Factory ดูเหมือนว่าจะมีประโยชน์ที่นี่ อาจเป็นกรณีที่การใช้โอเวอร์โหลดตามที่คุณทำไปแล้วเป็นวิธีแก้ปัญหาที่สมบูรณ์แบบ มันยากที่จะพูดโดยไม่รู้อะไรมากกว่านี้   -  person Radiodef    schedule 06.07.2017
comment
ดูเหมือนว่าสิ่งที่ @Radiodef พูดนั้นสมเหตุสมผลสำหรับฉันตอนนี้ ฉันจะต้องสร้างและอินเทอร์เฟซหรือคลาสนามธรรมเพื่อจัดการสิ่งนี้   -  person ajroot    schedule 06.07.2017
comment
อย่างแน่นอน. หากไม่มีนามธรรม การกระทำทั้งสาม (new EitherType(), objOfUnrelatedType.a = objOfAnotherUnrelatedType.a;, return objOfEitherType;) ของวิธีใดวิธีหนึ่ง จะ การกระทำที่แตกต่างกัน เนื่องจากจะไม่นับรวมลักษณะที่ปรากฏของซอร์สโค้ดที่คล้ายคลึงกัน   -  person Holger    schedule 06.07.2017


คำตอบ (2)


สร้าง interface Foo และนำ interface นี้ไปใช้ทั้งในคลาส paramObject1 และ paramObject2 ตอนนี้วิธีการของคุณควรมีลักษณะดังนี้:

public Foo myFunction(Foo foo, int a){
    //Rest of the code.
    return foo;
}
person Jasman Shakya    schedule 06.07.2017
comment
ฉันก็คิดตามบรรทัดเหล่านั้นเช่นกันและคลาสพื้นฐานที่เป็นนามธรรมสำหรับความธรรมดาสามัญ - person JGFMK; 06.07.2017
comment
มันสมเหตุสมผล แต่ฉันสงสัยว่ามีวิธีอื่นหรือไม่ ฉันต้องการหลีกเลี่ยงการสร้างอินเทอร์เฟซใหม่เพื่อจัดการสิ่งนี้เนื่องจากฉันมีออบเจ็กต์มากมายที่แตกต่างกันออกไป - person ajroot; 06.07.2017
comment
ฉันคิดว่าคุณกำลังทำอะไรบางอย่างอยู่ ความท้าทายคือคุณไม่สามารถทำ new Foo() ได้เมื่อ Foo เป็นส่วนต่อประสาน ต้องหาทางแก้ปัญหานั้นให้ได้ - person Ole V.V.; 06.07.2017

คุณสามารถใช้วิธีที่ 3 apply เพื่อลบการทำซ้ำโค้ด โดยแยกการสร้างและการเริ่มต้นออกจากวิธี apply ในแนวทางนี้ และไม่สนใจว่าจะใช้ T ประเภทใด ตัวอย่างเช่น:

returnObject1 myfunction(paramObject1 a, int b) {
    return apply(returnObject1::new, b, value -> {
        //uses paramObject1
        //populates returnObject1
        //for example:
        value.foo = a.bar;
    });
}

returnOject2 myfunction(paramObject2 a, int b) {
    return apply(returnOject2::new, b, value -> {
        //uses paramObject2 
        //populates returnObject2
        //for example:
        value.key = a.value;
    });
}

<T> T apply(Supplier<T> factory, int b, Consumer<T> initializer) {
    T value = factory.get();
    initializer.accept(value);
    //does work ...
    return value;
}

หมายเหตุ 2 myfunction เป็นทางเลือก คุณสามารถลบออกจากซอร์สโค้ดของคุณ และเรียกใช้เมธอด apply ได้โดยตรง ตัวอย่างเช่น:

paramObject2 a = ...;

returnObject2  result = apply(returnOject2::new, 2, value -> {
    //for example:
    value.key = a.value;
});
person holi-java    schedule 06.07.2017
comment
ฉันต้องการยกเลิกการเขียนสองฟังก์ชัน แทนที่จะมีฟังก์ชันเดียวที่รับพารามิเตอร์ต่างกัน - person ajroot; 06.07.2017
comment
@AJRoot อาจจะ apache beanutils ตรงตามความต้องการของคุณ คุณให้ข้อมูลไม่เพียงพอ ดังนั้นคำตอบของฉันก็ นามธรรม เช่นกัน... :) และสังเกตว่า 2 myfunction วิธีด้านบนเป็นทางเลือก คุณสามารถลบออกได้เช่นกัน - person holi-java; 06.07.2017