关于代码的重构问题!!设计模式~原则!!谢谢大家!!!!

问题描述

假设实体类ClassA有属性abcdefg.现在我需要向ClassA对应表中插入六条记录。其中ab字段是需要使用给定的值的(如:a需取遍"X,Y,Z,U,V,W",b在a取X、Y时取M,其他时候取N),其他字段的值来自ClassB对应的字段。并且有下述要求:对属性c:若a取X,则c取classB.getX();若a取Y,则c取classB.getY();若a取Z,则c取classB.getZ();若a取U,则c取classB.getU();若a取V,则c取classB.getV();若a取W:ifclassB.getPar1=="CONSTANT1"则c取"C1"ifclassB.getPar1=="CONSTANT2"则c取"C2"elsec取classB.getW();属性d、e、f分别取用classB的par2、par3、par4即可。当然,这样写肯定没错:ClassAca1=newClassA();ca1.setA("X");ca1.setB("M");ca1.setC(classB.getPar1());ca1.setD(classB.getPar2());ca1.setE(classB.getPar3());ca1.setF(classB.getPar4());ClassAca2=newClassA();ca2.setA("Y");ca2.setB("M");ca2.setC(classB.getY());ca2.setD(classB.getPar2());ca2.setE(classB.getPar3());ca2.setF(classB.getPar4());ClassAca3=newClassA();ca3.setA("Z");ca3.setB("N");ca3.setC(classB.getZ());ca3.setD(classB.getPar2());ca3.setE(classB.getPar3());ca3.setF(classB.getPar4());ClassAca4=newClassA();ca4.setA("U");ca4.setB("N");ca4.setC(classB.getU());ca4.setD(classB.getPar2());ca4.setE(classB.getPar3());ca4.setF(classB.getPar4());ClassAca5=newClassA();ca5.setA("V");ca5.setB("N");ca5.setC(classB.getV());ca5.setD(classB.getPar2());ca5.setE(classB.getPar3());ca5.setF(classB.getPar4());ClassAca6=newClassA();ca6.setA("W");ca6.setB("N");if(classB.getPar1()=="CONSTANT1"){ca6.setC("C1");}elseif(classB.getPar1()=="CONSTANT2"){ca6.setC("C2");}else{ca6.setC(classB.getW());}ca6.setD(classB.getPar2());ca6.setE(classB.getPar3());ca6.setF(classB.getPar4());dao.save(ca1...6);

但这显然不是好的编码风格,重复的代码应该提出来。问下大家,欲重构的话,应该采用什么样的设计模式,或者需要遵循什么样的原则那?谢谢大家!!!

解决方案

本帖最后由 Wuaner 于 2010-03-09 12:19:57 编辑
解决方案二:
抢个sofar.
解决方案三:
沙发抢这么快。。。刚要改个错误。。。这下倒好,又改不了了。。代码第四行该是ca1.setC(classB.getX());

解决方案四:
分支太多了....就不写代码了...我的看法还是用工厂比较好....如果数据只是由classB给定,那么工厂的接口就只接受classB实例
解决方案五:
还没学到这一课,但是帮顶一下,希望楼主能尽快解决问题
解决方案六:
我在ClassA里面放了一个构造方法,publicClassA(Stringa,Stringb,Stringc,Stringd,Stringe,Stringf){this.a=a;this.b=b;this.c=c;this.d=d;this.e=e;this.f=f;}

然后写了个抽象工厂类,使用的就是工厂模式啦publicabstractclassClassAFactory{/**a字段的值*/privatestaticfinalStringX="X";privatestaticfinalStringY="Y";privatestaticfinalStringZ="Z";privatestaticfinalStringU="U";privatestaticfinalStringV="V";privatestaticfinalStringW="W";/**b字段的值*/privatestaticfinalStringM="M";privatestaticfinalStringN="N";publicstaticClassAgetClassAInstance(Stringa,ClassBclassB){if(null==a||null==classB){System.out.println("Invalidparameters");returnnull;}Stringb=(a.equals(X)||a.equals(Y))?M:N;Stringc=getCByA(a,classB);if(null==c){System.out.println("Invalidparameters.Thevalueofais"+a);returnnull;}returnnewClassA(a,b,c,classB.getPar2(),classB.getPar3(),classB.getPar4());}privatestaticStringgetCByA(Stringa,ClassBclassB){Stringc=null;if(a.equals(X)){c=classB.getX();}elseif(a.equals(Y)){c=classB.getY();}elseif(a.equals(Z)){c=classB.getZ();}elseif(a.equals(U)){c=classB.getU();}elseif(a.equals(V)){c=classB.getV();}elseif(a.equals(classB.getW())){c=classB.getW();}returnc;}}

解决方案七:
引用5楼tillperfect的回复:

