実現したいこと
添付コードの状況において「Carインスタンス作成後に、プレイヤーの数値入力によって動的にSuperEngineのgearを上げ下げできるようにしたい」といった仕様変更が入った際、どのように修正するのが良いか意見を伺いたいです。
発生している問題・分からないこと
そもそもこのような仕様変更が入る可能性を考えずにIEngineインターフェースで抽象化してしまったのが間違いなのか、それとも他に抽象化のメリットを維持しながら仕様変更に対処する方法があるなら知りたい。
該当のソースコード
C#
1public class Hello{ 2 public static void Main(){ 3 4 Car car = new Car(new MiniEngine()); 5 Car car2 = new Car(new SuperEngineAdapter(new SuperEngine(1))); 6 7 car.Run(); // 5 8 car2.Run(); // 30 9 10 var line = System.Console.ReadLine(); 11 int newGear = 0; 12 bool result = int.TryParse(line, out newGear); 13 if(result){ 14 //car2.SetGear(newGear); //コンパイルエラー 15 System.Console.WriteLine($"newGear:{newGear}"); 16 } 17 18 19 car2.Run(); // newGearに応じて変化させたい 20 21 } 22} 23 24 25 26public class Car{ 27 public IEngine engine; 28 public Car(IEngine engine){ 29 this.engine = engine; 30 } 31 32 public void Run(){ 33 float power = engine.Boost(); 34 System.Console.WriteLine("power=" + power.ToString()); 35 } 36} 37 38public interface IEngine{ 39 float Boost(); 40} 41public class SuperEngine{ 42 int gear; 43 public SuperEngine(int initalGear){this.gear = initalGear;} 44 45 public float GetPower(){ 46 if(gear == 0) {return 10;} 47 else if(gear == 1){return 30;} 48 else return 50; 49 } 50 51 //public void SetGear(int gear) {this.gear = gear;} 52 53} 54public class SuperEngineAdapter : IEngine 55{ 56 SuperEngine se; 57 public SuperEngineAdapter(SuperEngine se){ 58 this.se = se; 59 } 60 public float Boost(){ 61 return se.GetPower(); 62 } 63} 64 65public class MiniEngine : IEngine{ 66 public float Boost(){ 67 return 5; 68 } 69}
修正済みコード(追加)
C#
1public class Hello{ 2 public static void Main(){ 3 4 Car car = new Car(new MiniEngine()); 5 Car car2 = new Car(new SuperEngineAdapter(new SuperEngine(1))); 6 7 car.Run(); // 5 8 car2.Run(); // 30 9 10 var line = System.Console.ReadLine(); 11 int newGear = 0; 12 bool result = int.TryParse(line, out newGear); 13 if(result){ 14 //New Code 15 car.SetEngineGear(newGear); 16 car2.SetEngineGear(newGear); 17 // 18 System.Console.WriteLine($"newGear:{newGear}"); 19 } 20 21 car.Run(); //Warning 22 car2.Run(); // newGearに応じて変化 23 24 } 25} 26 27 28 29public class Car{ 30 protected IEngine engine; 31 public Car(IEngine engine){ 32 this.engine = engine; 33 } 34 35 //New Code 36 public void SetEngineGear(int newGear){ 37 engine.SetGear(newGear); 38 } 39 40 public void Run(){ 41 float power = engine.Boost(); 42 System.Console.WriteLine("power=" + power.ToString()); 43 } 44} 45 46public interface IEngine{ 47 float Boost(); 48 void SetGear(int newGear); //New Code 49} 50public class SuperEngine{ 51 int gear; 52 public SuperEngine(int initalGear){this.gear = initalGear;} 53 54 public float GetPower(){ 55 if(gear == 0) {return 10;} 56 else if(gear == 1){return 30;} 57 else return 50; 58 } 59 60 public void SetGear(int gear) {this.gear = gear;} //New Code 61 62} 63public class SuperEngineAdapter : IEngine 64{ 65 SuperEngine se; 66 public SuperEngineAdapter(SuperEngine se){ 67 this.se = se; 68 } 69 public float Boost(){ 70 return se.GetPower(); 71 } 72 73 public void SetGear(int gear){ se.SetGear(gear);} //New Code 74} 75 76public class MiniEngine : IEngine{ 77 public float Boost(){ 78 return 5; 79 } 80 81 //New Code 82 public void SetGear(int newGear){ 83#warning MiniEngine has no gear choice. It's always 5. 84 } 85}
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
以下参考サイト
https://refactoring.guru/ja/design-patterns/adapter
https://www.youtube.com/watch?v=OCh1Bnj9gws
https://www.youtube.com/watch?v=CrqdpVPgE9k
補足
特になし
回答1件
あなたの回答
tips
プレビュー