目录
一、工厂模式(Factory Pattern)
工厂模式是Java中最常用的设计模式之一,属于创建型模式。
二、简单工厂模式
简单工厂模式并不是23种设计模式之一,因为它不符合开闭原则,主要目的是为了引出工厂方法模式,适合产品子类比较少的,操作比较简单的情况。
有一个工厂类,负责生产某一类产品。同一类产品,具备同一个抽象父类(抽象类,接口),将创建对象与使用对象分离(spring框架就是这种设计思想)。简单工厂模式违背了开闭原则,因为添加一个产品,就需要修改工厂代码。
由一个工厂根据传入的参数(一般是字符串参数),动态决定应该创建哪一个产品子类的实例,并以父类形式返回。具体看下面的例子。
该模式中包含的角色及职责:
1.工厂角色:简单工厂模式的核心,它负责实现创建所以实例的内部逻辑。工厂类提供静态方法,可以被外界直接调用,创建所需要的产品对象。
2.抽象产品角色:简单工厂模式所创建的所有对象的父类,描述所有实例共有的接口,可以是抽象类或接口。
3.具体产品角色:是简单工厂模式的创建目标。
优点:
客户端不负责对象的创建,而是由专门的工厂类完成;客户端只负责对象的调用,实现了创建和调用的分离,降低了客户端代码的难度。
缺点:
如果增加和减少产品子类,需要修改简单工厂类,违背了开闭原则。如果产品子类过多,会导致工厂类非常庞大,违反了开闭原则,不利于后期维护。
适用场景:
所有的产品子类都有同一个父类(或接口),属于同一个产品系列产品子类比较少而且创建操作比较简单。
例如:有一个专门生产Car的工厂类,负责生产奥迪汽车和宝马汽车,并且同一类汽车具备同一种功能(接口或抽象父类)。并且将创建对象和使用对象分离。
public class Aodi implements Car{
@Override
public void run() {
System.out.println("奥迪汽车行驶");
}
}
public class Bmw implements Car{
@Override
public void run() {
System.out.println("宝马汽车行驶");
}
}
public interface Car {
void run();
}
public class CarFactory {
public static Car createCar(String name){
if(name.equals("aodi")){
return new Aodi();
}
if(name.equals("bmw")){
return new Bmw();
}
return null;
}
}
public class Test {
public static void main(String[] args) {
Car bmw = CarFactory.createCar("bmw");
Car aodi = CarFactory.createCar("aodi");
bmw.run();
aodi.run();
}
}
测试结果:
三、工厂方法模式
在简单模式的基础之上,对工厂进行抽象,一个抽象的产品对应一个抽象的工厂,一个具体的产品对应一个具体的工厂,一个具体的工厂负责生产一个具体的产品。需要扩展新产品时,只需要添加新的具体产品类和新的生产该产品的具体工厂类即可,符合开闭原则。
该模式中包含的角色及其职责:
1.抽象工厂角色:工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
2.具体工厂接口:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用用以创建产品对象。
3.抽象产品角色:工厂方法模式所创建的对象的父类,就是产品对象个共同父类或共同拥有的接口。
4.具体产品角色;这个角色实现了抽象产品角色所定义的接口。某聚体产品有专门的具体工厂窗创建,它们之间往往一一对应。
优点:
客户端不负责对象的创建,而是由专门的工厂类完成;客户端只负责对象的调用,实现了创建和调用的分离,降低了客户端代码的难度;若增加和减少产品子类,不需要修改工厂类,只增加产品子类和工厂子类,符合开闭原则。即使产品子类过多,不会导致工厂类的庞大,利于后期维护。
缺点:
需要编写额外的代码,增加了工作量
例如:
public class Aodi implements Car {
@Override
public void run() {
System.out.println("奥迪汽车行驶");
}
}
public class Bmw implements Car {
@Override
public void run() {
System.out.println("宝马汽车行驶");
}
}
public class AodiFactory implements CarFactory{
@Override
public Car createCar() {
return new Aodi();
}
}
public class BmwFactory implements CarFactory{
@Override
public Car createCar() {
return new Bmw();
}
}
public interface Car {
void run();
}
public interface CarFactory {
Car createCar();
}
public class Test {
public static void main(String[] args) {
CarFactory aodicarFactory = new AodiFactory();
Car aodi = aodicarFactory.createCar();
aodi.run();
CarFactory bmwcarFactory = new BmwFactory();
Car bmw = bmwcarFactory.createCar();
bmw.run();
}
}
四、抽象工厂模式
简单工厂模式中,一个工厂负责同一类所有产品对象的创建,如果产品较多,职责大大增加,增加或减少产品时,需要修改工厂类,违背了开闭原则。
工厂方法模式中,一个具体的工厂类负责创建一个单独的产品,如果产品增加或减少,不需要修改工厂类,符合开闭原则。但是如果这些产品之间是有联系的,也必须有不同的工厂分别创建。
抽象工厂模式:一个具体的工厂负责创建一系列互相关联的产品(华为手机,华为汽车),在抽象的工厂中定义不同的产品,具体的工厂负责一个公司一系列产品。
该模式中包含的角色及其职责:
抽象工厂、具体工厂、抽象产品、具体产品
优点:
获取具体系列产品只需要通过具体系列工厂获取,无须关心创建的细节。
例如:
public class AodiCar implements Car{
@Override
public void run() {
System.out.println("奥迪汽车行驶");
}
}
public class AodiFactory implements AbstractFactory{
@Override
public Car getCar() {
return new AodiCar();
}
@Override
public Phone getPhone() {
return new AodiPhone();
}
}
public class AodiPhone implements Phone{
@Override
public void call() {
System.out.println("奥迪手机打电话");
}
}
public class BmwCar implements Car{
@Override
public void run() {
System.out.println("宝马汽车行驶");
}
}
public class BmwFactory implements AbstractFactory{
@Override
public Car getCar() {
return new BmwCar();
}
@Override
public Phone getPhone() {
return new BmwPhone();
}
}
public class BmwPhone implements Phone {
@Override
public void call() {
System.out.println("宝马手机打电话");
}
}
public interface Car {
void run();
}
public interface AbstractFactory {
Car getCar();
Phone getPhone();
}
public interface Phone {
void call();
}
public class Test {
public static void main(String[] args) {
AbstractFactory aodiFactory = new AodiFactory();
Car aodiCar = aodiFactory.getCar();
Phone aodiphone = aodiFactory.getPhone();
aodiCar.run();
aodiphone.call();
AbstractFactory bmwFactory = new BmwFactory();
Car bmwCar = bmwFactory.getCar();
Phone bmwPhone = bmwFactory.getPhone();
bmwCar.run();
bmwPhone.call();
}
}
运行结果: