C#面向对象编程补充

来源:互联网 发布:医院数据分析方法 编辑:程序博客网 时间:2024/05/22 07:52


装饰者模式

装饰者模式就好比买了房子再在外为加个围墙,涂上一层漆,不用管房子里面是怎么样的,只需要修饰自己就行,不用管围墙围的是什么。

优点:

1. 装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活

2. 通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合

3. 装饰者模式有很好地可扩展性

缺点:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。

使用场景

1. 需要扩展一个类的功能或给一个类增加附加责任。

2. 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能

 

案例

    ///<summary>

    /// 定义抽象类computer

    /// </summary>

    abstract class  computer

    {

        public abstract void print();

        public abstract void view();

}

 

    /// <summary>

    /// 定义抽象类decorator

    /// </summary>

    abstract class decorator:computer

    {

        protected computer computer;

        public decorator(computer computer)

        {

            this.computer = computer;

        }

        public abstract void run();

        public abstract void usb();

}

 

    /// <summary>

    /// 定义computer实体类 华硕电脑

    /// </summary>

    class AsusComputer : computer

    {

        public override void print()

        {

            Console.WriteLine("this isasus computer");

        }

 

        public override void view()

        {

            Console.WriteLine("asuscomputer's view!");

        }

}

 

   /// <summary>

    /// 电脑能够插入u盘

    /// </summary>

    class Udisk : decorator

    {

        public Udisk(computer computer) :base(computer) {  }

        public override void print()

        {

            //执行实体类的print

            this.computer.print();

            ///在后面扩展其他

            Console.WriteLine("udiskptint");

        }

 

        public override void run()

        {

            this.computer.print();

            Console.WriteLine("insertUdisk");

        }

 

        public override void usb()

        {

            Console.WriteLine("read orwrite in Udisk");

        }

 

        public override void view()

        {

            readwrite();

        }

        private void readwrite()

        {

            Console.WriteLine("read orwrite in Udisk");

        }

    }

 

    /// <summary>

    /// 能够连接手机

    /// </summary>

    class Phone : decorator

    {

 

        public Phone(computer computer) :base(computer) { }

        public override void print()

        {

            Console.WriteLine("insertphone");

        }

 

        public override void run()

        {

            this.computer.print();

            Console.WriteLine("insertmobile phone usb");

        }

 

        public override void usb()

        {

            throw newNotImplementedException();

        }

 

        public override void view()

        {           

            readwrite();

        }

        private void readwrite()

        {

            Console.WriteLine("read orwrite in phone");

        }

}

 

static void Main(string[] args)

        {

           computer computer = new AsusComputer();

           computer.view();

            Udiskudisk = new Udisk(computer);

            Phonephone = new Phone(udisk);

           phone.run();

           udisk.print();

           udisk.run();

           

        }

 

运行结果:

asus computer's view!

this is asus computer

udisk ptint

insert mobile phone usb

this is asus computer

udisk ptint

this is asus computer

insert Udisk

 

 

单例模式

单例模式也叫单件模式,主要是初始化一个静态类,每次都返回它。本例子引用至: http://www.cnblogs.com/xun126/archive/2011/03/09/1970807.html

讲的很好,没做什么修改。

解析如下:

  1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;

  2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例;

  3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。

    class singleton

   {

        private static singleton  instance;

        private static object _lock = new object();

        ///<summary>

        ///饿汉模式,自己主动实例化,可以省去getsingletion中的加锁和判断,只需要return

        ///</summary>

        private static readonly singleton instance2 = new singleton();

        private singleton() { }

        int i = 0;

        public static singleton getsingletion()

        {

            if (instance == null) lock (_lock)instance = new singleton();

            Console.WriteLine("this is "+instance.i+"th time to return");

            instance.i++;

            return instance;

        }

}

        static void Main(string[] args)

        {

            singleton singleton =singleton.getsingletion();

            for (int i = 0; i < 6; i++)

            {

                Thread thread = new Thread(delegate () { singleton.getsingletion(); });

                thread.Start();

            }

       

 }

结果:this is 0th time to return

this is 1th time to return

this is 1th time to return

this is 3th time to return

this is 4th time to return

this is 5th time to return

this is 6th time to return

上述代码中函数getsingletion使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。

上面使用的readonly关键可以跟static一起使用,用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用GetInstance()后才实例化出唯一的单例对象。