设计模式是干啥的?有啥用?
首先需要明白的是设计模式并不是新的语法,而是一种优雅的代码组织方式。
举个最简单的例子,我们为默认编码utf-8定义一个常量,这样我们的项目在指定编码的时候都可以引用Constants.DEFAUL_CHARSET
,如果更换编码的时候我们不用一个个去找utf-8这个字符串,而是直接更改Constants.DEFAUL_CHARSET
的值就行了。
这其中就蕴含了一中代码组织的思想——避免重复——重复可能会带来难以维护的问题。
public class Constants {
public static final String DEFAULT_CHARSET="utf-8";
}
在代码发展的悠久过程中,产生了很多使用的代码组织思想,其中有些异常经典的思想经过总结后,形成了常用的设计模式,通过了解设计模式,可以吸收一些好的方法,让我们的代码更加合理、健壮、可维护、可拓展。
工厂模式1.0——极简版本工厂是干嘛的地方,就是一个批量生产东西的地方。在我们的项目中如果有一些对象经常被需要,那么我们不用自己制造,让工厂去制造就OK了,比如针对学生类
public class Student {
private String id;
private String name;
private String sex;
private String age;
//省略get set方法
}
我们在测试中各处代码都需要一个随机用户,相当于每次都得自己制造一个Student对象
//常规写法
Student randStudent=new Student();
randStudent.setId(UUID.randomUUID().toString());//通过UUID产生一个唯一id
randStudent.setName("张三");
randStudent.setAge("20");
randStudent.setSex("男");
每个地方都写这样的代码,也就是说多次制造这个对象都得自己来,那不如让工厂批量制造,所以可以用工厂模式:
/**
* 学生工厂
* @author easypanda
* @date 2018-06-28
*/
public class StudentFactory {
public static Student createRandStudent(){
Student randStudent=new Student();
randStudent.setId(UUID.randomUUID().toString());//通过UUID产生一个唯一id
randStudent.setName("张三");
randStudent.setAge("20");
randStudent.setSex("男");
return randStudent;
}
}
Student randStudent=StudentFactory.createRandStudent();//每次使用从工厂生产即可
工厂模式2.0——拓宽产品种类
靠一种产品打天下是行不通的,比如小米手机,低中高配置都得有,比如海尔,电冰箱、洗衣机热水器都有,这样效率高。
同样,工厂模式的工厂不能只生产一种对象,而是生产很多类似的对象。
/**
* 抽象用户接口
* @author easypanda
* @date 2018-06-28
*/
public interface User {
}
/**
* 学生类
* @author easypanda
* @date 2018-06-28
*/
public class Student implements User{
private String id;
private String name;
private String sex;
private String age;
//省略get set
}
/**
* 教师类
* @author easypanda
* @date 2018-06-28
*/
public class Teacher {
private String id;
private String name;
private String sex;
private String age;
private String course;//教学科目
//省略get set
}
/**
* 用户工厂,可以产生各类用户
* @author easypanda
* @date 2018-06-28
*/
public class UserFactory {
public static User createUser(String userType){
if(userType.equals("Teacher"))
return new Teacher();
else if(userType.equals("Student"))
return new Student();
else
return null;
}
}
工厂模式3.0——精准的产品线
产品多了有个问题啊,就是自己的业务员都弄不明白各种产品之间的区别,很容易搞错。
比如上面的工厂,如果程序员忘了可以产生的用户种类仅有Teacher和Student,他调用UserFactory .createUser("schoolmaster;")
想弄个校长,结果就不成了,很容易引起错误。
如果控制呢,利用枚举就好了,因为枚举就是限定类型的啊。
/**
* 用户类型枚举
* @author easypanda
* @date 2018-06-28
*/
public enum UserType {
STUDENT,TEACHER;
}
/**
* 用户工厂,可以产生各类用户
* @author easypanda
* @date 2018-06-28
*/
public class UserFactory {
public static User createUser(UserType userType){
if(userType==UserType.TEACHER)
return new Teacher();
else if(userType==UserType.TEACHER)
return new Student();
}
}
这样才生产的时候,必须严格按照已有类型生产:
User user=UserFactory.createUser(UserType.STUDENT);
总结
工厂模式说白了就是反复做的生成对象的代码,放到工厂里面批量做,以避免一个一个的做带来的诸多问题——分散难以维护效率低。
同时在工厂里也好集中监管,必须按照工艺规定(枚举)生产,保证了管理水平。