我有一个Scenario,它使用A或几个As。 A是在此[[Scenario之外创建的,但在A内部创建的B却不知道该实例的场景。这就是想法,A和B不必知道场景的工作原理,它们只需要在引发/调用UpdateEvent时工作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var sce1 = new Scenario();
sce1.Add(new A(1));
sce1.Add(new A(3));
sce1.Update(2);
sce1.Update(5);
var sce2 = new Scenario();
sce2.Add(new A(6));
sce2.Update(0.3);
Console.ReadKey();
}
}
public class BasicEvent : EventArgs
{
public double Number { get; set; }
}
public abstract class toBeUpdated
{
public abstract void OnUpdate(object sender, BasicEvent e);
}
public class C : toBeUpdated
{
public double Number { get; set; }
public C(double num)
{
Number = num * num;
}
public override void OnUpdate(object sender, BasicEvent e)
{
Number = Math.Pow(e.Number, 2);
}
}
public class B : toBeUpdated
{
public double Number { get; set; }
public B(double num)
{
Number = num;
}
public override void OnUpdate(object sender, BasicEvent e)
{
Number *= e.Number;
}
}
public class A : toBeUpdated
{
private B B1 { get; set; }
private B B2 { get; set; }
private C C1 { get; set; }
public A(double number)
{
B1 = new B(number);
B2 = new B(number);
C1 = new C(number);
}
public override void OnUpdate(object sender, BasicEvent e)
{
Console.WriteLine($"Updating A.. Data = {B1.Number + B2.Number * C1.Number}");
}
}
public class Scenario
{
private event EventHandler<BasicEvent> UpdateEvent;
private List<toBeUpdated> toKeepTrack { get; set; }
public Scenario()
{
toKeepTrack = new List<toBeUpdated>();
}
public void Add(toBeUpdated obj)
{
toKeepTrack.Add(obj);
UpdateEvent += obj.OnUpdate;
}
public void doSomethingWithTheList()
{
....
}
public void Update(double num)
{
UpdateEvent?.Invoke(this, new BasicEvent() { Number = num });
Console.WriteLine();
}
}
}
我需要创建几种方案,我不能使其成为静态。
IScenario
,并让Scenario
扩展此接口。这将隐藏 Scenario
的实现细节,并允许您将IScenario
直接传递到A
的构造函数中。
public interface IScenario
{
void Add(toBeUpdated obj);
void Update(int num);
}
您现在可以像这样扩展Scenario
:
public class Scenario : IScenario { ... }
相应地更新A
:
public class A : toBeUpdated { ... public A(int number, IScenario scenario) { B1 = new B(number); scenario.Add(this); scenario.Add(B1); } ... }
如何使用将类似于:
var sce = new Scenario(); A a1 = new A(1, sce); A a3 = new A(3, sce); sce.Update(2); sce.Update(5);
此方法可确保A
不知道Scenario
正在以最小的努力进行更新,并且该方法是可测试的。另一种方法是在A
上添加一个方法,该方法registers
Scenario
(如果A
在创建后需要添加新的Scenario
,则很有用):public void Register(IScenario scenario)
{
scenario.Add(this);
scenario.Add(B1);
}
,但是当您进入注意:创建
IScenario
不是必需
unit testing
并想要mock
对象时,最好具有它。