代码改变世界

《深入浅出设计模式-中文版》读书笔记-继承与组合(三)

2010-07-03 16:53  Virus-BeautyCode  阅读(2197)  评论(1编辑  收藏  举报

  经过上一次的改造,鸭子类不是靠继承行为接口而拥有行为,而是靠调用者指定行为的方式。例如:指定叫声的形式和飞的形式。保留了灵活性,将权利交给调用者,鸭子本身不再负责行为的初始化。具体的行为表现交给指定的行为方式处理。如果需要有新的行为方式定义,只要实现行为的接口,然后给鸭子指定新定义的行为方式即可。

  就像上一回的例子中,将几个类结合起来使用,这就是组合composition。这种做法和“继承”不同的地方就是,鸭子的行为不是继承来的,而是和适当的行为对象“组合”来的。

  这就是第三个设计原则:

  多用组合,少用继承。
  使用组合使系统具有很大的弹性,可以在运行的时候动态指定行为,只要行为是符合标准的接口即可。当然,组合也不是万能的,没有银弹,在后面会讲到它的优缺点。

  这种设计使得行为成为一个族群,一个算法群,可以使用里面的任何一个实现来替换。

  恭喜你,你已经在使用设计模式了。也就是策略模式(Strategy Pattern),不用怀疑,你正在使用策略模式改进你的代码。

  策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

  

  关于继承和组合的一点个人想法:

  我认为继承适合用在继承属性上面,例如外观、长相、显示、拥有的物品之类的。如果是行为之类的,就不适合用继承了,适合使用组合。因为继承会使得所有继承类都拥有了相同的行为方式,可能会不是想要的结果。使用组合可以灵活的定义行为、扩展行为,把行为的权力交给了初始化对象的调用者,调用者可以自己选择或者是扩展行为的方式。

  

  设计谜题

  内容:一个游戏场景,游戏中各种角色,还有各种武器。角色可以使用武器,每次只能使用一个武器,但是在游戏的过程中可以更换武器。

  

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BeautyCode.DesignPattern.Head.First
{
    
public interface IWeaponBehavior
    {
        
void UseWeapon();
    }
    
public class KnifeBehavior : IWeaponBehavior
    {
        
public void UseWeapon()
        {
            
throw new NotImplementedException();
        }
    }
    
public class BowAndArrowBehavior : IWeaponBehavior
    {
        
public void UseWeapon()
        {
            
throw new NotImplementedException();
        }
    }
    
public class AxeBehavior : IWeaponBehavior
    {
        
public void UseWeapon()
        {
            
throw new NotImplementedException();
        }
    }
    
public class Sword : IWeaponBehavior
    {
        
public void UseWeapon()
        {
            
throw new NotImplementedException();
        }
    }
    
public abstract class Character
    {
        
private IWeaponBehavior _weapon;

        
public IWeaponBehavior Weapon
        {
            
get { return _weapon; }
            
set { _weapon = value; }
        }
        
public void Fight()
        {
            _weapon.UseWeapon();
        }
    }
    
public class King:Character 
    {
        
    }
    
public class Queen : Character
    {
    }
    
public class Knight : Character
    {
    }
    
public class Troll : Character
    {
    }
}

 

  调用代码

  

Head.First.King king = new Head.First.King();
            king.Weapon 
= new Head.First.Sword();
            king.Fight();

 

  这个例子也是对前面的一个练习和巩固。关于对象的创建,可以重构为在第一片《深入浅出设计模式-中文版》读书笔记(一) 中讲解的简单工厂来实现。

  如何使用设计模式

  设计模式不会直接进入你的代码中,而是先进入你的大脑。首先要对设计模式有一个概念的理解,关于模式的原理,可以解决的问题,应用的场景,模式的代码结构等等。然后才能在设计新模块的时候,合适的引入模式,并且在以前的代码变得一团糟而没有弹性的时候,可以重构它们,重构到模式。

  良好的OO需要具备:可复用性、可扩充性、可维护性。

  模式不是代码,而是针对设计问题的通用解决方案。你可以把他们应用到特定的应用中。

  我们通常会把系统中变化的部分抽出来封装。

  OO基础

  •   抽象
  •   封装
  •   多态
  •   继承

  OO原则

  •   封装变化
  •   多用组合,少用继承
  •   针对接口编程,不针对实现编程

  OO模式

  •   策略模式-定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。