工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
什么时候使用工厂模式
1.当一个类不知道它所必须创建的对象的类的时候。
2.当一个类希望由它的子类来指定它所创建的对象的时候。
3.当将创建对象的职责委托给多个帮助类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化的时候。
使用工厂模式的好处
- ① new对象的话,一旦代码有变化或者拓展,就必须改变原来的代码,也就是说你的代码并“对修改关闭”
- ② 解耦,便于更新和维护;
工厂模式的应用场景
- 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
- 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏
- 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无需关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
工厂模式的分类
1. 简单工厂模式(Simple Factory)
2. 工厂方法模式(Factory Method)
3. 抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。还有一种分类法,就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。两者皆可,这本为使用《Java与模式》的分类方法。
实现工厂模式的几种方法
简单工厂实例
你会建立一个专门生产Sample实例的工厂:
package DesignPattern.simplefactory;
public class BoxFactory {
public static Box creatBox(Class<? extends Box> c){
Object box = null;
try {
box = Class.forName(c.getName()).newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (Box) box;
}
}
RedBox.class
package DesignPattern.simplefactory;
public class RedBox implements Box{
@Override
public void doSome() {
System.out.println("this is red box");
}
}
Box.class
package DesignPattern.simplefactory;
public interface Box {
void doSome();
}
Box instance = BoxFactory.creatBox(RedBox.class); 那么在你的程序中,如果要创建instance 的实列时候可以使用
这样,在整个就不涉及到instance 的具体的实现类,达到封装效果,也就减少错误修改的机会,这个原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易犯错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,犯错误可能性就越少.好象我们从编程序中也能悟出人生道理。
使用工厂方法 要注意几个角色,首先你要定义产品接口,如上面的Box类的接口,产品接口下有Box接口的实现类,如RedBox,其次要有一个Factory类,用来生成产品Box接口的具体实例。
抽象工厂实例
就拿生活中的一个实例来描述如何创建一个抽象工厂
小米工厂,会创建小米电脑,和小米本
苹果工厂,会创建苹果手机,和苹果本
而小米工厂和苹果工厂都隶属于工厂,小米手机和苹果手机都是手机,反之电脑也是一样
有上述场景可以写出下面的代码
(1)创建相关接口:
手机
public interface Moible {
void showMoible();
}
电脑
public interface Computer {
void showComputer();
}
(2)创建接口对应实现类:
小米手机
public class XiaoMiMoible implements Moible{
@Override
public void showMoible() {
System.out.println("这是一个小米手机");
}
}
小米电脑
public class XiaoMiComputer implements Computer{
@Override
public void showComputer() {
System.out.println("这是个小米本");
}
}
苹果手机
public class IphoneMoible implements Moible {
@Override
public void showMoible() {
System.out.println("这是一个苹果手机");
}
}
苹果电脑
public class IphoneComputer implements Computer{
@Override
public void showComputer() {
System.out.println("这是个苹果本");
}
}
(3)创建工厂接口
public interface Factory {
Computer createComputer();
Moible createMoible();
}
(4)创建具体工厂
小米工厂创建小米电脑和小米手机
public class XiaoMiFactory implements Factory{
@Override
public Computer createComputer() {
return new XiaoMiComputer();
}
@Override
public Moible createMoible() {
return new XiaoMiMoible();
}
}
苹果工厂创建苹果手机和苹果电脑
public class IphoneFactory implements Factory{
@Override
public Computer createComputer() {
return new IphoneComputer();
}
@Override
public Moible createMoible() {
return new IphoneMoible();
}
}
上面是一个简单的例子,个人之前没有用过,也是最近看工厂模式才试着写的。
简单工厂的创建和抽象工厂都离不开借口以及接口的实现,通过写了一系列代码感觉,抽象工厂还需要将工厂写成抽象的,在根据实际需求写工厂的实例来获得不同的对象。
面试时候可能问到的问题
可能文中会存在一些问题,请指出,方便及时修改,也防止对别人产生误导