装饰者模式 检查装饰器循环

装饰者模式  检查装饰器循环

过度设计 较复杂。

    public abstract class Shape
    {
        public virtual string AsString() => string.Empty; 
    }
    class Circel : Shape
    {
        float ridus;

        public Circel(float ridus)
        {
            this.ridus = ridus;
        }

        public override string AsString()
        {
            return $"Circle Ridus:{ridus}";
        }

        public void Resize(float size)
        {
            ridus *= size;
        }
    }

    class Square : Shape
    {
        float Side;

        public Square(float side)
        {
            Side = side;
        }

        public override string AsString()
        {
            return $"Square Side: {Side}";
        }
    }

    public abstract class ShapeDecorator : Shape
    {
        protected internal readonly List<Type> types = new();
        internal Shape Shape;

        public ShapeDecorator(Shape shape)
        {
            Shape = shape;
            if (shape is ShapeDecorator sd)
            {
                types.AddRange(sd.types);
            }
        } 
    }

    public abstract class ShapeDecorator<TSelf, TCycles> : ShapeDecorator
        where TCycles :ShaprDecoratorCyclePolicy,new()
    {
        protected readonly TCycles cycles = new TCycles();
        public ShapeDecorator(Shape shape) : base(shape)
        {
            if (cycles.TypeAdditionAllowed(typeof(TSelf),types))
            {
                types.Add(typeof(TSelf));
            }
        }
    }

    public class ShapeDecotatorWithPolicy<T> :ShapeDecorator<T, ThrowOnCycPolicy>
    {
        public ShapeDecotatorWithPolicy(Shape shape) : base(shape)
        {
        }
    }

    public class ColoredShape
       // :ShapeDecorator<ColoredShape,ThrowOnCycPolicy> //不允许相同
        :ShapeDecorator<ColoredShape, AbsorbCyclePolicy> //允许相同

       // : ShapeDecotatorWithPolicy<ColoredShape>
    {
       private readonly string color; 
        public ColoredShape(Shape shape, string color):base(shape)
        {
            this.Shape = shape;
            this.color = color;
        }

        public override string AsString()
        {
            var sb = new StringBuilder($"{Shape.AsString()}");
            if (cycles.ApplicationAllowed(types[0], types.Skip(1).ToList()))
                sb.Append($" has the color {color}");
            return sb.ToString();
        }
    }
     

    public class Transparent : Shape
    {
        Shape shape;
        float percentage;

        public Transparent(Shape shape, float _percentage)
        {
            this.shape = shape;
            this.percentage = _percentage;
        }

        public override string AsString()
        {
            return $"{shape.AsString()} Transparent:{percentage * 100.0}%";
        }
    }
   public abstract class ShaprDecoratorCyclePolicy
    {
        public abstract bool TypeAdditionAllowed(Type type, IList<Type> alltType);
        public abstract bool ApplicationAllowed(Type type, IList<Type> alltType);

    }

    public class CycesAllowedPolicy : ShaprDecoratorCyclePolicy
    {
        public override bool ApplicationAllowed(Type type, IList<Type> alltType)
        {
            return true;
        }

        public override bool TypeAdditionAllowed(Type type, IList<Type> alltType)
        {
            return true;
        }
    }

    public class ThrowOnCycPolicy : ShaprDecoratorCyclePolicy
    { 
        public bool handler(Type type, IList<Type> alltType) 
        {
            if (alltType.Contains(type))
                throw new InvalidOperationException($"Cycle Detected! Type is Error,{type.FullName}");
            return true;
        }
        public override bool ApplicationAllowed(Type type, IList<Type> alltType)
        {
           return handler(type, alltType);
        }

        public override bool TypeAdditionAllowed(Type type, IList<Type> alltType)
        {
            return handler(type, alltType);
        }
    }
    public class AbsorbCyclePolicy : ShaprDecoratorCyclePolicy
    {
        public override bool ApplicationAllowed(Type type, IList<Type> alltType)
        {
             return !alltType.Contains(type);
        }

        public override bool TypeAdditionAllowed(Type type, IList<Type> alltType)
        {
            return true;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Square sq = new Square(1.23f);
            Console.WriteLine(sq.AsString()); 

            ColoredShape colorShape = new ColoredShape(sq, "Black");
            colorShape = new ColoredShape(colorShape, "red");
            Console.WriteLine(colorShape.AsString()); 
        }
    }

 

posted @ 2022-05-19 15:18  后跳  阅读(33)  评论(0)    收藏  举报