1. 程式人生 > 其它 >裝飾者模式 檢查裝飾器迴圈

裝飾者模式 檢查裝飾器迴圈

裝飾者模式  檢查裝飾器迴圈

過度設計 較複雜。

    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()); } }