31日間で学習ノート11を再構築する.ポリシークラスの使用


要旨:最近リビルドのプロジェクトをしているため、リビルドについてもう一度学習と整理を行い、31日間のリビルドについて最初に接触したのは2009年10月で、当時はSean Chambersのblogを購読していなかったため、海外のコミュニティをぶらぶらしている間にリンクしたことがある.シリーズ全体を一気に見終わったのを覚えていますが、これらの基本的なプロジェクトは使用されていますが、私たちはそれを表示したり整理したりしていないので、あまり重視されていません.今突然この再構築プロジェクトを引き継ぐと、チームメンバーの技術と経験がバラバラになっているため、再構築の要綱を専門に整理する必要があります.もちろん、このシリーズも新しいシステムのコード規範の参考に適しています.コードの場所があれば、この再構築規範は価値があります.週末もぶらぶらしたくないし、この美しい町に着いたばかりなので、親戚や友达がいないので、2日間落ち着いてこの再構築の参考規範を書くことができます.Windows Live writerで文章を書く快感も感じました.もちろん再構築された全体的なアーキテクチャは別です(全体的なアーキテクチャは私のこの文章で専門的な説明があります(http://www.cnblogs.com/zenghongliang/archive/2010/06/23/1763438.html). 大きなアーキテクチャが設計された後、これらの再構築の細部点は東風の後の大火となり、プロジェクト全体にとっても重要である.31日間でこのシリーズを再構築するのは、「コード大全」、「再構築:既存のコードの設計を改善する」と比較すると、比較的簡単で分かりやすいのが最大の特徴です.では、私もこれらの文章はSean Chambersの31日間の再構築を学ぶノート整理なので、このノートに異議があれば指摘してもいいです.
具体的にはhttp://www.lostechies.com/blogs/sean_chambers/archive/2009/07/31/31-days-of-refactoring.aspx原文を調べる.
 
コンセプト:本明細書の「ポリシークラスの使用」とは、従来のswitch case文とif else文を設計モードのポリシーモードで置き換えることで、結合を解くことができ、メンテナンス性とシステムの拡張性を大幅に向上させることを意味します.
 
本文:次のコードに示すように、
ClientCodeクラスはより列挙されます
Stateの値で呼び出す
ShippingInfoの方法は異なりますが、このように多くの判断文が生まれ、コード量が大きくなるとクラスが大きくなるとメンテナンス中に変更も大きくなり、1つの場所を変更するたびに構造全体をコンパイル(複数のエンジニアリングであれば)しなければならないので、それを再構築し、結合を剥がすことを考えました.
namespace LosTechies.DaysOfRefactoring.SwitchToStrategy.Before
{
public class ClientCode
{
public decimal CalculateShipping()
{
ShippingInfo shippingInfo = new ShippingInfo();
return shippingInfo.CalculateShippingAmount(State.Alaska);
}
}

public enum State
{
Alaska,
NewYork,
Florida
}

public class ShippingInfo
{
public decimal CalculateShippingAmount(State shipToState)
{
switch (shipToState)
{
case State.Alaska:
return GetAlaskaShippingAmount();
case State.NewYork:
return GetNewYorkShippingAmount();
case State.Florida:
return GetFloridaShippingAmount();
default:
return 0m;
}
}

private decimal GetAlaskaShippingAmount()
{
return 15m;
}

private decimal GetNewYorkShippingAmount()
{
return 10m;
}

private decimal GetFloridaShippingAmount()
{
return 3m;
}
}
}

 
再構築されたコードは次のように抽象化されています.
IShippingCalculationインタフェース
ShippingInfoクラスのGetAlaskaShippingAmount、GetNewYorkShippingAmount、GetFloridaShippingAmountの3つの方法をそれぞれ3つのクラスに抽出し、
IShippingCalculationインタフェースは、呼び出し時に
IEnumerable<
IShippingCalculation>は、以前のswitch case文を解除し、IOCのやり方とよく似ています.
 
using System;
using System.Collections.Generic;
using System.Linq;

namespace LosTechies.DaysOfRefactoring.SwitchToStrategy.After_WithIoC
{
public interface IShippingInfo
{
decimal CalculateShippingAmount(State state);
}

public class ClientCode
{
[Inject]
public IShippingInfo ShippingInfo { get; set; }

public decimal CalculateShipping()
{
return ShippingInfo.CalculateShippingAmount(State.Alaska);
}
}

public enum State
{
Alaska,
NewYork,
Florida
}

public class ShippingInfo : IShippingInfo
{
private IDictionary<State, IShippingCalculation> ShippingCalculations { get; set; }

public ShippingInfo(IEnumerable<IShippingCalculation> shippingCalculations)
{
ShippingCalculations = shippingCalculations.ToDictionary(calc => calc.State);
}

public decimal CalculateShippingAmount(State shipToState)
{
return ShippingCalculations[shipToState].Calculate();
}
}

public interface IShippingCalculation
{
State State { get; }
decimal Calculate();
}

public class AlaskShippingCalculation : IShippingCalculation
{
public State State { get { return State.Alaska; } }

public decimal Calculate()
{
return 15m;
}
}

public class NewYorkShippingCalculation : IShippingCalculation
{
public State State { get { return State.NewYork; } }

public decimal Calculate()
{
return 10m;
}
}

public class FloridaShippingCalculation : IShippingCalculation
{
public State State { get { return State.Florida; } }

public decimal Calculate()
{
return 3m;
}
}
}
 

まとめ:この再構成は設計モードの中でそれを単独で名前をつけた--戦略モードで、このような利点は結合を隔てて、注入の形式で機能を実現することができて、これは機能を増加して更に容易で簡便になって、同様に全体のシステムの安定性と丈夫性を強化しました.