乐趣区

初次接触装饰器

前言

前几天老师在优化重构我的代码的时候用到了装饰器,感觉装饰器是一个很有用的东西,在看学长的博客的时候也涉及装饰器,所以在这里讲一下我对装饰器的初步理解。

比喻

在网上看到一个很好的例子。内裤可以用来遮羞,但是到了冬天没法为我们防风御寒,聪明的人发明了长裤,有了长裤后就不会冷了,装饰器就像我们所说的长裤,在不影响短裤作用的前提下,长裤为我们提供了保暖的功能,也就是说装饰器在不影响原函数的功能下为我们提供了新功能。
学长对装饰器的比喻也很好,他把装饰器比喻成了咖啡店的服务生,我觉得咖啡有点苦,服务生把咖啡端走,给我带来了咖啡和糖。具体链接如下 https://segmentfault.com/a/1190000019148468
简单来说,装饰器会不影响原函数功能的情况下添加新功能。

为什么要有装饰器

装饰器本质上也是一个函数,我们知道,一个好的代码应该是对修改关闭,对扩展开放,这里说的应该就是装饰器了。装饰器可以让其他函数再不需要任何代码变动的前提下增加额外功能,它可以用于插入日志,性能测试,事务处理,缓存,权限校验等场景,有了装饰器,我们就可以抽离出大量与函数本身无关的雷同代码并继续重用。

举例

就拿我写的程序举例子,ListView是 c# 的一个样式 2,我们需要在
ListView 最上部加入我们的表格头原本是这样写的

this.listView1.Columns.Add("学号", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("姓名", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("数学", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("英语", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("政治", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("总分", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("平均分", 100, HorizontalAlignment.Center);
            this.listView1.Columns.Add("名次", 100, HorizontalAlignment.Center);
            this.listView1.View = System.Windows.Forms.View.Details;
        }

效果是这样的

我们发现,上述代码中用到的同一个函数 Columns.AddColumns.Add 函数需要传入 3 个变量,但是我们发现后二个参数是相同的,变化的只有第一个参数,我们可以装饰一下原函数

class YzListView
    {
        private ListView listView;

        private int width = 100;

        private HorizontalAlignment align = HorizontalAlignment.Center;

        public YzListView(ListView listView) {this.listView = listView;}

        public YzListView Add(string name) {return this.Add(name, this.width, this.align);
        }

        public YzListView Add(string name, int width) {return this.Add(name, width, this.align);
        }

        public YzListView Add(string name, int width, HorizontalAlignment align){this.listView.Columns.Add(name, width, align);
            return this;
        }
    }

因为 ListView 类的代码是不能修改的,所以我们定义一个新的类,并命名为 YzListView,构造函数中要传入ListView,并作接收,我们要对ListVIew 类中的 Columns.Add 函数做装饰。然后,我们再去装饰 ListVIew 类中的 Columns.Add 函数,通过对新定义的 Add 函数中传入的 name 参数,一层一层的做调用,最后调用 Columns.Add 函数,我们就实现了对 Columns.Add 函数的装饰。

结语

实践中才能对知识理解的更深,当我写代码的时候想到用装饰器的时候,就说明我真正理解装饰器了。

退出移动版