重构与模式_ppt [兼容模式].pdf
重构与模式重构与模式何谓重构何谓重构?重构是一种对软件内部结构的改善,目的是在不改变软件的可见行为的情况下,使其更理解,修改成本更低。可读性好的代码可读性好的代码?Ward Cuinningham?创造了CRC(Class-Responsibility-Collaboration)卡?Wiki Web?极限编程?根据日期进行检查?看看可读性好的代码?november(20,2005)?调用了 public void Date november(int day,int year)?还可以直接这样实现?java.util.Calendar c=java.util.Calendar.getInstance();?c.set(2005,java.util.Calendar.NOVEMBER,20);?c.getTime();?但可读性好的代码?读起来像自然语言?将重要代码与分散注意力的代码分离开来不好的代码不好的代码?最常见的设计问题都出自这样的代码?重复?不清晰?复杂面对很多包含重复代码的构造函数面对很多包含重复代码的构造函数public class Loan public Loan(float notional,float outstanding,int rating,Date expiry)this.strategy=new TermROC();this.notional=notional;this.outstanding=outstanding;this.rating=rating;this.expiry=expiry;public Loan(float notional,float outstanding,int rating,Date expiry,Date maturity)this.strategy=new RevolvingTermROC();this.notional=notional;this.outstanding=outstanding;this.rating=rating;this.expiry=expiry;this.maturity=maturity;public Loan(CapitalStrategy strategy,float notional,float outstanding,int rating,Date expiry,Date maturity)this.strategy=strategy;this.notional=notional;this.outstanding=outstanding;this.rating=rating;this.expiry=expiry;this.maturity=maturity;把构造函数链接起来,从而获得最少的代码重复把构造函数链接起来,从而获得最少的代码重复public class Loan public Loan(float notional,float outstanding,int rating,Date expiry)this(new TermROC(),notional,outstanding,rating,expiry,maturity);public Loan(float notional,float outstanding,int rating,Date expiry,Date maturity)this(new RevolvingTermROC(),notional,outstanding,rating,expiry,maturity);public Loan(CapitalStrategy strategy,float notional,float outstanding,int rating,Date expiry,Date maturity)this.strategy=strategy;this.notional=notional;this.outstanding=outstanding;this.rating=rating;this.expiry=expiry;this.maturity=maturity;用用Factory Method引入多态创建引入多态创建?一个层次中的类都相似地实现一个方法,只是对象创建的步骤不同DOMBuilderTest+testAddAboveRoot():voidXMLBuilderTest+testAddAboveRoot():voidbuilder=new DOMBuilder(“order”);builder=new XMLBuilder(“order”);用用Factory Method引入多态创建引入多态创建?创建调用Factory Method来处理实例化的方法的唯一超类版本AbstractBuilderTest#builder:OUtputBuilderbuilder=createBuilder(“orders”)#createBuilder(rootName:String):OutputBuilder+testAddAboveRoot():voidDOMBuilderTest#createBuilder(rootName:String):OutputBuilderXMLBuilderTest#createBuilder(rootName:String):OutputBuilder用用Strategy替换条件逻辑替换条件逻辑Loancapital:doublecapital()if(expiry=null&maturyty!=null)return commitment*duration()*riskFactor();用用Strategy替换条件逻辑替换条件逻辑Loancapital:doublecapital()return capitalStrategy.capital(this);为每个变体创建一个Strategy并使方法把计算委托到Strategy实例CapitalStrategycapital(loan:Loan):doubleCapitalStrategyAdvisedLine capital(loan:Loan):doubleCapitalStrategyRevolvercapital(loan:Loan):double形成形成Template Method?子类中的两个方法以相同的顺序执行相似的步骤,但是步骤并不完全相同CapitalStrategycapital(loan:Loan):doubleCapitalStrategyAdvisedLine capital(loan:Loan):doubleCapitalStrategyTermLoancapital(loan:Loan):doubleReturn loan.getCommitment()loan.getUnusedPercentage()duration(loan)riskFactorfor(loan);Return loan.getCommitment()duration(loan)riskFactorfor(loan);形成形成Template Method?通过把这些步骤提取成具有相同签名的方法来泛化这两个方法,然后上移这些泛化方法,形成Template MethodCapitalStrategycapital(loan:Loan):doubleduration(loan:Loan):doubleriskFactorfor(loan):doubleriskAmountFor(loan:Loan):doubleCapitalStrategyAdvisedLine riskAmountFor(loan:Loan):doubleCapitalStrategyTermLoanduration(loan:Loan):double riskAmountFor(loan:Loan):doubleReturn loan.getCommitment()loan.getUnusedPercentage()Return loan.getCommitment()Return riskAmountFor(loan:Loan)duration(loan)riskFactorfor(loan);应用组合方法应用组合方法public void add(Object element)if(!readonly)int newSize=size+1;if(newSize elements.length)object newElements=new Objectelements.length+10;for(int i=0;I size;i+)newElementsi=elementsi;elements=newElements;elementssize+=elements;无法迅速地理解一个方法的逻辑应用组合方法应用组合方法public void add(Object element)if(readonly)return;if(atCapacity()grow();addElement(element);把方法的逻辑转换成几个同一细节层面上的、能够说明意图的步骤用用Command替换条件调度程序替换条件调度程序?条件逻辑用来调度请求和执行操作If(actionName.equals(NEW_WORKSHOP)/lots of code to create a new workshop else if(actionName.equals(ALL_WORKSHOPS)/用用Command替换条件调度程序替换条件调度程序?为每个动作创建一个Command?把这些Command存储在一个集合中,并用获取及执行Command的代码替换条件逻辑Commandexecute():HandlerResponseNetWorkshopHandler execute():HandlerResponseAllWorkshopHandlerexecute():HandlerResponse用用Composite模式替换隐含树模式替换隐含树Xml.append(“”);For(int i=0;i orders.getOrderCount();i+)Order order=orders.getOrder(i);Xml.append(“”);for(int j=0;jorder.getProductCount();j+)Product product=Products.getProduct(i);Xml.append(“”);Xml.append(“”);Xml.append(“product.getPrice”);Xml.append(“/price”);Xml.append(“product.getName();Xml.append(“/product”);Xml.append(“”);Xml.append(“”);TagNode-attributes:String-tagName:String-children:List+TagNode(name:String)+add(childNode:TagNode)+addAttribute()+addValue()+toString():StringTransparentTreeComponent:抽象构件public interface TransparentTreeComponentvoid Display();void Add(TransparentTreeComponent treeBranch);void Remove(TransparentTreeComponent treeBranch);TransparentTreeBranch:树枝构件class TransparentTreeBranch:TransparentTreeComponent protected string _name;public string Nameget return _name;set _name=value;public TransparentTreeBranch(string Name)this.Name=Name;private ArrayList treeBranch=new ArrayList();public void Display()IEnumerator treeEnumerator=treeBranch.GetEnumerator();while(treeEnumerator.MoveNext()if(treeEnumerator.Current is TransparentTreeBranch)Console.WriteLine(树枝:+this.Name);public void Add(TransparentTreeComponent ttc)treeBranch.Add(ttc);public void Remove(TransparentTreeComponent ttc)treeBranch.Remove(ttc);TransparentTreeLeaf:树叶构件class TransparentTreeLeaf:TransparentTreeComponentprotected string _name;public string Nameget return _name;set _name=value;public TransparentTreeLeaf(string Name)this.Name=Name;public void Display()Console.WriteLine(this.Name);public void Add(TransparentTreeComponent ttc)public void Remove(TransparentTreeComponent ttc)客户端应用代码class Programstatic void Main(string args)TransparentTreeBranch troot=new TransparentTreeBranch(Root);troot.Add(new TransparentTreeLeaf(LeafRoot-1);troot.Add(new TransparentTreeLeaf(LeafRoot-2);TransparentTreeBranch tb1=new TransparentTreeBranch(TB1);tb1.Add(new TransparentTreeLeaf(LeafTB1-1);tb1.Add(new TransparentTreeLeaf(LeafTB1-2);Console.WriteLine(-透明式-);Console.WriteLine(透明式Root根下含有);troot.Add(tb1);troot.Display();Console.WriteLine(透明式Branch1下含有);tb1.Display();Console.ReadLine();#endregion用用State替换状态改变条件语句替换状态改变条件语句SystemPermissionState:StringREQUESTED:StringCLAIMED:StringGRANTED:StringDENIED:StringUNIX_REQUESTED:StringUNIX_CLAIMED:StringclaimedBy():voidgrantedBy():voiddeniedBy():voidIf(state!=REQUESTED&state!=UNIX_REQUESTED return;willBehandledBy(admin);If(state=REQUESTED)state=CLAIMED;Else if(state=UNIX_REQUESTED)state=UNIX_CLAIMED;?控制一个对象状态转换的条件表达式过于复杂SystemPermissionclaimedBy():voidgrantedBy():voiddeniedBy():voidpermissionState.claimedBy();PermissionStatename:StringREQUESTED:PermissionStateCLAIMED:PermissionStateGRANTED:PermissionStateDENIED:PermissionStateUNIX_REQUESTED:PermissionStateUNIX_CLAIMED:PermissionStatePermissionState(name:String)PermissionClaimed grantedBydeniedByPermissionRequestedclaimedBy