如果之前有人问过,请道歉;我甚至正在努力使用正确的术语来定义问题/目标。
我有Person
个对象......
public class Person
{
public string FullName { get; set; }
public HeroAbilities Abilities { get; set; }
public SuperHero Hero { get; set; }
}
...每个Person
都有一系列能力使他们成为潜在的超级英雄:
[FlagsAttribute()]
public enum HeroAbilities : long
{
None = 0,
Strong = 1,
Fly = 2,
WarpSpeed = 4,
Crazy = 8
}
一旦我知道他们的能力是什么,我就能让他们成为合适的英雄:
public class SuperHero
{
public string Name { get; set; }
}
例如,以下是我如何声明两个Person
个对象,并检查每个对象:
// Simple check: person should travel at warp speed
var p1 = new Person() { FullName = "Barry Allen", Abilities = HeroAbilities.Strong | HeroAbilities.WarpSpeed };
if(p1.Abilities.HasFlag(HeroAbilities.WarpSpeed))
{
p1.Hero = new SuperHero() { Name = "The Flash" };
}
// Complex check: person should either be crazy, or be strong AND can fly
var p2 = new Person() { FullName = "Mr F. Bar", Abilities = HeroAbilities.None };
if (p2.Abilities.HasFlag(HeroAbilities.Crazy) || p2.Abilities.HasFlag(HeroAbilities.Strong) && p2.Abilities.HasFlag(HeroAbilities.Fly))
{
p2.Hero = new SuperHero() { Name = "SuperFooB" };
}
目标是采用检查Person
是否适合作为英雄的逻辑,并将其放在每个相应的SuperHero
类中,这样我就可以这样做:
var sh = new SuperHero() { ... };
var p = new Person() { .... };
if(sh.PersonSuitable(p)) { p.Hero = sh };
我真正努力的部分是一些检查很复杂(例如X or (Y and Z)
),所以[Enum.HasFlag][1]
是不够的。我正处于我相当有限的OOP体验的极限,所以也许缺少一些简单的东西。
答案 0 :(得分:1)
免责声明:代码可能无法按预期执行,因为它只是用于显示问题的概念解决方案。
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject4
{
[TestClass]
public class UnitTest2
{
[TestMethod]
public void TestMethod1()
{
var superHeroFactory = new SuperHeroFactory();
var p1 = new Person {FullName = "Barry Allen", Abilities = {new Strong(), new WarpSpeed()}};
p1.Hero = superHeroFactory.Create(p1);
var p2 = new Person {FullName = "Mr F. Bar", Abilities = {new Crazy(), new Strong(), new CanFly()}};
p2.Hero = superHeroFactory.Create(p2);
}
}
public class SuperHeroFactory
{
private readonly List<Tuple<SuperHero, List<Ability>>> _profiles =
new List<Tuple<SuperHero, List<Ability>>>
{
new Tuple<SuperHero, List<Ability>>(
new SuperHero {Name = "The Flash"}, new List<Ability> {new WarpSpeed()}),
new Tuple<SuperHero, List<Ability>>(
new SuperHero {Name = "SuperFooB"}, new List<Ability> {new Crazy()}),
new Tuple<SuperHero, List<Ability>>(
new SuperHero {Name = "SuperFooB"}, new List<Ability> {new Strong(), new CanFly()})
};
public SuperHero Create(Person person)
{
// you may end up with more then one match here ))..
return _profiles.FirstOrDefault(
profile => !person.Abilities.Except(profile.Item2).Any())?.Item1;
}
}
public class Person
{
public string FullName { get; set; }
public ICollection<Ability> Abilities { get; } = new List<Ability>();
public SuperHero Hero { get; set; }
}
public class SuperHero
{
public string Name { get; set; }
}
public abstract class Ability { }
public class Strong : Ability { }
public class CanFly : Ability { }
public class WarpSpeed : Ability { }
public class Crazy : Ability { }
}