Unity设计模式---合成复用原则

68 阅读3分钟

合成复用原则

合成复用原则:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新对象通过委派达到复用已有功能的目的。

简而言之,要尽量使用对象合成/聚合,尽量不要使用继承

区分"has-A"和"is-A"是严格的分类学意义定义,意思是一个类是另一个类的一种。而"has-A"则不同,它表示某一角色具有某一项责任。导致错误的使用继承而不是合成/聚合的一个常见原因是错误地将"has-A"当作"is-A"。

面向对象设计原则中继承的限制:对象的继承关系在编译时就已经确定好了,所以无法在运行时改变从父类继承的实现,子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其它更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

合成和复用都是关联的特殊种类,复用表示一种"拥有"关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。

合成则是一种强的"拥有"关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。比如:复用体现在一只大雁和一群大雁,合成体现在大雁与翅膀。

盲目使用继承会影响程序的扩展和修改,本质原因是继承是一种强耦合结构,父类变,子类就要变。使用继承时要在"is-a"关系时再考虑使用,而不是任何时候都去使用。

合成复用原则分析

在面向对象设计中,可以通过两种基本方法在不同的环境中复用已有的设计和实现,即通过组合/聚合关系或通过继承。

继承复用:实现简单,易于拓展。破坏系统的封装性;从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性;只能在有限的环境中使用。("白箱复用")。(子类与父类) 使用继承时,需要严格遵守里氏替换原则。要避免在程序系统设计中出现一个类的继承层次超过3次。

合成复用:耦合度相对较低,选择性地调用成员对象的操作;可以在运行时动态进行。("黑箱复用")(个体与整体)。

合成复用原则实例


namespace 合成复用原则
{
    //合成复用原则
    //人和嘴巴
    public class Head
    {
         private Mouth mouth;
         public Head() 
        {
            mouth = new Mouth();
        }
    }
    public class  Mouth
    {
           
    }
    //汽车和引擎
    public class Car
    { 
        private Engine engine;
        public Car(Engine engine) 
        { 
            this.engine = engine;
        }
        public void SetEngine(Engine engine) 
        { 
            this.engine=engine;
        }
    }

    public class Engine 
    { 
    
    }

    //操作系统和手机
    public class IOS
    { 
    
    }

    public class Iphone5
    {
        private IOS iOS;
        public Iphone5(IOS iOS) 
        { 
            this.iOS = iOS;
        }

        public void CreateIphone()
        {
            Console.WriteLine("我有一台Ipone5,上面搭载有IOS操作系统");
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            Iphone5 iphone5 = new Iphone5(new IOS());
            iphone5.CreateIphone();
            Console.Read();
        }
    }
}