简单工厂模式
介绍:
将创建对象的动作封装成一个方法(可以为静态),根据入参值的不同,返回不同类型的对象。
好处:
- . 隐藏对象创建细节
- . 客户端不需要再依赖具体的对象类(代码里表现为需要import各种类),依赖关系全部转嫁到工厂类中,客户端只需要依赖一个工厂类即可。
缺点: - 扩展性差,当需要增加类型时同样需要修改工厂类的代码。
扩展: - 利用反射的方法拿到入参的类,并通过类的instance方法创建对象,该方法能够一定程度上扩展简单工厂模式需要频繁修改的情况,但对于一些定制对象的生产无法适用。
工厂方法模式
介绍:
使用抽象类或者接口定义同一产品等级的产品对象产生方法,具体的对象生产动作延迟到子类工厂中进行。
优点:
- 当同一产品等级的产品需要增加时,只需要创建新的产品生产工厂即可。
缺点: - 当产品族发生更改时,会导致类爆炸(所有类都要修改)的情况发生。
举例
- JDK中的Collection接口中定义的iterator方法,返回一个迭代器,子类Arraylist和Linkedlist的该方法均是工厂方法,均返回的自身内部类实现的Itr
抽象工厂模式
介绍:
在接口或抽象类中定义同一产品族的产品对象的生产方法,子类工厂负责具体的创建工作,能够生产同一产品族的多个产品。
区别:
- 相比较工厂方法模式,抽象工程模式下的各个工厂生产的对象属于同一产品族,反应在代码里为各个方法返回的对象类型并不完全一样,但是均属于某个特定产品类型下的产品。如华为的手机/电脑/手表,均属于华为,是一个产品族,生产的对象也是有手机/电脑/手表等多种。
- 工程方法模式中的工程返回的对象的类型均是一致的。如华为手机/苹果手机/三星手机,全是手机,属于同一产品等级,生产的对象也全是手机。
举例
- java.sql.connection
- java.sql.statement
- mybatis.sqlsessionfactory
代码
通用bean定义
public abstract class Student {
public abstract void say();
}
public class ManStudent extends Student{
@Override
public void say() {
System.out.printf("我是男学生");
}
}
public class WomenStudent extends Student{
@Override
public void say() {
System.out.println("我是女学生");
}
}
public abstract class Teacher {
public abstract void say();
}
简单工厂
public class EasyFactory {
public Student createInstance(String type){
if (type.equals("man")){
return new ManStudent();
}
if (type.equals("women")){
return new WomenStudent();
}
return null;
}
}
public class Test {
public static void main(String[] args) {
EasyFactory factory = new EasyFactory();
Student s = factory.createInstance("man");
s.say();//我是男学生
}
}
如上,如果如要增加学生类别,需要更改工厂类。
使用反射扩展,但只能应用在简单对象创建:
public class EasyFactory {
public Student createInstance(String className) throws Exception{
return (Student)Class.forName(className).newInstance();
}
}
工厂方法
public interface MethodFactory {
Student createStudent();
}
public class ManFactory implements MethodFactory {
@Override
public Student createStudent() {
return new ManStudent();
}
}
public class WomenFactory implements MethodFactory {
@Override
public Student createStudent() {
return new WomenStudent();
}
}
public class Test {
public static void main(String[] args) {
MethodFactory factory = new ManFactory();
Student s = factory.createStudent();
s.say();//我是男学生
}
}
如上,要增加女学生对象的生产,只需要增加新的女学生建造工厂即可,无需更改原有工厂。
但如果不增加学生,要增加老师,则无法应对这种情况。
抽象工厂
假如要组建学习小组,小组内必须有一名老师一名学生,则使用抽象工程模式,将老师和学生组装成一个组,即产品族的定义。假如需要一个组是一男一女,直接增加新的GroupFactory即可。
public interface AbstFactory {
Student createStudent();
Teacher createTeacher();
}
public class ManGroupFactory implements AbstFactory {
@Override
public Student createStudent() {
return new ManStudent();
}
@Override
public Teacher createTeacher() {
return new ManTeacher();
}
}
public class WomenGroupFactory implements AbstFactory {
@Override
public Student createStudent() {
return new WomenStudent();
}
@Override
public Teacher createTeacher() {
return new WomenTeacher();
}
}
public class Test {
public static void main(String[] args) {
AbstFactory factory = new ManFactory();
Student s = factory.createStudent();
Teacher t = factory.createTeacher();
s.say();//我是男学生
t.say();//我是男老师
}
}