问题描述
假设实体类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学习
解决方案:
顶顶顶顶顶