我在ClassA里面放了一个构造方法,JavacodepublicClassA(Stringa,Stringb,Stringc,Stringd,Stringe,Stringf){this.a=a;this.b=b;this.c=c;this.d=d;this.e=e;this.f=f;}然后写了个抽象工厂类,使用的就是工厂模式啦JavacodepublicabstractclassClassAFactory{/**a字段的值*/privatestaticfinalStringX="X";privatestaticfinalStringY="Y";privatestaticfinalStringZ="Z";privatestaticfinalStringU="U";privatestaticfinalStringV="V";privatestaticfinalStringW="W";/**b字段的值*/privatestaticfinalStringM="M";privatestaticfinalStringN="N";publicstaticClassAgetClassAInstance(Stringa,ClassBclassB){if(null==a||null==classB){System.out.println("Invalidparameters");returnnull;}Stringb=(a.equals(X)||a.equals(Y))?M:N;Stringc=getCByA(a,classB);if(null==c){System.out.println("Invalidparameters.Thevalueofais"+a);returnnull;}returnnewClassA(a,b,c,classB.getPar2(),classB.getPar3(),classB.getPar4());}privatestaticStringgetCByA(Stringa,ClassBclassB){Stringc=null;if(a.equals(X)){c=classB.getX();}elseif(a.equals(Y)){c=classB.getY();}elseif(a.equals(Z)){c=classB.getZ();}elseif(a.equals(U)){c=classB.getU();}elseif(a.equals(V)){c=classB.getV();}elseif(a.equals(classB.getW())){c=classB.getW();}returnc;}}

用prototype或者builder..把具体负责的构建过程委托出去这里的方案不能用Factory..Factory是提供创建类的接口的,具体的类的实现延迟到子类prototype是由原型来决定对象的种类,并通过拷贝这个原型来实现这个类builder是将对象的构建过程与表示过程分离,使得有相同的构建过程却有不同的表示,这个例子最好用builder楼上的例子用的是工厂,但是最后却有getInstance的方法名,感觉最好不要用,因为getInstance用于SingleTon模式
解决方案八:
6楼说的对,这里不应该使用工厂模式。prototype原型模式似乎也不合适。我使用了builder模式,又写了个代码,等会发下
解决方案九:
模板加反射。根据A的属性取值反射到B的属性。剩余的动作提取一下,放到公用的方法里就OK了
解决方案十:
/**生成器接口*/interfaceBuilderClass{publicvoidbuildA(Stringa);publicvoidbuildB(Stringa);publicvoidbuildC(Stringa,ClassBclassB);publicvoidbuildD(Stringd);publicvoidbuildE(Stringe);publicvoidbuildF(Stringf);publicClassAgetInstance();}/**具体的生成器*/classBuilderClassAAimplementsBuilderClass{privateStringa;privateStringb;privateStringc;privateStringd;privateStringe;privateStringf;privatestaticfinalStringX="X";privatestaticfinalStringY="Y";privatestaticfinalStringZ="Z";privatestaticfinalStringU="U";privatestaticfinalStringV="V";privatestaticfinalStringW="W";privatestaticfinalStringM="M";privatestaticfinalStringN="N";publicvoidbuildA(Stringa){this.a=a;}publicvoidbuildB(Stringa){b=(a.equals(X)||a.equals(Y))?M:N;}publicvoidbuildC(Stringa,ClassBclassB){if(a.equals(X)){c=classB.getX();}elseif(a.equals(Y)){c=classB.getY();}elseif(a.equals(Z)){c=classB.getZ();}elseif(a.equals(U)){c=classB.getU();}elseif(a.equals(V)){c=classB.getV();}elseif(a.equals(classB.getW())){c=classB.getW();}}publicvoidbuildD(Stringd){this.d=d;}publicvoidbuildE(Stringe){this.e=e;}publicvoidbuildF(Stringf){this.f=f;}publicClassAgetInstance(){returnnewClassA(a,b,c,d,e,f);}}/**用于构建最终的对象*/classProduct{privateBuilderClassbuilder;publicProduct(BuilderClassbuilder){this.builder=builder;}publicvoidbuild(Stringa,ClassBclassB){builder.buildA(a);builder.buildB(a);builder.buildC(a,classB);builder.buildD(classB.getPar2());builder.buildE(classB.getPar3());builder.buildF(classB.getPar4());}}/**调用生成器*/publicclassBuilderClassA{publicstaticvoidmain(String[]args){ClassBcb=newClassB("par1","par2","par3","par4","xxx","yyy","zzz","uuu","vvv","www");Stringa="X";BuilderClassbuilder=newBuilderClassAA();ProductfinalBuilder=newProduct(builder);finalBuilder.build(a,cb);ClassAca=builder.getInstance();System.out.println(ca.getA()+""+ca.getB()+""+ca.getC());}}

