简体   繁体   中英

Reuse similar constructors without the use of inheritance

This is a code for MonoGame 3.8.1 and .NET 6.

public interface IEntity
{
    int Size { get; }
    Vector2 Position { get; }
}
public class Player : IEntity
{
    public int Size { get; } = 32;
    public Vector2 Position { get; private set; }

    public Player(Scene scene)
    {
        var spawnOffset = new Vector2(0, -3);

        Position = new Vector2(
            spawnOffset.X * scene.TileSize + scene.Room.Center.x - Size / 2,
            spawnOffset.Y * scene.TileSize + scene.Room.Center.y - Size / 2);
    }
}
public class Enemy : IEntity
{
    public int Size { get; } = 32;
    public Vector2 Position { get; private set; }

    public Enemy(Scene scene)
    {
        var spawnOffset = new Vector2(0, 0);
    
        Position = new Vector2(
            spawnOffset.X * scene.TileSize + scene.Room.Center.x - Size / 2,
            spawnOffset.Y * scene.TileSize + scene.Room.Center.y - Size / 2);
    }

}

Without the use of inheritance, I want every class that implements IEntity to be able to reuse calculations for Position assignment. The only difference between both constructors is the spawnOffset values.

What's the most simple way to do this?

Normally - I would call the base class constructor, but here I'm trying to do this without a base class.

Looks like you follow "prefer composition over inheritance" - indeed that is a valid approach, just finish that by extracting "position" functionality into separate class:


class EntityPosition
{
    public Vector2 Position { get; private set; }
    public EntityPosition (Scene scene, Vector2 spawnOffset, int size)
    {
       Position = new Vector2(
        spawnOffset.X * scene.TileSize + scene.Room.Center.x - size / 2,
        spawnOffset.Y * scene.TileSize + scene.Room.Center.y - size / 2);
    }
    // add other shared methods for position updates here as necessary
}

public class Player : IEntity
{
    EntityPosition position;
    public int Size { get; } = 32;
    public Vector2 Position => position.Position;

    public Player(Scene scene)
    {
        var spawnOffset = new Vector2(0, -3);

        position = EntityPosition(scene, spawnOffset, Size);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM