Optimal architecture for card effects, prefabs or scriptableobjects?

Hi all, I am making a turn based CCG for fun and educational purposes. At the moment I have a system in place for creating card effects, it is usable but not up to the standard I would like to have.

Current System:

Each effect contains 3 main properties:

- A list of triggers

A trigger is an event in the game world

Example: When a card is played

- A list of conditions

Conditions are the necessary states needed in order to execute the effect action

Example: If the player has more than x life

- A list of effect actions

An effect action alters the state of the game/player/card in some way

Example: Deal x damage to the opponent

The problem with the current system:

This system requires me to create a new game object for each card effect. There is no need for this to be a game object. Also, any trigger,condition or effect action that the card uses must be attached to the game object. This can lead to a very cluttered inspector view on more complex effects.
As previously stated, this works but I feel it can be improved upon and can’t seem to figure out how.

Alternatives:

I have played around with scriptable objects without much success. For example, if I had an EffectAction class called DealDamageToPlayer, anytime I want to use this class on an effect; I would need to create a new instance because it would alter the original value. This would leave me with multiple copies of the same class all with different values. Also, I understand that this also occurs with the current system, when I attach the same script to multiple effect game objects. The difference is that it is not visible in the project explorer and does not result in clutter.

Similar Questions:

My original system was inspired by this question ‘What is the most effective way to structure Card Effects in a Single Player game?’ They ran into the same issue I mentioned in the alternatives section with regards to scriptable objects.

This question: ‘Card Game, cards as ScriptableObject, card effects as ScriptableObjects, effects have different parameters. How to make an inspector UI support this structure?’ includes the type of UI I am after. However, because they use scriptable objects there will be many duplicate instances.

If anything I said is incorrect, please do correct me.

Any and all assistance would be greatly appreciated.

Scripts:

Trigger.cs

public abstract class Trigger : MonoBehaviour
{
    public abstract void SubscribeToEvent(Action<EventInfo> checkConditions);

    public abstract void UnsubscribeFromEvent(Action<EventInfo> checkConditions);
}

Condition.cs

public abstract class Condition : MonoBehaviour
{
    public abstract bool Requirement(EventInfo eventInfo);
}

EffectAction.cs

public abstract class EffectAction : MonoBehaviour
{
    public abstract void ApplyEffectAction();
}

Effect.cs

public class Effect : MonoBehaviour
{

    [Header("WHEN")]
    public List<Trigger> triggers;

    [Header("IF")]
    public List<Condition> conditions;

    [Header("DO")]
    public EffectAction effectAction;

    public void SetUpTriggers()
    {
        foreach (Trigger trigger in triggers)
        {
            trigger.SubscribeToEvent(CheckConditions);
        }
    }

    public void RemoveTriggers()
    {
        foreach (Trigger trigger in triggers)
        {
            trigger.UnsubscribeFromEvent(CheckConditions);
        }
    }

    public void CheckConditions(EventInfo eventInfo)
    {
        if (conditions.Count != 0)
        {
            foreach (Condition condition in conditions)
            {
                if (!condition.Requirement(eventInfo))
                {
                    Debug.Log("CheckConditions: false");
                    return;
                }
            }
        }
        effectAction.ApplyEffectAction();
    }
}

Hello, i would go with a little different approach, but this is just an idea, i would make Effect class a ScriptableObject and add the createassetlabel to create instance of effects in the project folder.
Second i would NOT create an instance for each EffectAction for example, step by step for what i would do, this example is only based on the EffectAction class, i would first create an enum with all the effects posible

public enum EffectDataType
{
    heal,
    damage,
    powerup
}

second, when you are using instance of EffectAction i would simply use a struct, serializable so that can be edited in the scriptablobject inspector with all the damage/cost and data needed

[System.Serializable]
public struct EffectActionData
{
    public EffectDataType type;
    public int damage;
    public int cost;
    public string name;
}

then i would create your effectaction parent class and a damage child for example

 public abstract class EffectAction
 {
     public abstract void ApplyEffectAction(EffectActionData data);
 }

 public abstract class DamageAction: EffectAction 
 {
     public virtual void ApplyEffectAction(EffectActionData data)
     {
          Debug.Log("logic");
     }
 }

and finally create the effect scriptable object class

[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/Effect", order = 1)]
public class Effect : ScriptableObject 
{
    public EffectActionData cardEffect;
    public void CheckConditions()
    {
        //if (conditions.Count != 0)
        {
            //  foreach (Condition condition in conditions)
            {
            //    if (!condition.Requirement(eventInfo))
                {
                    Debug.Log("CheckConditions: false");
                    // return;
                }
            }
        }

        switch (cardEffect.type)
        {
            case EffectDataType.damage:
                Debug.Log("Here you would call to the ApplyEffectAction method that could even be static so you dont need instances");
                break;
            case EffectDataType.heal:
                break;
            case EffectDataType.powerup:
                break;
        }
    }
}