using System.Collections.Generic;
public interface IVisitable<Visitor> {
void Accept(Visitor visitor);
public interface IGameAction<Visitor> : IVisitable<Visitor> {
public interface BaseGameAction : IGameAction<IBaseGameEventVisitor> {
public interface IBaseGameEventHandler{
public interface IGameActionListener<Visitor> {
void receive(IGameAction<Visitor> gameEvent);
public interface IBaseGameEventVisitor
void Visit(BaseAction1 action);
public class BaseAction1 : BaseGameAction {
public void Accept(IBaseGameEventVisitor visitor) {
public class ActionExecute<Visitor>{
private List<IGameActionListener<Visitor>> _listeners = new List<IGameActionListener<Visitor>>();
public void subscribe(IGameActionListener<Visitor> listener){
_listeners.Add(listener);
public void Execute(IGameAction<Visitor> action){
foreach(var listener in _listeners){
listener.receive(action);
public class BaseActionWrapper : ConcreteGameAction {
private BaseGameAction _baseAction;
public BaseActionWrapper(BaseGameAction baseAction){
_baseAction = baseAction;
public void Accept(IConcreteGameEventVisitor visitor) {
_baseAction.Accept(visitor);
public interface IConcreteGameEventVisitor : IBaseGameEventVisitor
void Visit(ConcreteAction1 action);
public interface ConcreteGameAction : IGameAction<IConcreteGameEventVisitor>{
public class ConcreteAction1 : ConcreteGameAction {
public void Accept(IConcreteGameEventVisitor visitor) {
public class LoggerActionVisitor : IConcreteGameEventVisitor, IGameActionListener<IConcreteGameEventVisitor> {
public void receive(IGameAction<IConcreteGameEventVisitor> action){
public void Visit(BaseAction1 action){
Console.WriteLine(action.ToString());
public void Visit(ConcreteAction1 action){
Console.WriteLine(action.ToString());
public static void Main()
var loggerVisitor = new LoggerActionVisitor();
var runner = new ActionExecute<IConcreteGameEventVisitor>();
runner.subscribe(loggerVisitor);
runner.Execute(new BaseActionWrapper(new BaseAction1()));
runner.Execute(new ConcreteAction1());