工厂设计模式简介
在所有的设计模式中,我认为工厂设计模式算是比较好写的。但是,同时,他对于新手来说虽然比较容易写,代码也比较容易读,但是理解工厂设计模式的思想还是有点困难的。
简单来说,
没有工厂:如果你想要一个对象,那么必须new一个对象。
有了工厂:你要一个对象,你可以找该对象的工厂,该工厂给你提供一个。
工厂设计模式别的帖子写的有很多了。我贴两个我觉得写的不错的。
下边贴一个我在工作中实际用到的关于工厂设计模式的使用。
先说下需求
很简单的一个根据id来获取一个借款人对象;
但是借款人如果类型不一样,该借款人对象也不一样。
所以就要使用工厂来获取。
代码
先来看实体对象,一个借款人父类,三个类型的借款人子类
/**
* 父类
*/
public class Borrower {
}
/**
* 子类A
*/
public class BorrowerA extends Borrower{
private String id;
private String name;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "BorrowerA{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
/**
* 子类B
*/
public class BorrowerB extends Borrower{
private String id;
private String address;
private String phone;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "BorrowerB{" +
"id='" + id + '\'' +
", address='" + address + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
/**
* 子类C
*/
public class BorrowerC extends Borrower{
private String id;
private String CompanyName;
private String CompanyPhone;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCompanyName() {
return CompanyName;
}
public void setCompanyName(String companyName) {
CompanyName = companyName;
}
public String getCompanyPhone() {
return CompanyPhone;
}
public void setCompanyPhone(String companyPhone) {
CompanyPhone = companyPhone;
}
@Override
public String toString() {
return "BorrowerC{" +
"id='" + id + '\'' +
", CompanyName='" + CompanyName + '\'' +
", CompanyPhone='" + CompanyPhone + '\'' +
'}';
}
}
然后看一下service ,在这里也是需要一个父类service,三个子类service
/**
* 父类service
*/
public interface BorrowerService {
// 传参 借款人id 借款人类型
Borrower getBorrowerById(String id,BorrowerTypeEnum borrowerTypeEnum);
}
@Service
public class BorrowerAService implements BorrowerService {
@Override
public Borrower getBorrowerById(String id,BorrowerTypeEnum borrowerTypeEnum) {
//这个C类型的借款人假装从数据库中查询出来的
BorrowerA borrowerA = new BorrowerA();
borrowerA.setAge(18);
borrowerA.setName("a姓名");
borrowerA.setId("id");
return borrowerA;
}
}
@Service
public class BorrowerBService implements BorrowerService{
@Override
public Borrower getBorrowerById(String id,BorrowerTypeEnum borrowerTypeEnum) {
//这个C类型的借款人假装从数据库中查询出来的
BorrowerB borrowerB = new BorrowerB();
borrowerB.setAddress("b地址");
borrowerB.setPhone("b电话");
borrowerB.setId("bid");
return borrowerB;
}
}
@Service
public class BorrowerCService implements BorrowerService{
@Override
public Borrower getBorrowerById(String id,BorrowerTypeEnum borrowerTypeEnum) {
//这个C类型的借款人假装从数据库中查询出来的
BorrowerC borrowerC = new BorrowerC();
borrowerC.setCompanyName("c公司名");
borrowerC.setCompanyPhone("c公司电话");
borrowerC.setId("cid");
return borrowerC;
}
}
准备工作基本上就完事了,在写个最重要的工厂类
@Component
public class BorrowerFactory {
@Autowired
private BorrowerService borrowerAService;
@Autowired
private BorrowerService borrowerBService;
@Autowired
private BorrowerService borrowerCService;
public BorrowerService init(BorrowerTypeEnum borrowerTypeEnum){
if(borrowerTypeEnum.getCode()==1){
return borrowerAService;
}else if(borrowerTypeEnum.getCode()==2){
return borrowerBService;
}else{
return borrowerCService;
}
}
}
这就好了。我们看Controller中是怎么使用的
@Controller
public class BorrowerController {
@Autowired
private BorrowerFactory borrowerFactory;
public Borrower getBorrowerById(String id, BorrowerTypeEnum borrowerTypeEnum){
//工厂进行初始化,返回该类型的borrowerService
BorrowerService init = borrowerFactory.init(borrowerTypeEnum);
//该service直接调用返回父类对象
Borrower borrower = init.getBorrowerById(id, borrowerTypeEnum);
return borrower;
}
}
最后看一下,test运行结果
@RunWith(SpringRunner.class)
@SpringBootTest
public class FactoryDesignPatternApplicationTests {
@Autowired
private BorrowerController borrowerController;
@Test
public void contextLoads() {
Borrower borrowerById = borrowerController.getBorrowerById("1", BorrowerTypeEnum.BORROWER_B);
System.out.println(borrowerById);
}
//输出 BorrowerB{id='bid', address='b地址', phone='c电话'}
}
这个例子很简单。也很实用。向外部提供接口的话不用提供三个了,提供一个就行了。