《软件设计精要与模式》读书笔记(三)

第三章 体验重构

     个人强烈推荐《重构--改善既有代码的设计》(不过建议有2年以上的开发人员看,太早看是浪费时间)。

     

     本章,作者用来一个阶乘容器的设计来说明重构。

3.1 一个阶乘容器

     通常,作为一个初学者,我们的代码最初会设计如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
class FactorialContainer
    {
        
public FactorialContainer()
        {
            m_factorialList 
= new ArrayList();
        }
        
public FactorialContainer(int capacity)
        {
            m_capacity 
= capacity;
            m_factorialList 
= new ArrayList(capacity);
        }
        
protected ArrayList m_factorialList;
        
protected int m_capacity;
        
        
public int Capacity
        {
            
get { return m_capacity; }
            
set { m_capacity = value; }
        }
        
public long this[int index]
        {
            
get { return (long)m_factorialList[index]; }
            
set { m_factorialList[index] = value; }
        }
        
public void Add()
        {
            
long result = 1;
            
int seed = m_factorialList.Count + 1;
            
for (int i = 1; i <= seed; i++)
            {
                result 
*= i;
            }

            m_factorialList.Add(result);
        }
        
public void RemoveAt(int index)
        {
            m_factorialList.RemoveAt(index);
        }
        
public void Clear()
        {
            m_factorialList.Clear();
        }
    }

 

3.2 代码的坏味道

     上面的代码计算阶乘的算法与元素的添加行为紧密的纠缠在一起。根据职责分离原则,需要进行分离。

 

ContractedBlock.gif ExpandedBlockStart.gif Code
public void Add()
        {
            
long result = CountFactorial();
            m_factorialList.Add(result);
        }
private long CountFactorial()
        {
            
long result = 1;
            
int seed = m_factorialList.Count + 1;
            
for (int i = 1; i <= seed; i++)
            {
                result 
*= i;
            }

            
return result;
        }

 

3.3 需求发生变化

     后来我们的需求发生变化,需要增加菲波那契数列的计算。

     经过重构:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
public abstract class MathContainer
    {
        
public MathContainer()
        {
            m_mathList 
= new ArrayList();
        }
        
public MathContainer(int capacity)
        {
            m_capacity 
= capacity;
            m_mathList 
= new ArrayList(capacity);
        }
        
protected ArrayList m_mathList;
        
protected int m_capacity;
        
        
public int Capacity
        {
            
get { return m_capacity; }
            
set { m_capacity = value; }
        }
        
public long this[int index]
        {
            
get { return (long)m_mathList[index]; }
            
set { m_mathList[index] = value; }
        }
        
public void Add()
        {
            m_mathList.Add(Count());
        }
        
public void RemoveAt(int index)
        {
            m_mathList.RemoveAt(index);
        }
        
public void Clear()
        {
            m_mathList.Clear();
        }
        
protected abstract long Count();
    }

 

 

ContractedBlock.gif ExpandedBlockStart.gif Code
public class FactorialContainer : MathContainer
    {
        
public FactorialContainer() : base() { }
        
public FactorialContainer(int capacity) : base(capacity) { }
        
protected override long Count()
        {
            
long result = 1;
            
int seed = m_factorialList.Count + 1;
            
for (int i = 1; i <= seed; i++)
            {
                result 
*= i;
            }
            
return result;
        }
    }
public class FibonacciContainer : MathContainer
    {
        
public FibonacciContainer() : base() { }
        
public FibonacciContainer(int capacity) : base(capacity) { }
        
protected override long Count()
        {
            
long result = 0;
            
int seed = m_mathList.Count;
            
if (seed == 0 || seed == 1)
            {
                result 
= 1;
            }
            
else
            {
                result 
= this[seed - 1+ this[seed - 2];
            }
            
return result;
        }
    }

     呵呵,上面是Template Method 模式。

 

3.5引入设计模式

     使用工厂模式来管理实例的创建。

 

ContractedBlock.gif ExpandedBlockStart.gif Code
public abstract class MathFactory
    {
        
public abstract MathContainer CreateInstance();
        
public abstract MathContainer CreateInstance(int capacity);
    } 
public class FactorialFactory : MathFactory
    {
        
public override MathContainer CreateInstance()
        {
            
return new FactorialContainer();
        }
        
public override MathContainer CreateInstance(int capacity)
        {
            
return new FactorialContainer(capacity);
        }
    } 
public class FibonacciFactory : MathFactory
    {
        
public override MathContainer CreateInstance()
        {
            
return new FibonacciContainer();
        }
        
public override MathContainer CreateInstance(int capacity)
        {
            
return new FibonacciContainer(capacity);
        }
    } 

 

     通过工厂对象,通过它来创建需要的具体容器类对象了。

 

ContractedBlock.gif ExpandedBlockStart.gif Code
[STAThread]
        
static void Main(string[] args)
        {
            MathFactory factory1 
= new FactorialFactory();
            MathFactory factory2 
= new FibonacciFactory();

            MathContainer factorial 
= factory1.CreateInstance();
            MathContainer fibonacci 
= factory2.CreateInstance();

            Console.WriteLine(
"Count Factorial form 1 to 8:");
            
for (int i = 1; i <= 8; i++)
            {
                factorial.Add();
            }
            
for (int i = 0; i < 8; i++)
            {
                Console.WriteLine(factorial[i].ToString());
            }

            Console.WriteLine();
            Console.WriteLine(
"Count Fibonacci form 1 to 8:");

            
for (int i = 1; i <= 8; i++)
            {
                fibonacci.Add();
            }
            
for (int i = 0; i < 8; i++)
            {
                Console.WriteLine(fibonacci[i].ToString());
            }
            Console.ReadLine();

        }

 

 

转载于:https://www.cnblogs.com/stan0714/archive/2008/08/09/1264260.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值