怎么做和京东一样网站,衣服网站设计,app下载网址进入,wordpress提权引言一般来说#xff0c;随着我们项目的迭代以及业务的越来越复杂#xff0c;项目中的分支判断会原来越多。当项目中涉及到复杂的业务判断或者分支逻辑时#xff0c;我们就需要考虑是否需要对项目进行重构了#xff0c;或者if else和switch case是否能够满足当前项目的复杂…引言一般来说随着我们项目的迭代以及业务的越来越复杂项目中的分支判断会原来越多。当项目中涉及到复杂的业务判断或者分支逻辑时我们就需要考虑是否需要对项目进行重构了或者if else和switch case是否能够满足当前项目的复杂度。我们举一个简单的例子假如我们是马戏团的老板在训练一些动物去做一些指令刚开始很简单只训练了一条狗当狗握了一下手后给她奖励一些狗粮。这样慢慢地小狗就学会了握手。我们先定义一条小狗对象小狗做了某些事情(“握手”)后可以得到一些奖励public class Dog {public void train(){System.out.println(握手);}public void getReward(){System.out.println(狗粮);}}定义驯兽师通过train来训练动物public class Beast {/*** 训练*/public void train(Dog dog){/*** 狗狗做了一些事情*/dog.train();/*** 狗狗得到奖励*/dog.getReward();}}如果我们只需要训练一条动物那么相对来说比较简单。但是后来马戏团又引进了一头狮子需要训练狮子钻火圈因此为了区分狗和狮子我们增加了一种类型区分训练的动物是狗还是狮子。public class Lion {public void train(){System.out.println(钻火圈);}public void getReward(){System.out.println(得到一只鸡);}}重新修改Beast类使其既可以训练小狗又可以训练狮子public class Beast {public void train(Object animal, int type){if (type 1){trainDog((Dog)animal);}else if (type 2){trainLion((Lion)animal);}}/*** 训练*/public void trainDog(Dog dog){/*** 狗狗做了一些事情*/dog.train();/*** 狗狗得到奖励*/dog.getReward();}/*** 训练*/public void trainLion(Lion lion){/*** 狗狗做了一些事情*/lion.train();/*** 狗狗得到奖励*/lion.getReward();}}我们通过type类型来区分训练的动物类型后来马戏团引来了越来越多的动物那我们的type的取值会越来越多1表示狗2表示狮子3表示猫4表示老虎5表示猴子...等等。而且随着系统越来越复杂我们在训练之前不同的动物还需要做不同的准备工作。当然目前的系统只要增加if else或者switch case是可以满足需求的但这样写显得不是太优雅我们希望找到一种比较优雅比较有设计感的方式来取代if else或者switch case优化if else在做优化之前我们需要先弄清楚我们的目的。我们是马戏团的驯兽师目的是训练动物。目的训练动物做一些事情(doSomething)方式通过奖励(getReward)诱导动物进行训练。有了上面的目的之后我们就可以定义一个模型animalpublic interface IAnimal {/*** 获取动物种类* return*/int getType();/*** 训练动作*/void train();}Animal只暴露两个方法其中doSomething是专门用来训练动物的至于如何训练全都由子类实现。getType():用来区分不同的动物train():训练动物然后我们定义一个子类实现这个接口用来具体化如何训练动物public abstract class AbsTrainAnimal implements IAnimal{/*** 训练前需要做的准备*/abstract void beforeTrain();/*** 训练后需要做的准备*/abstract void afterTrain();/*** 训练出现异常需要做的*/abstract void exceptionTrain(Throwable throwable);/*** 具体训练*/abstract void doSomething();/*** 训练动作*/Overridepublic final void train() {try {beforeTrain();doSomething();afterTrain();}catch (Throwable throwable){exceptionTrain(throwable);}}}我们定义了一个抽象类用来实现IAnimal接口作为所有动物训练的基类。其中实现的接口train使用了final进行了限制防止子类对其进行覆盖操作。在AbsTrainAnimal中我们对train()进行了各种功能的细化doSomething具体训练的内容beforeTrain训练之前需要做的一些准备afterTrain训练之后需要做的事情exceptionTrain训练中发生意外应该如何处理因为所有动物的以上四个方法可能都不相同所以我们声明为abstract方法方便子类自己实现。基于以上设计我们就可以定义一个Dog类对其进行训练。public class Dog extends AbsTrainAnimal {/*** 训练前需要做的准备*/Overridevoid beforeTrain() {System.out.println(抚摸额头以示鼓励);}/*** 训练后需要做的准备*/Overridevoid afterTrain() {System.out.println(奖励一些狗粮);}/*** 训练出现异常需要做的** param throwable*/Overridevoid exceptionTrain(Throwable throwable) {System.out.println(出去罚站);}/*** 具体训练*/Overridevoid doSomething() {System.out.println(握手);}/*** 获取动物种类** return*/Overridepublic int getType() {return 1;}}同时定义一个狮子Lionpublic class Lion extends AbsTrainAnimal {/*** 训练前需要做的准备*/Overridevoid beforeTrain() {System.out.println(友好交流);}/*** 训练后需要做的准备*/Overridevoid afterTrain() {System.out.println(奖励一只鸡);}/*** 训练出现异常需要做的** param throwable*/Overridevoid exceptionTrain(Throwable throwable) {System.out.println(紧急送往医院);}/*** 具体训练*/Overridevoid doSomething() {System.out.println(钻火圈);}/*** 获取动物种类** return*/Overridepublic int getType() {return 2;}}我们可以看到Dog和Lion的动物种类是不一样的Dog为1Lion为2。我们可以根据type区分是狮子还是狗。但为了避免使用if else进行区分我们需要一个工厂类来生产这两种动物。Servicepublic class AnimalFactory {private static List animalLists Lists.newArrayList();private static Map animalMaps Maps.newHashMap();static {animalLists.add(Dog.class);animalLists.add(Lion.class);}PostConstructpublic void init() throws IllegalAccessException, InstantiationException {for (Class extends IAnimal clazz : animalLists){Object obj clazz.newInstance();animalMaps.put(obj.getType(), obj);}}/*** 构建动物类* param type* return*/IAnimal build(int type){return animalMaps.get(type);}}我们有了这个工厂类就可以根据不同的动物类型获取不同的对象并对其进行训练。当然我们这里都是使用的单例模式每个对象只对应一个实例如果每次都生成不同的实例可以对其进行简单的改造即可实现。我们再重写驯兽师Beast类Servicepublic class Beast {Resourceprivate AnimalFactory animalFactory;/*** 训练动物只需要知道动物的类型即可* param type*/public void train(int type){IAnimal animal animalFactory.build(type);animal.train();}}可以看到train方法只需要关系动物类型即可不需要再根据type进行判断动物类型在对其进行不同的操作。如果有新的动物加入只需要实现AbsTrainAnimal基类然后向AnimalFactory进行注册即可。避免了根据不同type进行if else或者switch的判断总结其实上述所述的方法不但但省去了if else的判断也是目前比较流行的领域模型的一种实现方式。IAnimal是领域内对外暴露的唯一方式外部领域(驯兽师)不需要关心任何内部实现的细节。内部的实现完全集合在IAnimal内。