C# .Net设计模式与代码实现(二)——结构型模式

结构型模式


1、代理模式

场景:
某对象具有保护的内容或调用复杂,不应直接被访问。

定义:
给某对象提供一个代理以控制对该对象的访问。即通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。

目的:
起到中介作用,保护目标对象。
使调用和目标对象分离,降低系统耦合。

代码示例:

/// <summary>
/// 代理模式
/// </summary>
public class Proxy
{
    //抽象主题
    public interface Subject
    {
        public void Request();
    }

    //真实主题
    public class RealSubject : Subject
    {
        public void Request()
        {
            Console.WriteLine("RealSubject");
        }
    }

    //代理
    public class RealSubjectProxy : Subject
    {
        private RealSubject RealSubject;

        public void Request()
        {
            if (RealSubject == null)
            {
                RealSubject = new RealSubject();
            }
            PreRequest();
            RealSubject.Request();
            PostRequest();
        }

        public void PreRequest()
        {
            Console.WriteLine("预处理");
        }

        public void PostRequest()
        {
            Console.WriteLine("后续处理");
        }
    }

    /*
        调用方式:
        RealSubjectProxy proxy = new RealSubjectProxy();
        proxy.Request();
     */
}

2、适配器模式

场景:
一个类型需要适配多种功能。

定义:
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

目的:
将目标类适配新的功能,并满足开闭原则。

代码示例:

/// <summary>
/// 适配器模式
/// </summary>
public class Adapter
{
    /// <summary>
    /// 打印接口
    /// </summary>
    /// <remarks>
    /// 目标接口(需要适配的接口)
    /// </remarks>
    public interface Print
    {
        void Print();
    }

    /// <summary>
    /// 人类
    /// </summary>
    /// <remarks>
    /// 适配者(被适配的类型)
    /// </remarks>
    public class Person
    {
        public string GetName()
        {
            return "ABC";
        }
    }

    /// <summary>
    /// 人输出适配器类
    /// </summary>
    /// <remarks>
    /// 结构型适配器,继承需要适配的类型并实现需要适配的接口
    /// </remarks>
    public class PersonPrintAdapter : Person, Print
    {
        /// <summary>
        /// 输出人的名称
        /// </summary>
        public void Print()
        {
            Console.WriteLine(GetName());
        }
    }

    /*
        调用方式:
        Print print = new PersonPrintAdapter();
        print.Print();
     */

    /// <summary>
    /// 人输出适配器类
    /// </summary>
    /// <remarks>
    /// 对象型适配器
    /// </remarks>
    public class PersonPrintObjectAdapter : Print
    {
        private Person Person;

        public PersonPrintObjectAdapter(Person person)
        {
            this.Person = person;
        }

        public void Print()
        {
            Console.WriteLine(Person.GetName());
        }
    }

    /*
        调用方式:
        Person person = new Person();
        Print print = new PersonPrintObjectAdapter(person);
        print.Print();
     */
}

3、桥接模式

场景:
一个类内部具备两种或多种变化维度,且这些维度都需要进行扩展。

定义:
将抽象属性与实现分离,使它们可以独立变化。

目的:
将目标类桥接多个维度的属性和实现,并满足开闭原则。
解决继承关系在多个维度下数量很多且扩展困难的问题。

代码示例:

/// <summary>
/// 桥接模式
/// </summary>
public class Bridge
{
    /// <summary>
    /// 颜色
    /// </summary>
    public interface Color
    {
        public string GetColor();
    }

    /// <summary>
    /// 红色
    /// </summary>
    /// <remarks>
    /// 扩展颜色
    /// </remarks>
    public class Red : Color
    {
        public string GetColor()
        {
            return "Red";
        }
    }

    /// <summary>
    /// 蓝色
    /// </summary>
    /// <remarks>
    /// 扩展颜色
    /// </remarks>
    public class Blue : Color
    {
        public string GetColor()
        {
            return "Blue";
        }
    }

    /// <summary>
    /// 材质
    /// </summary>
    public interface Texture
    {
        public string GetTexture();
    }

    /// <summary>
    /// 棉质
    /// </summary>
    /// <remarks>
    /// 扩展材质
    /// </remarks>
    public class Cotton : Texture
    {
        public string GetTexture()
        {
            return "Cotton";
        }
    }

    /// <summary>
    /// 涤纶
    /// </summary>
    /// <remarks>
    /// 扩展材质
    /// </remarks>
    public class Polyester : Texture
    {
        public string GetTexture()
        {
            return "Polyester";
        }
    }

    /// <summary>
    /// 商品抽象
    /// </summary>
    public abstract class Commodity
    {
        protected Color Color { get; set; }

        protected Texture Texture { get; set; }

        public void SetColor(Color color)
        {
            this.Color = color;
        }

        public void SetTexture(Texture texture)
        {
            this.Texture = texture;
        }

        public abstract void Print();
    }

