java设计模式---(2)工厂模式

工厂模式就是自己不去实例化对象,而使用对象工厂去实例化对象,大致分3种:简单工厂模式、工厂模式、抽象工厂模式
先定义几个类:Person类,人这个类是个父类,而人分很多种人,这里举例子有Student类和Teacher类继承了Person类。

简单工厂模式

public class PersonFactory {
	public static Person createPerson(String type) {
		Person person = null;
		switch (type) {
		case "student":
			person = new Student();
			break;
		case "teacher":
			person = new Teacher();
			break;
		}
		return person;
	}
}

定义一个人类工厂,工厂有个静态方法根据不同类型的参数来造不同的人:

	public static void main(String[] args) {
		Student student = (Student) PersonFactory.createPerson("student");
		System.out.println(student.toString()); // Student [grade=null, classes=null, school=null,name=null]
	}

这是最简单的工厂模式,在业务简单中他的确比较好使。但是他有个问题就是工厂类里面的设计不符合“开放-封闭”原则。如果业务有改动,比如要加个Master校长类,就得去改这个类,每次修改业务都要去改工厂类,这是不合适的。所以在简单工厂模式的基础上有个工厂模式。

工厂模式
为了不去改工厂类中的方法,所以把工厂类做成一个接口,接口中定义工厂方法:

public interface PersonFactory {
	public Person createPerson();
}

然后根据工厂类中的各个条件分支分别去写各种工厂接口的实现类,创建学生的工厂类StudentFactory

public class StudentFactory implements PersonFactory{
	public Student createPerson(){
		return new Student();
	}
}

创建老师的工厂类TeacherFactory

public class TeacherFactory implements PersonFactory{
	public Teacher createPerson(){
		return new Teacher();
	}
}

如果再要加创建校长的工厂类的话只需要实现PersonFactory接口,然后按照其逻辑来实现createPerson()方法即可。
调用的地方 直接调用相应的实现类中的方法就可以创建相应的对象了:

	public static void main(String[] args) {
		PersonFactory factory = new StudentFactory();
		Person student = factory.createPerson();
		System.out.println(student.toString()); // Student [grade=null, classes=null, school=null,name=null]
	}

然而这样也不是完全就没有任何问题的,相像一下如果要创建世界上所有职业类型的人类,那就要去写“司机”、“前台”、“老板”…无数个工厂类了,这肯定是不行的,所以代码可以再提练一下:

public class PersonFactory {

	@SuppressWarnings("unchecked")
	public <T extends Person> T createPerson(Class<T> clazz) {
		Person p = null;
		try {
			p = (Person) Class.forName(clazz.getName()).newInstance();
		} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return (T) p;
	}
}

利用反射来动态的传一个类类型过来,然后再根据类类型来创建对应的对象,这样就不用去写各种类型的实现工厂类了。测试如下:

public class PersonFactoryTest {

	public static void main(String[] args) {
		PersonFactory personFactory = new PersonFactory();
		Student student = personFactory.createPerson(Student.class);
		System.out.println(student.toString()); // // Student [grade=null, classes=null, school=null,name=null]
	}
}

这样就不用再去一个个的写工厂类了,只用写继承Person类的实体类就行了。

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。抽象工厂模式意图提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。主要解决接口选择的问题,系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
接着上面的代码举例子,这里先定义一个“系列产品”:StudentFemaleStudentMaleTeacherFemaleTeacherMale分别是女学生、男学生、女老师、男教师。他们可以抽象成2类,男性、女性:

// 男性产品抽象接口
public interface IMale {
	void printName();
}
// 女性产品抽象接口
public interface IFemale {
	void printName();
}

每个产品分别实现对应的抽象接口,此处只贴一个“产品”,男老师的代码,其他几个的代码都是一样的:

public class TeacherMale implements IMale {
	private String name;
	@Override
	public void printName() {
		System.out.println("TeacherMale..."+this.name);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public TeacherMale(String name) {
		super();
		this.name = name;
		System.out.println("TeacherMale...constructor");
	}
}

“产品”定义好了,再定义一下超级工厂PersonFactory接口:

public interface PersonFactory {

	IMale createMale(String name);

	IFemale createFemale(String name);
}

这个工厂里面定义2个接口,创建男性和创建女性,超级工厂定义好了后,一般的工厂再来实现这个超级工厂:
创建学生的工厂StudentFactory类:

public class StudentFactory implements PersonFactory {

	@Override
	public IMale createMale(String name) {
		return new StudentMale(name);
	}

	@Override
	public IFemale createFemale(String name) {
		return new StudentFemale(name);
	}

}

创建老师的工厂TeacherFactory类:

public class TeacherFactory implements PersonFactory {

	@Override
	public IMale createMale(String name) {
		return new TeacherMale(name);
	}

	@Override
	public IFemale createFemale(String name) {
		return new TeacherFemale(name);
	}
}

至此抽象工厂模式就写好了,看测试:

public class MainTest {

	public static void main(String[] args) {
		StudentFactory sf = new StudentFactory();
		TeacherFactory tf = new TeacherFactory();

		IFemale studnetFemale = sf.createFemale("女学生");
		IMale studnetMale = sf.createMale("男学生");
		IFemale teacherFemale = tf.createFemale("女教师");
		IMale teacherMale = tf.createMale("男教师");

		studnetFemale.printName();
		studnetMale.printName();
		teacherFemale.printName();
		teacherMale.printName();
	}

}

测试输出:

StudentFemale...constructor
StudentMale...constructor
TeacherFemale...constructor
TeacherMale...constructor
StudentFemale...女 学生
StudentMale...男 学生
TeacherFemale...女 教师
TeacherMale...男 教师

最后再画个草图示意一下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u012843361/article/details/84791529