С шаблоном декоратора вы могли бы возможно сделать это.
Character person = new Character("Rambo");
person = new Fighter(person); // decorate him with Fighter skills
person = new Thief(person); // also decorate him with Thief skills
Лично я бы, вероятно, вместо этого посмотрел на присоединение классов к персонажу:
Character person = new Character("Rambo");
person.AttachClass(new Fighter());
person.AttachClass(new Thief());
Конечно, если вам нужно сложное взаимодействие между классами, так что боец / вор не только получает бонусы и навыки от каждого, но он также получает что-то большее, возможно, единственный правильный путь для этого - создать специальные мультиклассы для всех комбинаций:
Character person = new Character("Rambo");
person.AttachClass(new FighterThief());
Это, конечно, просто взорвалось бы со всеми комбинациями.
А как насчет чисто настольных усилий?
Поместите все применимые навыки, заклинания, бонусы, эффекты и т. Д. В огромный стол, затем определите классы, связав определенный класс с конкретными предметами в этой таблице. Таким образом, было бы намного проще создавать гибридные классы, связывая различные базовые классы.
Чтобы использовать шаблон декоратора и при этом получить надлежащий доступ ко всему, каждый класс (в смысле программирования) должен быть правильно реализован как класс декоратора.
Например:
public class BaseClass
{
protected BaseClass(BaseClass underlyingCharacterClass);
public abstract bool CanCastSpells();
public abstract List<Spell> GetAvailableSpells();
protected BaseClass UnderlyingCharacterClass;
}
public class Wizard : BaseClass
{
public override bool CanCastSpells() { return true; }
public override List<Spell> GetAvailableSpells()
{
List<Spell> result = new List<Spell>();
if (UnderlyingCharacterClass != null)
result.AddRange(UnderlyingCharacterClass.GetAvailableSpells());
result.Add(new WizardSpell1());
...
return result;
}
}
public class Thief : BaseClass
{
public override bool CanCastSpells()
{
if (UnderlyingCharacterClass != null)
return UnderlyingCharacterClass.CanCastSpells();
return false;
}
public override List<Spell> GetAvailableSpells()
{
List<Spell> result = new List<Spell>();
if (UnderlyingCharacterClass != null)
result.AddRange(UnderlyingCharacterClass.GetAvailableSpells());
return result;
}
}