ฉันไม่แน่ใจว่ารูปแบบการออกแบบใดที่สามารถช่วยแก้ไขปัญหานี้ได้
ฉันมีคลาส 'ผู้ประสานงาน' ซึ่งกำหนดว่าควรใช้คลาสใดของผู้ปฏิบัติงานโดยไม่ต้องทราบเกี่ยวกับประเภทของแรงงานที่มีทั้งหมด - เพียงแค่เรียกใช้ WorkerFactory และดำเนินการตามอินเทอร์เฟซ IWorker ทั่วไป
จากนั้นตั้งค่าผู้ปฏิบัติงานที่เหมาะสมให้ทำงานและส่งคืนผลลัพธ์ของวิธี 'DoWork'
นี่เป็นเรื่องปกติ ... จนถึงตอนนี้; เรามีข้อกำหนดใหม่สำหรับคลาส Worker ใหม่ "WorkerB" ซึ่งต้องการข้อมูลเพิ่มเติมเช่นพารามิเตอร์อินพุตเพิ่มเติมเพื่อให้สามารถใช้งานได้
มันเหมือนกับว่าเราต้องการวิธีการทำงานหนักที่มีพารามิเตอร์อินพุตเพิ่มเติม ... แต่จากนั้นคนงานที่มีอยู่ทั้งหมดจะต้องใช้วิธีการนั้น - ซึ่งดูเหมือนว่าผิดเพราะคนงานเหล่านั้นไม่ต้องการวิธีการนั้นจริงๆ
ฉันจะสร้างสิ่งนี้ใหม่ได้อย่างไรเพื่อให้ผู้ประสานงานไม่ทราบว่ามีการใช้งานของคนงานคนใดและยังอนุญาตให้ผู้ใช้งานแต่ละคนได้รับข้อมูลที่ต้องใช้ในการทำงาน แต่ไม่มีคนงานทำสิ่งที่ไม่จำเป็น
มีคนงานที่มีอยู่จำนวนมากอยู่แล้ว
ฉันไม่ต้องการเปลี่ยนคนงานคอนกรีตที่มีอยู่เพื่อรองรับความต้องการของคลาส WorkerB ใหม่
ฉันคิดว่าบางทีรูปแบบของ Decorator น่าจะดีที่นี่ แต่ฉันไม่เคยเห็น Decorators ตกแต่งวัตถุด้วยวิธีเดียวกัน แต่ใช้พารามิเตอร์ที่แตกต่างกันมาก่อน ...
สถานการณ์ในรหัส:
public class Coordinator
{
public string GetWorkerResult(string workerName, int a, List<int> b, string c)
{
var workerFactor = new WorkerFactory();
var worker = workerFactor.GetWorker(workerName);
if(worker!=null)
return worker.DoWork(a, b);
else
return string.Empty;
}
}
public class WorkerFactory
{
public IWorker GetWorker(string workerName)
{
switch (workerName)
{
case "WorkerA":
return new ConcreteWorkerA();
case "WorkerB":
return new ConcreteWorkerB();
default:
return null;
}
}
}
public interface IWorker
{
string DoWork(int a, List<int> b);
}
public class ConcreteWorkerA : IWorker
{
public string DoWork(int a, List<int> b)
{
// does the required work
return "some A worker result";
}
}
public class ConcreteWorkerB : IWorker
{
public string DoWork(int a, List<int> b, string c)
{
// does some different work based on the value of 'c'
return "some B worker result";
}
public string DoWork(int a, List<int> b)
{
// this method isn't really relevant to WorkerB as it is missing variable 'c'
return "some B worker result";
}
}
Coordinator
ต้องมีการเปลี่ยนแปลงเพื่อรองรับพารามิเตอร์พิเศษนั้นในGetWorkerResult
ฟังก์ชั่นซึ่งหมายความว่าละเมิดหลักการเปิดของโซลิด ดังนั้นการเรียกรหัสทั้งหมดCoordinator.GetWorkerResult
จึงต้องเปลี่ยนด้วย ลองดูสถานที่ที่คุณเรียกฟังก์ชั่นนั้น: คุณตัดสินใจได้อย่างไรว่า IWorker จะขออะไร นั่นอาจนำไปสู่ทางออกที่ดีกว่า
IWorker
อินเตอร์เฟซที่จดทะเบียนรุ่นเก่าหรือว่าเป็นรุ่นใหม่ที่มีพารามิเตอร์เพิ่ม?