    /// <summary>
    /// A商品
    /// </summary>
    /// <remarks>
    /// 扩展抽象
    /// </remarks>
    public class ACommodity : Commodity
    {
        public override void Print()
        {
            Console.WriteLine($"A:{Color.GetColor()}:{Texture.GetTexture()}");
        }
    }

    /// <summary>
    /// B商品
    /// </summary>
    /// <remarks>
    /// 扩展抽象
    /// </remarks>
    public class BCommodity : Commodity
    {
        public override void Print()
        {
            Console.WriteLine($"B:{Color.GetColor()}:{Texture.GetTexture()}");
        }
    }

    /*
        调用方式:
        Color color = new Red();
        Texture texture = new Polyester();
        Commodity commodity = new ACommodity();
        commodity.SetColor(color);
        commodity.SetTexture(texture);
        commodity.Print();
     */
}

4、装饰器模式

场景:
在不改变现有对象结构的情况下,动态地给该对象增加一些额外功能的模式。

定义:
在不改变现有对象结构的情况下,动态地给该对象增加一些额外功能的模式。

目的:
不改变原有对象的情况下,动态的给一个对象扩展功能。

代码示例:

/// <summary>
/// 装饰器模式
/// </summary>
public class Decorator
{
    /// <summary>
    /// 抽象产品
    /// </summary>
    public interface Product
    {
        public void PrintName();
    }

    /// <summary>
    /// 食物
    /// </summary>
    /// <remarks>具体产品</remarks>
    public class Food : Product
    {
        public void PrintName()
        {
            Console.WriteLine("Food");
        }
    }

    /// <summary>
    /// 抽象装饰器
    /// </summary>
    public class ProductDecorator : Product
    {
        private Product Product;

        public ProductDecorator(Product product)
        {
            this.Product = product;
        }

        public virtual void PrintName()
        {
            this.Product.PrintName();
        }
    }

    /// <summary>
    /// 价格装饰器
    /// </summary>
    /// <remarks>装饰器具体实现</remarks>
    public class PriceProductDecorator : ProductDecorator
    {
        public PriceProductDecorator(Product product) : base(product)
        {
        }

        public override void PrintName()
        {
            base.PrintName();

            //添加打印价格的功能
            Console.WriteLine("Price: 100$");
        }
    }

    /*
        调用方式:
        Product product = new Food();
        Product decorator = new PriceProductDecorator(product);
        decorator.PrintName();
     */
}

5、外观模式

场景:
多个子系统具有复杂组合流程。

定义:
将多个子系统组合为一个新的接口,使外部调用不用关心内部子系统的具体细节。

目的:
将多个子系统组合为一个新的接口。

缺点:
增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。

代码示例:

/// <summary>
/// 外观模式
/// </summary>
public class Facade
{
    /// <summary>
    /// 吃饭
    /// </summary>
    /// <remarks>子系统</remarks>
    public class Eat
    {
        public void Do()
        {
            Console.WriteLine("Eat");
        }
    }

    /// <summary>
    /// 睡觉
    /// </summary>
    /// <remarks>子系统</remarks>
    public class Sleep
    {
        public void Do()
        {
            Console.WriteLine("Sleep");
        }
    }

    /// <summary>
    /// 玩
    /// </summary>
    /// <remarks>子系统</remarks>
    public class Play
    {
        public void Do()
        {
            Console.WriteLine("Sleep");
        }
    }

    /// <summary>
    /// 一天要做的事
    /// </summary>
    /// <remarks>外观模式</remarks>
    public class OneDayFacade
    {
        private Eat Eat = new Eat();
        private Sleep Sleep = new Sleep();
        private Play Play = new Play();

        /// <summary>
        /// 组合执行
        /// </summary>
        public void Do()
        {
            Eat.Do();
            Sleep.Do();
            Play.Do();
        }
    }

    /*
        调用方式:
        OneDayFacade oneDayFacade = new OneDayFacade();
        oneDayFacade.Do();
     */
}

6、享元模式

场景:
有多个需要复用的对象,且需要的状态一致。

定义:
共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

目的:
减少需要创建的对象数量。

缺点:
增加新的享元角色可能需要修改享元工厂类的源代码,违背了开闭原则。

代码示例:

/// <summary>
/// 享元模式
/// </summary>
public class Flyweight
{
    /// <summary>
    /// 文本打印对象
    /// </summary>
    /// <remarks>
    /// 非享元角色
    /// </remarks>
    public class TextPrint
    {
        public TextPrint()
        {
            this.Text = String.Empty;
        }

        /// <summary>
        /// 文本内容
        /// </summary>
        private string Text { get; set; }

        /// <summary>
        /// 添加文本
        /// </summary>
        /// <param name="text">添加的文本</param>
        public void AddText(string text)
        {
            this.Text += text;
        }

        /// <summary>
        /// 打印文本内容
        /// </summary>
        public void Print()
        {
            Console.WriteLine(Text);
        }
    }

    /// <summary>
    /// 文本写入享元抽象
    /// </summary>
    /// <remarks>抽象享元角色</remarks>
    public interface TextWriteFlyweight
    {
        public void Write(TextPrint textPrint, string name);
    }

