c# 装饰器模式

c# 装饰器模式

  • 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

  • 所以:装饰器和适配器最大得区别在

    • 装饰器 是功能不满足 扩展功能

    • 适配器 是功能满足 但是需要转换输出

https://www.bilibili.com/video/BV194411y7dp?p=7

利用装饰器模式

写如下 缓冲区 代码

思路:

1.继承stream 实现Read(byte[] buffer, int offset, int count)接口 其实就是保持base.read()的调用不变

2.实现自己的一个字节一个字节取得Read()方法

核心:将Stream流通过构造函数传过来

class MyBufferedStream2 : Stream
{
    private const int DefaultBufferSize = 163804;
    private Stream stream;
    private byte[] cb;
    private int index;
    private int count;

    public MyBufferedStream2(Stream stream, int bufferSize)
    {
        this.stream = stream;
        this.cb = new byte[bufferSize];

    }

    public MyBufferedStream2(Stream stream)
        : this(stream, DefaultBufferSize)
        {

        }

    private void EnSureCanOpen()
    {
        if(stream.CanRead == false)
        {
            _BufferError.StreamIsColse();
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return stream.Read(buffer, offset, count);
    }

    public int Read()
    {
        EnSureCanOpen();
        if (count == 0)
        {
            count = Read(cb, 0, cb.Length);
            index = 0;
        }
        if (count == 0 )
        {
            unchecked
            {
                return -1;
                //return (byte)-1;
            }

        }

        byte b = cb[index];
        index++;
        count--;
        return b;
    }








    public override bool CanRead => throw new NotImplementedException();

    public override bool CanSeek => throw new NotImplementedException();

    public override bool CanWrite => throw new NotImplementedException();

    public override long Length => throw new NotImplementedException();

    public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

    public override void Flush()
    {
        throw new NotImplementedException();
    }



    public override long Seek(long offset, SeekOrigin origin)
    {
        throw new NotImplementedException();
    }

    public override void SetLength(long value)
    {
        throw new NotImplementedException();
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        throw new NotImplementedException();
    }
}
internal static class _BufferError
{
    internal static void StreamIsColse()
    {
        throw new ObjectDisposedException("file closed");
    }
}

调用:

//因为FileStream 自带缓冲区!!!! 所以我们将它改为1
FileStream fs2 = new FileStream(path,FileMode.Open, FileAccess.Read,FileShare.Read,1);

sw.Start();
while ((c = fs2.ReadByte()) != -1)
{
    //Console.WriteLine((char)c);
}
fs2.Close();
sw.Stop();
Console.WriteLine((sw.Elapsed.TotalSeconds));
sw.Reset();


MyBufferedStream2 mbs2 = new MyBufferedStream2(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 1));
sw.Start();
while ((c = mbs2.Read()) != -1)
{
    //Console.WriteLine((char)c);
}
sw.Stop();
Console.WriteLine((sw.Elapsed.TotalSeconds));

输出结果

0.032399
0.0012816

测试文件生成:

string path = "c:/abc.txt";
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
    BufferedStream bfs = new BufferedStream(fs);
    byte[] bytes = Encoding.UTF8.GetBytes("hello world\n");
    for (int i = 0; i < 1000; i++)
    {
        bfs.Write(bytes, 0, bytes.Length);
    }
    bfs.Close();
}

简单 举例2:

namespace Decorator
{
    abstract class AbstractRobot
    {
        public abstract void Walk();
    }

    internal class MyRobot : AbstractRobot
    {
        public override void Walk()
        {
            Console.WriteLine("myrobot walk");
        }
    }

    internal class BaseDecorator : AbstractRobot
    {
        private AbstractRobot robot;

        public BaseDecorator(AbstractRobot robot)
        {
            this.robot = robot;
        }
        public override void Walk()
        {
            robot.Walk();
        }
    }

    internal class RobotDecorator : BaseDecorator
    {
        
        public RobotDecorator(AbstractRobot robot) :base( robot) {}

        public override void Walk()
        {
            base.Walk();
            Console.WriteLine("after walking ,song a song");
        }


        public void Laugh()
        {
            Console.WriteLine("laugh!");
        }
    }
}
//调用
 static void Main(string[] args)
 {
     AbstractRobot robot = new MyRobot();
     RobotDecorator robotDecorator = new RobotDecorator(robot);
	//扩展一个功能 让机器人能走完后自动唱歌
     robotDecorator.Walk();
     robotDecorator.Laugh();
 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值