IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 设计模式- 装饰模式(Decorator) -> 正文阅读

[游戏开发]设计模式- 装饰模式(Decorator)

装饰模式:

装饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

结构图:

模式的组成:

Component是定义一个对象接口。可以给这些对象动态的添加职责。
ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator,装饰抽象类,继承了Component。从外类来扩展Component类的功能。对于Component来说,是无需知道Decorator的存在的。ConreteDecorator就是具体的装饰对象。起到给Component添加职责的功能。

抽象类算法:Component

abstract class Component
{
    public abstract void Operation();
}

ConcreteComponent类

class ConreteComponent:Component
{
    public override void Operation()
    {
        Console.WriteLine("具体对象的操作");
    }
}

Decorator类

abstract class Decorator:Component
{
    protected Component component;

    public void SetComponent(Component component)
    {
        this.component = component;
    }

    public override void Operation()
    {
        if(component != null)
        {
            component.Operation();
        }
    }
}

具体ConcreteDecorator类:

class ConcreteDecoratorA:Decorator
{
    private string addedState;
    public override void Operation()
    {
        base.Operation();
        addState = "New State";
        Console.WriteLine("具体装饰对象A的操作");
    }
}

class ConcreteDecoratorB:Decorator
{
    
    public override void Operation()
    {
        base.Operation();
        AddBehavior();
        Console.WriteLine("具体装饰对象A的操作");
    }
    private void AddedBehavior()
    {
        // 具体操作B
    }
}

客户端调用:


ConcreteComponent c = new  ConcreteComponent();
ConcreteDecoratorA d1 = new  ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();

举例,对一个人名为小菜的穿着进行包装。在使用装饰类之前的代码可能是这样的:

初级版:

class Person
    {
        private string name;
        public Person(string name)
        {
            this.name = name;
        }

        public void WearTShirts()
        {
            Console.Write("大T恤 ");
        }

        public void WearBigTrouser()
        {
            Console.Write("垮裤 ");
        }

        public void WearSneakers() 
        {
            Console.WriteLine("破球鞋 ");
        }

        public void WearSuit()
        {
            Console.WriteLine("西装 ");
        }

        public void WearTie()
        {
            Console.Write("领带 ");
        }

        public void Show()
        {
            Console.WriteLine("装扮的{0}",name);
        }
    }

客户端调用:

class Program
    {
        static void Main(string[] args)
        {
            Person xiaocai = new Person("小菜");
            Console.WriteLine("\n第一种装扮: ");
            xiaocai.WearTShirts();
            xiaocai.WearBigTrouser();
            xiaocai.WearSneakers();
            xiaocai.Show();

            Console.WriteLine("\n 第二种装扮:");
            xiaocai.WearSuit();
            xiaocai.WearTie();
            xiaocai.WearLeatherShose();
            xiaocai.Show();
        }
    }

输出:

?从功能上看是实现了装扮的功能。但是这类代码不易维护,如果要添加功能的话,就要修改代码。就需要修改Person类添加功能函数。但是这违背开放封闭原则。所以我们进行一下改进:

输出第二版,对Person类和服饰类进行分离:

    class Person
    {
        private string name;

        public Person(string name)
        {
            this.name = name;
        }

        public void Show()
        {
            Console.WriteLine("装扮的{0}",name);
        }
    }

    abstract class Finery
    {
        public abstract void Show();
    }

子类:

 class BigTrouser : Finery
    {
        public override void Show()
        {
            Console.WriteLine("垮裤 ");
        }
    }
    class TShirts : Finery
    {
        public override void Show()
        {
            Console.WriteLine("T恤 ");
        }
    }

    class Sneakers : Finery
    {
        public override void Show()
        {
            Console.WriteLine("破球鞋 ");
        }
    }

    class Suit : Finery
    {
        public override void Show()
        {
            Console.WriteLine("西服 ");
        }
    }

    class Tie : Finery
    {
        public override void Show()
        {
            Console.WriteLine("领带 ");
        }
    }

    class LeatherShoes : Finery
    {
        public override void Show()
        {
            Console.WriteLine("破球鞋 ");
        }
    }

客户端调用:

class Program
    {
        static void Main(string[] args)
        {
            Person xiaocai = new Person("小菜");
            Console.WriteLine("\n第一种装扮: ");
            Finery dtx = new TShirts();
            Finery kk = new BigTrouser();
            Finery pqx = new Sneakers();
            dtx.Show();
            kk.Show();
            pqx.Show();
            xiaocai.Show();

            Console.WriteLine("\n 第二种装扮:");
            Finery xz = new Suit();
            Finery ld = new Tie();
            Finery px = new LeatherShoes();
            xiaocai.Show();

        }
    }

结果同上。这个虽然做到了一定的分离,但是代码中出现了大量的Show()调用。这就是将穿的动作完全暴露出来。这里应该做一个封装。内部调用。

第三种方案走起:

class Person
    {
        public string name;

        public Person()
        {

        }

        public Person(string name)
        {
            this.name = name;
        }

        public virtual void Show()
        {
            Console.WriteLine("装扮的{0}", name);
        }
    }

    class Finery : Person
    {
        protected Person component;

        public void Decorate(Person component)
        {
            this.component = component;
        }

        public override void Show()
        {
            if (component != null)
            {
                component.Show();
            }
        }
    }

子类:

    class BigTrouser : Finery
    {
        public override void Show()
        {
            Console.WriteLine("垮裤 ");
            base.Show();
        }
    }
    class TShirts : Finery
    {
        public override void Show()
        {
            Console.WriteLine("T恤 ");
            base.Show();
        }
    }

    class Sneakers : Finery
    {
        public override void Show()
        {
            Console.WriteLine("破球鞋 ");
            base.Show();
        }
    }

    class Suit : Finery
    {
        public override void Show()
        {
            Console.WriteLine("西服 ");
            base.Show();
        }
    }

    class Tie : Finery
    {
        public override void Show()
        {
            Console.WriteLine("领带 ");
            base.Show();
        }
    }

    class LeatherShoes : Finery
    {
        public override void Show()
        {
            Console.WriteLine("破球鞋 ");
            base.Show();
        }
    }  

客户端调用:

 class Program
    {
        static void Main(string[] args)
        {
            Person xiaocai = new Person("小菜");
            Console.WriteLine("\n第一种装扮: ");
            Sneakers pqx = new Sneakers();
            BigTrouser kk = new BigTrouser();
            TShirts dtx = new TShirts();

            pqx.Decorate(xiaocai);
            kk.Decorate(pqx);
            dtx.Decorate(kk);
            dtx.Show();

            Console.WriteLine("\n 第二种装扮: ");
            LeatherShoes px = new LeatherShoes();
            Tie ld = new Tie();
            Suit xz = new Suit();

            px.Decorate(xiaocai);
            ld.Decorate(px);
            xz.Decorate(ld);
            xz.Show();
        }
    }

效果:

子类的每次装饰都会调用父类的Show方法。这样就将Show方法隐藏起来。好了,这就是今天介绍的装饰模式。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:44:41  更:2022-04-01 23:47:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/30 7:35:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码