工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
- 案例: 在一个java后台项目中需要集成支付功能,而支付功能又分为了支付宝支付、微信支付、银联支付三种,并且以后还有可能会扩展百度钱包等支付
- 思路: 每种支付方式都有commitPayData()、pay()两个方法, 则设计一个接口 Pay, 然后每种支付方式实现这个Pay接口
public interface Pay {
Object commitPayData(String str);
boolean pay(Object obj);
}
public class AliPay implements Pay {
@Override
public Object commitPayData(String str) {
// 省略业务、功能代码
return null;
}
@Override
public boolean pay(Object obj) {
// 省略业务、功能代码
return false;
}
}
public class WxPay implements Pay {
@Override
public Object commitPayData(String str) {
// 省略业务、功能代码
return null;
}
@Override
public boolean pay(Object obj) {
// 省略业务、功能代码
return false;
}
}
public class UnionPay implements Pay {
@Override
public Object commitPayData(String str) {
// 省略业务、功能代码
return null;
}
@Override
public boolean pay(Object obj) {
// 省略业务、功能代码
return false;
}
}
支付工厂类, 创建对应的支付
public class PayFactory {
public static final String ALI_PAY = "ali";
public static final String WX_PAY = "wx";
public static final String UNION_PAY = "union";
/**
*
* @param payMethod 支付方式
* @return
*/
public static Pay getPayObj(String payMethod) {
Pay pay = null;
if (payMethod.equals(ALI_PAY)) {
pay = new AliPay();
} else if (payMethod.equals(WX_PAY)) {
pay = new WxPay();
} else if (payMethod.equals(UNION_PAY)) {
pay = new UnionPay();
} else {
// 其他支付方式不支持,可在此记录错误日志
}
return pay;
}
}
public class Main {
public static void main(String[] args) {
Pay pay = PayFactory.getPayObj("ali");
// 可调用pay的方法完成支付功能
pay.commitPayData("");
pay.pay("");
}
}
- 上面简单工厂模式的缺点是, 如果有新的支付方式, 需要改动PayFactory.
- 工厂方法模式则是将Factory改为接口, 然后不同的支付方法有自己的工厂, 并且实现Factory接口
public interface Pay {
Object commitPayData(String str);
boolean pay(Object obj);
}
public class AliPay implements Pay {
@Override
public Object commitPayData(String str) {
// 省略业务、功能代码
return null;
}
@Override
public boolean pay(Object obj) {
// 省略业务、功能代码
return false;
}
}
public class WxPay implements Pay {
@Override
public Object commitPayData(String str) {
// 省略业务、功能代码
return null;
}
@Override
public boolean pay(Object obj) {
// 省略业务、功能代码
return false;
}
}
public class UnionPay implements Pay {
@Override
public Object commitPayData(String str) {
// 省略业务、功能代码
return null;
}
@Override
public boolean pay(Object obj) {
// 省略业务、功能代码
return false;
}
}
public interface PayFactory {
Pay payMethod();
}
public class AliFactory implements PayFactory {
@Override
public Pay payMethod() {
return new AliPay();
}
}
public class WxFactory implements PayFactory {
@Override
public Pay payMethod() {
return new WxPay();
}
}
public class UnionFactory implements PayFactory {
@Override
public Pay payMethod() {
return new UnionPay();
}
}
public class Main {
public static void main(String[] args) {
Pay pay = PayFactory.getPayObj("ali");
// 可调用pay的方法完成支付功能
pay.commitPayData("");
pay.pay("");
}
}
Pay wechat = new WxFactory().payMethod();
Pay ali = new AliFactory().payMethod();
Pay Union = new UnionFactory().payMethod();
- 抽象工厂模式: 围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂
- 产品族和产品等级
- 抽象工厂模式可以产品等级和产品族创建具体的产品
- UML图
- 案例: 现在有两张表需要分别被两种数据库创建
- 产品族:两种DBMS
- 产品等级:两张表
超级工厂:
public interface IFactory {
public IUser createUser();
public IDept createDept();
}
public class SqlserverFactory implements IFactory{
@Override
public IUser createUser() {
return new SqlserverUser();
}
@Override
public IDept createDept() {
return new SqlserverDept();
}
}
public class AccessFactory implements IFactory{
@Override
public IUser createUser() {
// TODO Auto-generated method stub
return new AccessUser();
}
@Override
public IDept createDept() {
// TODO Auto-generated method stub
return new AccessDept();
}
}
public interface IDept {
void Insert(Dept dept);
Dep getDept(int did);
}
public class SqlserverDept implements IDept{
@Override
public void Insert(Dept dept) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给Department表增加一条记录");
}
@Override
public Dept getDept(int did) {
System.out.println("在Sqlserver中根据id="+did+"得到Department表一条记录");
return dept;
}
}
public class AccessDept implements IDept{
@Override
public void Insert(Dept dept) {
// TODO Auto-generated method stub
System.out.println("在Access中给Department表增加一条记录");
}
@Override
public Dept getDept(int did) {
// TODO Auto-generated method stub
System.out.println("在Access中根据id="+did+"得到得到Department表一条记录");
return dept;
}
public interface IUser {
void Insert(User user);
User getDept(int did);
}
public class SqlserverUser implements IUser{
@Override
public void Insert(User user) {
System.out.println("在Sqlserver中给User表增加一条记录");
}
@Override
public User getUser(int did) {
System.out.println("在Sqlserver中根据id="+did+"得到User表一条记录");
return user;
}
}
public class AccessUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Access中给Department表增加一条记录");
}
@Override
public User getDept(int did) {
// TODO Auto-generated method stub
System.out.println("在Access中根据id="+did+"得到得到User表一条记录");
return user;
}
public class Test {
public static void main(String[] args) {
//将新数据分别放入两个数据库并抓取
User user = new User();
Dept dept = new Dept();
//分别创建两个工厂
IFactory sqlFactory = new SqlserverFactory();
IFactory accessFactory = new AccessFactory();
//sql + user
IUser sqlUser = sqlFactory.createUser();
sqlUser.insert(user);
sqlUser.getUser(1);
//sql + dept
IDept sqlDept = sqlFactory.createDept();
sqlDept.insert(dept);
sqlDept.getDept(1);
//access + user
IUser accessUser = accessFactory.createUser();
accessUser.insert(user);
accessUser.etUser(1);
//access + dept
IDept accessDept = accessFactory.createDept();
accessDept.insert(user);
accessDept.etUser(1);
}