    /// <summary>
    /// 食物文本写入角色
    /// </summary>
    /// <remarks>具体享元角色</remarks>
    public class FoodTextWrite : TextWriteFlyweight
    {
        public void Write(TextPrint textPrint, string name)
        {
            textPrint.AddText($"Food:{name}");
        }
    }

    /// <summary>
    /// 饮品文本写入角色
    /// </summary>
    /// <remarks>具体享元角色</remarks>
    public class DrinkTextWrite : TextWriteFlyweight
    {
        public void Write(TextPrint textPrint, string name)
        {
            textPrint.AddText($"Drink:{name}");
        }
    }

    /// <summary>
    /// 文本写入享元工厂
    /// </summary>
    public class TextWriteFlyweightFactory
    {
        /// <summary>
        /// 文本写入享元字典
        /// </summary>
        private Dictionary<string, TextWriteFlyweight> TextWrites = new Dictionary<string, TextWriteFlyweight>();

        /// <summary>
        /// 获取文本写入享元对象
        /// </summary>
        /// <param name="type">类型标识</param>
        /// <returns></returns>
        public TextWriteFlyweight GetTextWriteFlyweight(string type)
        {
            if (TextWrites.ContainsKey(type))
            {
                //享元角色已存在,使用现有享元角色
                return TextWrites[type];
            }
            else
            {
                //享元角色不存在,使用工厂模式创建角色
                TextWriteFlyweight flyweight;
                switch (type)
                {
                    case "food":
                        flyweight = new FoodTextWrite();
                        break;
                    case "drink":
                        flyweight = new DrinkTextWrite();
                        break;
                    default:
                        throw new ArgumentException("type is invalid");
                }
                TextWrites.Add(type, flyweight);
                return flyweight;
            }
        }

        /*
            调用方式:
            TextPrint textPrint = new TextPrint();
            TextWriteFlyweightFactory factory = new TextWriteFlyweightFactory();
            var foodFlyweight = factory.GetTextWriteFlyweight("food");
            var drinkFlyweight = factory.GetTextWriteFlyweight("drink");
            foodFlyweight.Write(textPrint, "AAA");
            drinkFlyweight.Write(textPrint, "BBB");
            textPrint.Print();
         */
    }
}

7、组合模式

场景:
由多个对象组成的树状结构有统一的操作。

定义:
将对象组合成树状的层次结构的模式,使用户对单个对象和组合对象具有一致的抽象。

目的:
可以一致的处理单个对象和组合对象。
加入新对象对象时无需修改代码,满足开闭原则。

代码示例:

/// <summary>
/// 组合模式
/// </summary>
public class Composite
{
    /// <summary>
    /// 文本打印
    /// </summary>
    /// <remarks>透明式抽象构建</remarks>
    public interface TextPrint
    {
        //在安全式组合模式中,仅保留公有的方法(如Print)

        /// <summary>
        /// 添加子构件
        /// </summary>
        public void Add(TextPrint textPrint);

        /// <summary>
        /// 打印
        /// </summary>
        public void Print();
    }

    /// <summary>
    /// 食物文本打印
    /// </summary>
    /// <remarks>树叶构件</remarks>
    public class FoodTextPrint : TextPrint
    {
        public FoodTextPrint(string name)
        {
            this.Name = name;
        }

        /// <summary>
        /// 食物名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 无Add操作,省略
        /// </summary>
        public void Add(TextPrint textPrint)
        {
            //无Add操作,省略
        }

        /// <summary>
        /// 食物文本打印
        /// </summary>
        public void Print()
        {
            Console.WriteLine($"Food:{this.Name}");
        }
    }

    /// <summary>
    /// 文本打印组合
    /// </summary>
    /// <remarks>树枝构件</remarks>
    public class TextPrintGroup : TextPrint
    {
        private List<TextPrint> TextPrints = new List<TextPrint>();

        /// <summary>
        /// 添加子构件
        /// </summary>
        /// <param name="textPrint">子构件</param>
        public void Add(TextPrint textPrint)
        {
            TextPrints.Add(textPrint);
        }

        /// <summary>
        /// 子构件文本打印
        /// </summary>
        public void Print()
        {
            foreach (TextPrint textPrint in TextPrints)
            {
                textPrint.Print();
            }
        }
    }

    /*
        调用方式:
        TextPrint group = new TextPrintGroup();
        TextPrint group1 = new TextPrintGroup();

        FoodTextPrint foodPrint = new FoodTextPrint("apple");
        FoodTextPrint orangePrint = new FoodTextPrint("orange");
        FoodTextPrint bananaPrint = new FoodTextPrint("banana");
        
        //进行组合
        group.Add(foodPrint);
        group.Add(orangePrint);
        group1.Add(bananaPrint);
        group1.Add(group);
        
        //不同组合的打印
        group1.Print();
        group.Print();
     */
}

配套源码:
C# .Net设计模式与代码实现

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值