作者的话
本文全文贯穿一个示例进行演示,方便大家更好的理解工厂模式,如果有任何问题或者文章中出现的错误,请联系本人修改,感谢万分! 如果该篇文章对您有一点帮助,本人万分荣幸!
本文中所举的例子,是一个商场售卖的例子,假设目前只贩卖手机,手机有多个品牌,功能只有,学习,打游戏,聊天。
什么是工厂模式
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式(来源百度百科)
个人理解:工厂模式可以更好地实现设计模式中的OCP原则,通过仅改变工厂类的方法,实现功能拓展
不用工厂模式的实现
所需要的资源
- 一个抽象类Phone代表所有手机 (拥有study,game,message)方法
- 两个子类 (XiaoMiPhone,VIVOPhone) 分别重写功能方法(study,game,message)
- 一个PhoneSupermarket 手机商店类,可以售卖不同的手机
由于本文侧重讲设计模式,所以就不用代码实现这段分析了,其UML类图大致是这样的
PhoneSupermarket 中的createPhone用来创造不同型号的手机,这种情况如果多了一种型号的手机,则多
常用的几种工厂模式
简单工厂模式
简单工厂模式中,创建了一个工厂类,在这个工厂类中,创建出不同的对象从而实现返回
类图大概是这样子的 其中手机的实体类继承了Phone类 PhoneFactory根据传入的手机类型不同构建不同的对象,即拓展功能只需要创建手机实现类 继承Phone类 然后在工厂类支持一下这个类就可以了,实现了OCP原则。 接下来粘贴一下详细的代码
// Phone
public abstract class Phone {
private String name;
public abstract void study();
public abstract void game();
public abstract void message();
public void setName(String name) {
this.name = name;
}
}
// XIAOMIPhone
public class XIAOMIPhone extends Phone{
@Override
public void study() {
System.out.println("小米手机学习");
}
@Override
public void game() {
System.out.println("小米手机玩游戏");
}
@Override
public void message() {
System.out.println("小米手机发消息");
}
}
// VIVOPhone
public class VIVOPhone extends Phone {
@Override
public void study() {
System.out.println("Vivo手机学习");
}
@Override
public void game() {
System.out.println("Vivo手机玩游戏");
}
@Override
public void message() {
System.out.println("Vivo手机发消息");
}
}
// PhoneFactory 工厂类
public class PhoneFactory {
public static Phone createPhone(String type) {
Phone phone = null;
if (type.equals("小米")){
phone = new XIAOMIPhone();
}else if(type.equals("VIVO")){
phone = new VIVOPhone();
}
return phone;
}
}
// PhoneSupermarket
public class PhoneSupermarket {
public static void main(String[] args) {
String phoneType = "";
BufferedReader br = new BufferedReader(new InputStreamReader(System.in ));
System.out.print("输入手机型号:");
try {
phoneType = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
// 调用方法创建对象
Phone phone = PhoneFactory.createPhone(phoneType);
phone.study();
phone.message();
phone.game();
}
}
工厂方法模式
上面的简单方法模式,实现了卖手机的功能,现在升级了一下,不仅要卖手机,还要卖电脑,这样子就需要两个工厂的类, 如果再拓展,需要更多的工厂类,比较麻烦。
所以推荐使用工厂方法模式,工厂方法模式的核心就是一句话,将工厂类的实例化方法进行抽象,派生相关的手机工厂,电脑工厂等子类去实现抽象的实例化方法。 进一步降低耦合度
类结构,其中InstanceFactory是抽象类,就是所谓的工厂角色,但是创建实例的方法在XXXFactory中实现 看完类结构之后走一下代码 只展示修改的三个工厂类
public abstract class InstanceFactory {
public abstract Product createInstance(String type);
public InstanceFactory() {
Product product = null;
String productType;
productType = getType();
product = createInstance(productType); // 抽象方法 由工厂子类实现
product.study();
product.game();
product.message();
}
public String getType(){
String productType = "";
BufferedReader br = new BufferedReader(new InputStreamReader(System.in ));
System.out.print("输入设备型号:");
try {
productType = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return productType;
}
}
// 电脑工厂实现类
public class ComputerFactory extends InstanceFactory{
@Override
public Product createInstance(String type) {
Product product = null;
if (type.equals("小米")){
product = new XIAOMIComputer();
}else if (type.equals("Apple")){
product = new AppleComputer();
}
return product;
}
}
// 手机工厂实现类
public class PhoneFactory extends InstanceFactory{
@Override
public Product createInstance(String type) {
Product product = null;
if (type.equals("小米")){
product = new XIAOMIPhone();
}else if (type.equals("VIVO")){
product = new VIVOPhone();
}
return product;
}
}
经过这样的改动之后,可以将职责划分的更加明确,由统一的工厂角色进行管理,各个子类进行实现创建实例。
抽象工厂模式
这个比较好理解,不再画类图了哈,其实就是将工厂方法模式中的抽象类,换成了接口,然后各个具体的工厂实现接口,这样在客户端调用的时候,可以直接创建接口类型,其实就是完善了依赖倒置的思想。
依赖倒置
高层模块不应该依赖底层模块 二者都应该依赖其抽象
抽象不应该依赖细节,细节应该依赖抽象
类结构如下图所示 抽象工厂模式只是对工厂方法模式+简单工厂模式进行了进一步的封装,完善了依赖倒置 面向接口编程的思想。
全面发展,一专多能!!!