zoukankan      html  css  js  c++  java
  • Head.First.ObjectOriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(五)

    好的设计产生灵活的软件-上(good design = flexible software part 1)

    ------------没有什么是一成不变的nothing ever stays the same

     

     

     引言

      变化是不可避免的。无论现在你多么喜欢你的软件,明天还是可能会改变。你把软件开发的越难以改变,相应用户的需求变更就越困难。在本篇中我们将会视图改进一个已有的系统,看看多么小的一个改变能导致大问题。

     正文

          先来看一个已有系统的类关系图。就是一个guitar销售商店,可以查询guitar,添加guitar。

          客户说最近他想卖mandolins曼陀林(一种琵琶类乐器),想要我们在系统中实现这个功能,并且可以针对这种乐器进行搜索。

          我们需要在原有系统中支持曼陀林这种新的乐器。既然是乐器,肯定和guitar有共同的地方,我们可以抽象出来。加入一个乐器类,表示曼陀林和guitar的抽象。

     

     

         

          其实在上图中,我们会发现,乐器的细节类和guitar的细节类,以及mandolin的细节类都很相似,还应该有个抽象的乐器细节类。把共同的细节信息都移到抽象类中。

          就会变成下面的结果

     

     

     

     

     

          在UML图中

          如上图所示,第一条是关系,也就是通常我们说的类之间的关系,1:1,1:n,n:1,之类的。第二条就是继承。第三条是集成,还不太理解,在后面理解了我们再来讨论他。

          由上面最后的两张类图,我们可以写出下面的代码。

     

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

    namespace BeautyCode.Common.ConApp.Head.First.OO.Design
    {
        
    public abstract class InstrumentSpec
        {
            
    private Builder _builder;
            
    private InstrumentType _type;
            
    private Wood _backwood;
            
    private Wood _topwood;
            
    public InstrumentSpec(Builder builder, InstrumentType type, Wood backwood, Wood topwood)
            {
                _builder 
    = builder;
                _topwood 
    = topwood;
                _type 
    = type;
                _backwood 
    = backwood;
            }
            
    public virtual  bool Matches(InstrumentSpec instance)
            {
                
    if (instance._builder != _builder)
                    
    return false;
                
    if (instance._backwood != _backwood)
                    
    return false;
                
    if (instance._topwood != _topwood)
                    
    return false;
                
    if (instance._type != _type)
                    
    return false;
                
    return true;

            }
        }
        
    public abstract class Instrument
        {
            
    private string _serialNumber;

            
    public string SerialNumber
            {
                
    get { return _serialNumber; }
            }
            
    private double _price;

            
    public double Price
            {
                
    get { return _price; }
            }
            
    private InstrumentSpec _spec;

            
    public InstrumentSpec Spec
            {
                
    get { return _spec; }
            }
            
    public Instrument(string serialNumber, double price, InstrumentSpec spec)
            {
                _serialNumber 
    = serialNumber;
                _price 
    = price;
                _spec 
    = spec;
            }

        }
    }


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

    namespace BeautyCode.Common.ConApp.Head.First.OO.Design
    {
        
    public class GuitarSpec : InstrumentSpec
        {
            
    private int _numString;

            
    public int NumString
            {
                
    get { return _numString; }

            }
            
    public GuitarSpec(Builder builder, InstrumentType type, Wood backwood, Wood topwood, int numString)
                : 
    base(builder,
                    type, backwood, topwood)
            {
                
    this._numString = numString;
            }
            
    public override bool Matches(InstrumentSpec instance)
            {
                
    if (!base.Matches(instance))
                    
    return false;
                
    if (!(instance is GuitarSpec))
                    
    return false;
                GuitarSpec spec 
    = instance as GuitarSpec;
                
    if (spec._numString != _numString)
                    
    return false;
                
    return true;
            }
        }

        
    public class Guitar : Instrument
        {
            
    public Guitar(string serialNumber, double price, GuitarSpec spec)
                : 
    base(serialNumber, price, spec)
            {
            }
        }
    }


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

    namespace BeautyCode.Common.ConApp.Head.First.OO.Design
    {
        
    public class MandolinSpec : InstrumentSpec
        {
            
    private Style _style;

            
    public Style Style
            {
                
    get { return _style; }
            }
            
    public MandolinSpec(Builder builder, InstrumentType type, Wood backwood, Wood topwood, Style style)
                : 
    base(builder,
                    type, backwood, topwood)
            {
                
    this._style = style;
            }
            
    public override bool Matches(InstrumentSpec instance)
            {
                
    if (!base.Matches(instance))
                    
    return false;
                
    if (!(instance is GuitarSpec))
                    
    return false;
                MandolinSpec  spec 
    = instance as MandolinSpec ;
                
    if (spec._style  != _style )
                    
    return false;
                
    return true;
            }
        }
        
    public class Mandolin : Instrument
        {
            
    public Mandolin(string serialNumber, double price, MandolinSpec spec)
                : 
    base(serialNumber, price, spec)
            {
            }
        }
    }


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

    namespace BeautyCode.Common.ConApp.Head.First.OO.Design
    {
        
    public class Inventory
        {
            
    private List<Instrument> _inventory;
            
    public Inventory()
            {
                _inventory 
    = new List<Instrument>();
            }
            
    public void AddInstrument(string serialNumber,double price,InstrumentSpec spec)
            {
                Instrument instance 
    = null;
                
    if (spec is GuitarSpec)
                {
                    instance 
    = new Guitar(serialNumber, price,(GuitarSpec ) spec);
                }
                
    else if (spec is MandolinSpec)
                {
                    instance 
    = new Mandolin(serialNumber, price, (MandolinSpec)spec);
                }
                _inventory.Add(instance);
            }
            
    public Instrument Get(string serialNumber)
            {
                
    return _inventory.Find(i => i.SerialNumber == serialNumber);
            }
            
    public List<Instrument> Search(MandolinSpec searchSpec)
            {
                List
    <Instrument> instances =  _inventory  .FindAll(i => i.Spec.Equals(searchSpec));
                
    return instances;
            }
        }
    }

     

         

     结论

         

    【Blog】http://virusswb.cnblogs.com/

    【MSN】jorden008@hotmail.com

    【说明】转载请标明出处,谢谢

  • 相关阅读:
    Python自动截图html页面
    filebeat+kafka+logstash+Elasticsearch+Kibana日志收集系统搭建
    k8s重要概念
    1721. 使括号有效的最少添加
    167. 链表求和
    272. 爬楼梯 II
    1609. 链表的中间结点
    SQL server查看触发器是否被禁用
    C#窗体内控件大小随窗体等比例变化
    微信接口返回码参考表
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1784438.html
Copyright © 2011-2022 走看看