У меня есть несколько решений, которые все вращаются вокруг использования частного одиночного экземпляра в качестве «ключа», чтобы доказать, что вызывающий абонент - это тот, кем они себя называют.
Решение 1: класс друга-одиночка
public class A
{
private underwear myUnderwear;
public ChangeUnderwear(B friend, underwear newUnderwear)
{
if (friend == null) return;
myUnderwear = newUnderwear
}
}
public sealed class B
{
private B() {};
private B inst;
private MessWithA(A a)
{
a.ChangeUnderwear(this, new Thong());
}
}
Кто-нибудь там видит какой-нибудь недостаток? Этот метод будет работать, если у вас есть класс Foo и синглтон FooManager.
Решение 2:
Если друг не одиночка, я думаю, вы могли бы использовать ту же идею, скрывая конструкцию и скрывая все экземпляры:
interface IB
{ ... }
public sealed class B : IB
{
private B() {};
public IB CreateB()
{
return (IB)new B();
}
private MessWithA(A a)
{
a.ChangeUnderwear(this, new Thong());
}
}
Но теперь вам нужен какой-то способ, чтобы не дать врагу просто разыграть IB на B, а затем выдать себя за B, чтобы получить доступ только к членам A друзей. Есть идеи?
Решение 3: класс singleton позволяет его экземпляру принадлежать первому вызывающему, который его запрашивает. Класс друга пытается захватить экземпляр при запуске и вызывает истерику, если кто-то другой захватывает его первым
public class A
{
private underwear myUnderwear;
public ChangeUnderwear(B.IdCard friend, underwear newUnderwear)
{
if (friend == null) return;
myUnderwear = newUnderwear
}
}
public class B
{
public sealed class IdCard
{
private IdCard() {};
private static bool created = false;
public IDCard GetId()
{
if (created) throw new Exception("Why are two people asking for the same ID?!?");
created = true;
return new IDCard();
}
}
private static IdCard id;
static B()
{
id = IDCard.CreateId();
if (id == false) throw new Tantrum("Panic: Someone stole my ID card before I could grab it");
}
private void MessWithA(A a)
{
a.ChangeUnderwear(id, new Thong());
}
}