工厂方法模式
默认情况下,我们都是直接使用new
的方式去创建对象,但是当我们的程序中大量使用这种方式进行创建对象时,如果这个类的构造方法发生了改变,那就要挨个去进行修改。
因此我们可以直接通过工厂来创建对象,这样如果后续要进行修改,只需要修改工厂类中的实现细节即可。
public class App {
public static void main(String[] args) {
Fruit fruit = FruitFactory.getFruit("apple");
System.out.println(fruit);
}
}
class Fruit {
private String name;
public Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return "Fruit [name=" + name + "]";
}
}
class Apple extends Fruit {
public Apple() {
super("苹果");
}
}
class Orange extends Fruit {
public Orange() {
super("橘子");
}
}
class FruitFactory {
public static Fruit getFruit(String fruitName) {
switch (fruitName) {
case "apple":
return new Apple();
case "orange":
return new Orange();
default:
return null;
}
}
}
这样,根据给工厂类传入的参数不同,就可以创建、获取不同类的对象。
但上述方式也存在一些问题
如果现在要先加一种类型的水果,那么除了要创建一个新的类以外,还要修改工厂类中的代码,这显然是违背了开闭原则的
因此我们将代码修改为如下:
创建一个抽象工厂类,来定义一种规则,并使用泛型来约束入参
具体的工厂类只需要继承这个抽象类,并定义自身的行为即可
整体代码如下
package code2;
class Fruit {
private String name;
public Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return "Fruit [name=" + name + "]";
}
}
class Apple extends Fruit {
public Apple() {
super("苹果");
}
}
class Orange extends Fruit {
public Orange() {
super("橘子");
}
}
abstract class FruitFactory<T extends Fruit> {
public abstract T getFruit();
}
class AppleFactory extends FruitFactory<Apple> {
@Override
public Apple getFruit() {
return new Apple();
}
}
class OrangeFactory extends FruitFactory<Orange> {
@Override
public Orange getFruit() {
return new Orange();
}
}
public class App {
public static void main(String[] args) {
// 通过AppleFactory获取Apple对象
Apple apple = new AppleFactory().getFruit();
System.out.println(apple);
}
}
抽象工厂模式
建造者模式
如果某个类中的字段数目太多,那么在手动new
创建对象的时候,就会导致需要传递太多参数。
package code3;
public class App2 {
public static void main(String[] args) {
Student student = new Student(1, "yxr", 19, "三峡大学");
System.out.println(student);
}
}
// 省略了构造函数等方法
class Student {
private Integer id;
private String name;
private Integer age;
private String college;
}
为了避免传递过多的参数,并且让方法支持链式调用,我们可以使用建造者模式,通过builder
来创建对象