【设计模式】之结构型模式

哈哈,小编又来了,这次给大家分享的是设计模式的第二大类型:结构型模式。废话不多说,看导图:

【设计模式】之结构型模式_第1张图片

1、适配器模式(Adaper):将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可一起工作。

注:在Gof的设计模式中,适配器模式分为:类适配器模式和对象适配器模式。类适配器模式,通过多重继承对一个接口与另一个接口进行匹配。但,C#、VB.NET、JAVA等语言不支持多重继承(C++支持),即单根性,只有一个父类,此处只讲对象适配器。

解决的问题:需要的东西就在面前,但却不能使用,而短时间又无法改造它,于是我们就想办法适配它。如:因电压不同,用电源适配器,把电源变成需要的电压。

何时使用:使用一个已经存在的类,但其方法和你的要求不相同时,考虑用适配器模式。客户端代码统一调用同一接口。如:姚明去国外打球,但因语言不通,需要一个翻译员。

关键代码:

    //球员
    abstract class Player
    {      
        public abstract void Attack();//进攻
        public abstract void Defense();//防守
    }

    //外籍中锋
    class ForeignCenter
    {       
        //表明‘外籍中锋’只懂得中文‘进攻’、‘防守’
        public void 进攻()
        {
            Console.WriteLine("外籍中锋{0}进攻",name);
        }
        public void 防守()
        {
            Console.WriteLine("外籍中锋{0}防守",name);
        }
    }

    //翻译者
    class Translator:Player 
    {
        //声明并实例化一个内部‘外籍中锋’对象,表明翻译者与外籍球员有关联
        private ForeignCenter wjzf = new ForeignCenter();
        
        //翻译者将‘Attack’翻译为‘进攻’告诉外籍中锋
        public override void Attack()
        {
            wjzf.进攻();
        }
    }

     //客户端
     Player ym = new Translator ("姚明");
     ym.Attack();

2、桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

注:实现指的是抽象类与它的派生类用来实现自已的对象。如:手机既可以按照品牌类分类,也可以按照功能来分类。

核心意图:由于实现的方式有多种,就是把这些实现独立出来,让它们各自地变化。使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。即减少耦合

关键:抽象手机品牌和抽象手机软件是聚合关系。手机品牌包含手机软件,但软件并不是品牌的一部分。

   //手机品牌
    abstract class HandsetBrand
    {
        protected HandsetSoft soft;
        //设置手机软件
        public void SetHandsetSoft(HandsetSoft soft)
        {
            this.soft = soft;
        }
    }
 
     客户端:

            HandsetBrand ab;
            ab = new HandsetBrandN();

            ab.SetHandsetSoft(new HandsetGame());
            ab.Run();

            ab.SetHandsetSoft(new HandsetAddressList());
            ab.Run();

3、组合模式:将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性

如:人力资源部和财务部都继承公司,重写其方法。

何时使用:需求中体系部分与整体层次的结构时,及可忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时

好处:

1)定义了基本对象和组合对象,基本对象可以被组合成更复杂的组合对象,客户代码中,任何用到基本对象的地方都可以使用组合对象。

2)客户可以一致地使用组合结构和单个对象。

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

优点:把类中的装饰功能从类中搬移去除,简化原有的类。有效地把类的核心职责和装饰功能区分开了,可以去除相关类中重复的装饰逻辑。

注意:装饰模式的装饰顺序很重要,最理想的情况是保证装饰之间彼此独立,这样可以任意的顺序进行组合。

 class Finery:Person     //关键代码
    {
        protected Person component;  

        //打扮
        public void Decorate(Person component)  //普通方法
        {
            this.component = component;
        }
        public override void Show()     //方法重写
        {
            if (component !=null )
            {
                component.Show();
            }
        }
    }

    class TShirts:Finery
    {
        public override void Show()
        {
            Console.WriteLine("大T恤");
            base.Show();   //调用父类方法
        }
    }

客户端:
      //装饰过程   体现穿衣顺序
            pqx.Decorate(xc);
            kk.Decorate(pqx);
            dtx.Decorate(kk);
            dtx.Show();

5、外观模式(Façade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

总结:高层接口方法中调用了所有子类的方法。

客户端只需实例化接口,调用接口的方法即可。其他类的方法都被接口封装了,调用接口的方法即调用了其他所有类的方法。

何时使用:设计初期、开发阶段、维护大型系统时。

6、享元模式:运用共享技术有效地支持大量细粒度的对象。

目的:减少实例化的类的数量,节省存储开销

应用:功能类似,差别不大。

关键代码:

    //网站工厂
    class WebSiteFactory
    {
        private Hashtable flyweights = new Hashtable();
        //获得网站分类
        public WebSite GetWebSiteCategory(string key)
        {
          //判断是否存在这个对象,如果存在,则直接返回,若不存在,则实例化它再返回。
            if (!flyweights .ContainsKey (key))
                flyweights.Add(key, new ConcreteWebSite(key));                     
            return ((WebSite)flyweights[key]);
        }
     }

      static void Main(string[] args)
        {
            WebSiteFactory f = new WebSiteFactory();

            WebSite fx = f.GetWebSiteCategory("产品展示");
            fx.Use(new User("小菜"));

            WebSite fy = f.GetWebSiteCategory("产品展示");//共享上方生成的对象,不再实例化
            fx.Use(new User("大鸟"));
        }

7、代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。

关键:Pursuit(追求者)和Proxy(代理)都有送礼物的三个方法,只不过Proxy送的礼物是Pursuit买的,实质是Pursuit送的。因此,追求者和代理都实现了同样的接口(送礼物的)

 class Pursuit :IGiveGift     //追求者类
    {
        SchoolGirl mm;
        public Pursuit (SchoolGirl mm)
        {
            this.mm = mm;
        }
    }

  class Proxy:IGiveGift     //代理类
    {
        Pursuit gg;
        public Proxy (SchoolGirl mm)
        {
            gg = new Pursuit(mm);   
        }
        public void GiveDolls()
        {
            gg.GiveDolls();  //在实现方法中去调用“追求者”类的相关方法
        }
    }

 

你可能感兴趣的:(《设计模式》)