解决方案十一:
额。。。写得有点多啊。。。反正就是这个意思lz记得要进行判空操作,避免空指针。我没有写
解决方案十二:
没明白要做什么,而且楼主举的例子也很敷衍!
解决方案十三:
不用builder那么多。。而且,如果你的builer是这样写的话,给写客户端代码的人会带来很阴郁的感觉。。。对于builder的中间过程,尽量采取方法链的形式。要保证创建过程不被打断。另外,有个明确的方法返回你要创建的最终对象。publicclassBuilder{privateClassBb;privateClassAaa;publicBuilder(ClassBb){this.b=b;}publicBuildersetA(Aa){aa=newClassA();aa.setA(a);if(a=="x"){aa.setB("m");aa.setC(b.getX());}elseif(a=="y"){aa.setB("m");aa.setC(b.getY());}elseif(a=="z"){aa.setB("m");aa.setC(b.getZ());}elseif(a=="u"){aa.setB("n");aa.setC(b.getU());}elseif(a=="v"){aa.setB("n");aa.setC(b.getV());}elseif(a=="w"){aa.setB("n");if(b.getPart1()=="C1")aa.setC("C1");elseif(b.getPart1()=="C2")aa.setC("C2");elseaa.setC(b.getW());}aa.setD(b.getPart2());aa.setE(b.getPart3());aa.setF(b.getPart4());returnthis;}publicClassAcreateClassA(){if(aa==null)thrownewRuntimeException("");returnaa;}publicstaticvoidmain(String[]args){ClassBb=newClassB();Aa=newA("x");//...ClassAa=(newBuilder(b)).setA().createClassA();}}
解决方案十四:
/**生成器接口*/interfaceBuilderClass{publicvoidbuildA(Stringa);publicvoidbuildB(Stringa);publicvoidbuildC(Stringa,ClassBclassB);publicvoidbuildD(Stringd);publicvoidbuildE(Stringe);publicvoidbuildF(Stringf);publicClassAgetInstance();}/**具体的生成器*/classBuilderClassAAimplementsBuilderClass{privateStringa;privateStringb;privateStringc;privateStringd;privateStringe;privateStringf;privatestaticfinalStringX="X";privatestaticfinalStringY="Y";privatestaticfinalStringZ="Z";privatestaticfinalStringU="U";privatestaticfinalStringV="V";privatestaticfinalStringW="W";privatestaticfinalStringM="M";privatestaticfinalStringN="N";publicvoidbuildA(Stringa){this.a=a;}publicvoidbuildB(Stringa){b=(a.equals(X)||a.equals(Y))?M:N;}publicvoidbuildC(Stringa,ClassBclassB){if(a.equals(X)){c=classB.getX();}elseif(a.equals(Y)){c=classB.getY();}elseif(a.equals(Z)){c=classB.getZ();}elseif(a.equals(U)){c=classB.getU();}elseif(a.equals(V)){c=classB.getV();}elseif(a.equals(classB.getW())){c=classB.getW();}}publicvoidbuildD(Stringd){this.d=d;}publicvoidbuildE(Stringe){this.e=e;}publicvoidbuildF(Stringf){this.f=f;}publicClassAgetInstance(){returnnewClassA(a,b,c,d,e,f);}}/**用于构建最终的对象*/classProduct{privateBuilderClassbuilder;publicProduct(BuilderClassbuilder){this.builder=builder;}publicvoidbuild(Stringa,ClassBclassB){builder.buildA(a);builder.buildB(a);builder.buildC(a,classB);builder.buildD(classB.getPar2());builder.buildE(classB.getPar3());builder.buildF(classB.getPar4());}}/**调用生成器*/publicclassBuilderClassA{publicstaticvoidmain(String[]args){ClassBcb=newClassB("par1","par2","par3","par4","xxx","yyy","zzz","uuu","vvv","www");Stringa="X";BuilderClassbuilder=newBuilderClassAA();ProductfinalBuilder=newProduct(builder);finalBuilder.build(a,cb);ClassAca=builder.getInstance();System.out.println(ca.getA()+""+ca.getB()+""+ca.getC());}}

解决方案十五:
面向对象的思想考虑ClassA和ClassB存在什么关系
解决方案:
你这对象模型设计的好别扭
解决方案:
引用15楼wn_1985的回复:

你这对象模型设计的好别扭

这是一个非常大的系统,它就是这样设计的,我也没办法啊。。。
解决方案:
继续给答案啊。。。。。。。。。。。。。
解决方案:
似乎其他属性的值都是由a的值决定的,那么可以用状态模式,a的值决定这个对象的状态,a的取值有几种可能性,就有几种状态,这样扩充起来也很方便。
解决方案:
谢谢大家的热心回复!!!!!!请继续!
解决方案:
都是高手呵!
解决方案:
推荐你看看这个:http://www.vincehuston.org/dp/factory_method.html或者整体的DP23种http://www.vincehuston.org/dp/
解决方案:
MARK学习
解决方案:
顶顶顶顶顶

时间: 2024-11-05 14:38:48

关于代码的重构问题!!设计模式~原则!!谢谢大家!!!!的相关文章

软件重构和设计模式理解

之前在工作写了一个数据库查询的工具.大体背景就是这种工具需要跨不同环境的数据库,开发,测试,性能等.最早简单写了一个版本,在第一次查询时会初始化三个库的连接,保存在map中,然后后续查询直接根据使用者选择的环境类型取出对应的连接构造sql即可. 随着各个不同系统接入的越来越多,各个平台都保存了自己的连接,导致代码冗余度急剧上升,上周,利用晚上的一点时间读了一下<<重构>>,这本书,深受启发,一个是重构就是要采用小步快走的方式,在测试用例的覆盖下,快速改动,去掉代码中不合理的地方.另

浅谈遗留代码的重构

             背景 <重构>诞生至今有近17个年头了,日常开发中大家谈到重构,要么非常随意,认为重构就是改代码:要么非常谨慎,把重构描述成焦油坑,像瘟神一样敬而远之.针对最具挑战性的遗留代码重构,有哪些需要注意的呢? 谈论任何事情,都该有它的上下文.本文谈论的技术背景是大型通信类产品,对于互联网产品不一定适用.另外,本文也不会涉及重构技术,有兴趣读者可以读<重构>或者<Effective Refactoring in C++>. 遗留代码重构决策表 遗留代码

一次重构导向设计模式的实践(.NET)

设计 代码仅仅是说明问题,和实际的有所不同在项目开发过程中,有这样的需求:定义一个查询窗体使用DataGrid显示列表双击Grid后打开指定记录的编辑页面,窗体类为FormSearchEntity于是这么写了private void Grid_DoubleClick(object sender,System.EventArgs e){ string entityID = 双击记录的ID字段值: //这个有固定的办法 FormEntity frmEntity = new FormEntity(en

设计模式原则(单一、开放封闭、里氏代换、依赖倒转、迪米特法则五大原则)

原文:设计模式原则(单一.开放封闭.里氏代换.依赖倒转.迪米特法则五大原则) 单一职责原则 单一职责原则,就一个类而言,应该仅有一个引起它变化的原因.   如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力,当变化发生时,设计会遭受到意想不到的破坏.事实上,我们完全可以找出来进行分类,分离.   软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离.其实要去判断是否应该分离出类来,也不难,那就是如果你能够想到多余一个的动机去改变

java利用QQ邮件服务器发邮件的代码 谁有 各位大神谢谢了

问题描述 java利用QQ邮件服务器发邮件的代码 谁有 各位大神谢谢了 ...................................................................... 解决方案 //发送邮件 try { Properties prop = new Properties(); //设置服务器地址 prop.put("mail.smtp.host", "smtp.qq.com"); //设置需要身份验证 prop.put(&

领导重构代码,重构一堆的bug,怎么办 ?

问题描述 领导重构代码,重构一堆的bug,怎么办 ? 本来测试通过领导重构代码,重构一堆的bug,页面都给换了?怎么办 解决方案 领导说什么就是什么,不要自作主张 解决方案二: 重构代码,有bug就修正呗.

c语言-这两句代码是什么意思呢。谢谢大虾们了

问题描述 这两句代码是什么意思呢.谢谢大虾们了 //#define PLOG(fmt,args...) printf(">>"fmt,##args) /*gcc*/ #define U_PLOG(fmt,...) printf("u>> "fmt,##__VA_ARGS__) /*c99 gcc*/ 解决方案 sorry,i don't no

mysql-java代码如何封装MySQL数据库?谢谢

问题描述 java代码如何封装MySQL数据库?谢谢 java代码如何封装MySQL数据库,然后能io流生成jsp文件 解决方案 jdbc或者连接池访问数据库 那到数据 用El表达式 解决方案二: java代码连接mysql数据库java mysql连接数据库代码java连接mysql数据库 代码 解决方案三: jdbc或者连接池访问数据库 那到数据 用El表达式

java-请教各位密码学及数学高手,这段代码反加密如何实现。谢谢

问题描述 请教各位密码学及数学高手,这段代码反加密如何实现.谢谢 public static byte[] decrypt(byte[] paramArrayOfByte) { ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream(); for (int i = 0;; i += 2) { if (i >= paramArrayOfByte.length) return localByteArra

为什么我拖拽后的控件回不去!!帮忙看下代码是什么问题!!谢谢

问题描述 为什么我拖拽后的控件回不去!!帮忙看下代码是什么问题!!谢谢 这是JAVA代码 package com.example.test; import com.example.test1.R; import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; i