只是目前阶段 对本书第一章内容的浅显认知,说实话 这一章 我看了4遍左右,每一遍感觉都不一样
他的创建模式 有时候像设计模式,但作者已经在原文中描述,它并不等价于 设计模式
我们正常 创建一个年级类 是长这样的
我们不写成标准的javabean模式 ,只是对 静态工厂方法 代替构造方法 一章的内容进行自己简单的理解实现
这样写的 正常的,但是 这样的对未来 扩展性可能不是那么好,而且我们每次实例化该对象都需要new 一个,而且假如该对象 日后 成员变量增多,逻辑复杂,加载对象变多,我们 new对象的成本会增多, 用new 对象的方法 有时候对比于静态工厂方法 不够 清晰 所以我们 就可以用静态工厂方法代替构造方法
怎么代替 看如下代码
1.与构造方法不同 静态工厂方法代替构造方法 时候,静态工厂方法具有名字,比较清晰
这样构造好之后,我们在test 类中测试一下
2.与构造方法不同的是 不需要每次都创建一个新对象
跟单例设计模式有点像,但是 作者已经在文中标注 他不等价于任何的设计模式
同时可以用该静态方法 限制了随意创建新对象
3.与构造方法不同,它们可以返回其返回类型的任何子类型的对象
同时他也是第四个优点
4.是返回对象的类可以根据输入参数的不同而不同
直接看代码
interface GradeLeader {
void print();
}
class teacher1 implements GradeLeader{
@Override
public void print() {
System.out.println("我是teacher1 我被年级领导管理");
}
}
class teacher2 implements GradeLeader{
@Override
public void print() {
System.out.println("我是teacher2 我被年级领导管理");
}
}
public class GradeFactory {
public static GradeLeader valueOf(String teacherName){
if(teacherName.equalsIgnoreCase("teacher1")){
//这里返回的是 teacher 类型 的类 而不是 GradeLeader接口的实现
return new teacher1();
} else if (teacherName.equalsIgnoreCase("teacher2")) {
return new teacher2();
}
throw new IllegalArgumentException("输入的老师名称 没有所属的领导啦");
}
}
当然 你也可以不用接口,用类,直接继承 也是可以的这样我们只需要 选择 是创建哪个类就行了 ,而不需要在乎他的具体类创建时的逻辑实现
5.静态工厂的第五个优点是,在编写包含该方法的类时,返回的对象的类不需要存在
他的意思是 说 我们现在工厂方法里面只能返回teacher1 teacher2 对吧,假如说 我们将来想返回一个teacher3 ,我们完全可以 常见一个teacher3类,然后实现 Gradeleader 接口,然后再修改静态工厂方法 valueof就可以了,我们就不需要 修改 gradeleader 的接口内容,遵循开闭原则,对外扩展开放,对修改关闭
缺点
因为我们 有参 无参的构造全都是 私有的 ,所以我们无法继承该类
因为都是私有的 ,我们只关心输入参数,创建出来类使用就行了,但不知道内部的 一些内容,将来类中的静态工厂的方法多了之后,我们就很难找到 我们想要的实现的那个类 应该输入什么参数才能被创建出来
工厂类常用命名 从 书中copy 过来的
- from —— 类型转换方法,它接受单个参数并返回此类型的相应实例,例如:Date d = Date.from(instant);
- of —— 聚合方法,接受多个参数并返回该类型的实例,并把他们合并在一起,例如:Set\ faceCards = EnumSet.of(JACK, QUEEN, KING);
- valueOf —— from 和 to 更为详细的替代 方式,例如:BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
- instance 或 getinstance —— 返回一个由其参数 (如果有的话) 描述的实例,但不能说它具有相同的值,例如:StackWalker luke = StackWalker.getInstance(options);
- create 或 newInstance —— 与 instance 或 getInstance 类似,除此之外该方法保证每次调用返回一个新的实例,例如:Object newArray = Array.newInstance(classObject, arrayLen);
- getType —— 与 getInstance 类似,但是在工厂方法处于不同的类中的时候使用。getType 中的 Type 是工厂方法返回的对象类型,例如:FileStore fs = Files.getFileStore(path);
- newType —— 与 newInstance 类似,但是在工厂方法处于不同的类中的时候使用。newType中的 Type 是工厂方法返回的对象类型,例如:BufferedReader br = Files.newBufferedReader(path);
- type —— getType 和 newType 简洁的替代方式,例如:List\ litany = Collections.list(legacyLitany);
具体用公共构造方法 还是 静态工厂 还是看后期的需求