Why?
为什么我们可以用简单粗暴的方式来完成产品经理给的需求,还要用 23种设计模式 中的工厂方法模式
来重构代码呢?
这个问题在我刚入行的时候是不懂的,理解需求,完成代码,前后端联调,提交测试,业务上线一气呵成。
当我们的需求需要兼容多系统、多任务、多规则的时候,用简单的 CRUD 来完成就会让代码变的很臃肿、耦合、不优雅。那么如何写出优雅的代码呢?今天我来用工厂方法模式一步一步带你去重构代码,让代码变得优雅起来
业务场景
需求一
丰收村的苹果到了成熟的季节,需要采摘、包装、加工、运输这几个环节,需要我们来实现一下业务代码
代码实现
苹果类
public class Apple {
public void pick() {
System.out.println("采摘苹果...");
}
public void pack() {
System.out.println("包装苹果...");
}
public void process() {
System.out.println("加工苹果...");
}
public void transport() {
System.out.println("运输苹果....");
}
}
Main 方法
public class Main {
public static void main(String[] args) {
Apple apple = new Apple();
apple.pick();
apple.pack();
apple.process();
apple.transport();
}
}
output
采摘苹果...
包装苹果...
加工苹果...
运输苹果....
思路
我们大部分的需求都是这种简单的 CRUD,无脑写就完事了。
需求二
丰收村除了苹果到了成熟的季节,
梨也成熟了
,现在需要我们来完成这两个产品的采摘、包装、加工、运输这几个环节,需要我们来实现一下业务代码
代码实现
水果基类
/**
* @Author: Lisy
* @Date: 2022/10/19/16:11
* @Description: 抽象出操作环节抽象接口让每个农产品去继承即可
*/
public abstract class Fruit {
/**
* 采摘
*/
public abstract void pick();
/**
* 包装
*/
public abstract void pack();
/**
* 加工
*/
public abstract void process();
/**
* 运输
*/
public abstract void transport();
}
苹果实现类
public class Apple extends Fruit{
@Override
public void pick() {
System.out.println("采摘苹果...");
}
@Override
public void pack() {
System.out.println("包装苹果...");
}
@Override
public void process() {
System.out.println("加工苹果...");
}
@Override
public void transport() {
System.out.println("运输苹果....");
}
}
梨子实现类
public class Pear extends Fruit{
@Override
public void pick() {
System.out.println("采摘梨...");
}
@Override
public void pack() {
System.out.println("包装梨...");
}
@Override
public void process() {
System.out.println("加工梨...");
}
@Override
public void transport() {
System.out.println("运输梨....");
}
}
水果工厂基类
/**
* @Author: Lisy
* @Date: 2022/10/19/16:39
* @Description: 水果工厂基类
*/
public interface FruitFactory {
/**
* 采摘
*/
Fruit pick();
/**
* 包装
*/
Fruit pack();
/**
* 加工
*/
Fruit process();
/**
* 运输
*/
Fruit transport();
}
苹果工厂类
/**
* @Author: Lisy
* @Date: 2022/10/19/16:41
* @Description:苹果工厂类
*/
public class AppleFactory implements FruitFactory{
@Override
public Fruit pick() {
return new Apple();
}
@Override
public Fruit pack() {
return new Apple();
}
@Override
public Fruit process() {
return new Apple();
}
@Override
public Fruit transport() {
return new Apple();
}
}
梨子工厂类
/**
* @Author: Lisy
* @Date: 2022/10/19/16:41
* @Description: 梨子工厂类
*/
public class PearFactory implements FruitFactory{
@Override
public Fruit pick() {
return new Pear();
}
@Override
public Fruit pack() {
return new Pear();
}
@Override
public Fruit process() {
return new Pear();
}
@Override
public Fruit transport() {
return new Pear();
}
}
业务消费类
/**
* @Author: Lisy
* @Date: 2022/10/19/16:49
* @Description: 业务消费类
*/
public class Bussiness {
public static void pick(FruitFactory fruitFactory) {
fruitFactory.pick().pick();
}
public static void pack(FruitFactory fruitFactory) {
fruitFactory.pack().pack();
}
public static void process(FruitFactory fruitFactory) {
fruitFactory.process().process();
}
public static void transport(FruitFactory fruitFactory) {
fruitFactory.transport().transport();
}
}
Main测试类
public class Main {
public static void main(String[] args) {
Bussiness.pick(new AppleFactory());
Bussiness.pack(new AppleFactory());
Bussiness.process(new AppleFactory());
Bussiness.transport(new AppleFactory());
System.out.println("============");
Bussiness.pick(new PearFactory());
Bussiness.pack(new PearFactory());
Bussiness.process(new PearFactory());
Bussiness.transport(new PearFactory());
}
}
output
采摘苹果...
包装苹果...
加工苹果...
运输苹果....
============
采摘梨...
包装梨...
加工梨...
运输梨....
进程已结束,退出代码0
思路
采用水果工厂类(FruitFactory)定义顶层操作接口,每个产品(AppleFactory、PearFactory)去实现水果工厂类,调用时仅需要调用业务静态类(Bussiness)对应方法既可
需求三
幸福村看到丰收村的农产品大卖,他们也想把自己村的蔬菜产业进行销售,现在需要我们在已有的系统中加入蔬菜销售的逻辑
代码实现
农产品基类
/**
* @Author: Lisy
* @Date: 2022/10/19/17:06
* @Description: 农产品基类,定义相关操作
*/
public abstract class FarmProduct {
/**
* 采摘
*/
public abstract void pick();
/**
* 包装
*/
public abstract void pack();
/**
* 加工
*/
public abstract void process();
/**
* 运输
*/
public abstract void transport();
}
相应农产品继承农产品基类
public class Apple extends FarmProduct {
@Override
public void pick() {
System.out.println("采摘苹果...");
}
@Override
public void pack() {
System.out.println("包装苹果...");
}
@Override
public void process() {
System.out.println("加工苹果...");
}
@Override
public void transport() {
System.out.println("运输苹果....");
}
}
public class Pear extends FarmProduct {
@Override
public void pick() {
System.out.println("采摘梨...");
}
@Override
public void pack() {
System.out.println("包装梨...");
}
@Override
public void process() {
System.out.println("加工梨...");
}
@Override
public void transport() {
System.out.println("运输梨....");
}
}
public class Cabbage extends FarmProduct {
@Override
public void pick() {
System.out.println("采摘卷心菜...");
}
@Override
public void pack() {
System.out.println("包装卷心菜...");
}
@Override
public void process() {
System.out.println("加工卷心菜...");
}
@Override
public void transport() {
System.out.println("运输卷心菜....");
}
}
public class Celery extends FarmProduct {
@Override
public void pick() {
System.out.println("采摘芹菜...");
}
@Override
public void pack() {
System.out.println("包装芹菜...");
}
@Override
public void process() {
System.out.println("加工芹菜...");
}
@Override
public void transport() {
System.out.println("运输芹菜....");
}
}
农产品抽象工厂
/**
* @Author: Lisy
* @Date: 2022/10/19/17:06
* @Description: 农产品抽象工厂
*/
public abstract class AbstractFarmProduct {
/**
* 采摘
*/
public abstract FarmProduct pick();
/**
* 包装
*/
public abstract FarmProduct pack();
/**
* 加工
*/
public abstract FarmProduct process();
/**
* 运输
*/
public abstract FarmProduct transport();
}
苹果工厂类
public class AppleFactory extends AbstractFarmProduct {
@Override
public FarmProduct pick() {
return new Apple();
}
@Override
public FarmProduct pack() {
return new Apple();
}
@Override
public FarmProduct process() {
return new Apple();
}
@Override
public FarmProduct transport() {
return new Apple();
}
}
梨子工厂类
public class PearFactory extends AbstractFarmProduct {
@Override
public FarmProduct pick() {
return new Pear();
}
@Override
public FarmProduct pack() {
return new Pear();
}
@Override
public FarmProduct process() {
return new Pear();
}
@Override
public FarmProduct transport() {
return new Pear();
}
}
芹菜工厂类
public class CeleryFactory extends AbstractFarmProduct {
@Override
public FarmProduct pick() {
return new Celery();
}
@Override
public FarmProduct pack() {
return new Celery();
}
@Override
public FarmProduct process() {
return new Celery();
}
@Override
public FarmProduct transport() {
return new Celery();
}
}
卷子菜工厂类
public class CabbageFactory extends AbstractFarmProduct {
@Override
public FarmProduct pick() {
return new Cabbage();
}
@Override
public FarmProduct pack() {
return new Cabbage();
}
@Override
public FarmProduct process() {
return new Cabbage();
}
@Override
public FarmProduct transport() {
return new Cabbage();
}
}
业务消费类
public class Bussiness {
public static void pick(AbstractFarmProduct abstractFarmProduct) {
abstractFarmProduct.pick().pick();
}
public static void pack(AbstractFarmProduct abstractFarmProduct) {
abstractFarmProduct.pack().pack();
}
public static void process(AbstractFarmProduct abstractFarmProduct) {
abstractFarmProduct.process().process();
}
public static void transport(AbstractFarmProduct abstractFarmProduct) {
abstractFarmProduct.transport().transport();
}
}
Main 测试类
public class Main {
public static void main(String[] args) {
Bussiness.pick(new CabbageFactory());
System.out.println("=========");
Bussiness.pick(new AppleFactory());
System.out.println("=========");
Bussiness.pack(new AppleFactory());
}
}
output
采摘卷心菜...
=========
采摘苹果...
=========
包装苹果...
思路
通过抽象出一个公共抽象基类(FarmProduct),每个农产品去继承它
在抽象出一个公共农产品工厂类(AbstractFarmProduct),每个农产品工厂去继承它,实现自己的具体实现。
通过业务消费接口(Bussiness)调用每种操作(pick、pack等等)