Java 的静态工厂模式和抽象工厂模式
1、静态工厂模式
静态工厂模式,在平常开发中是比较常见的。
1.1、优缺点
- 优点:
- 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,明确了职责。
- 把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则,面向接口编程,而不是面向实现编程。
- 缺点:
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 要新增产品类的时候,就要修改工厂类的代码,违反了开放封闭原则。即:对扩展的开放,对修改的关闭。
- 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构.
1.2、实现案例
- 代码结构:
1.2.1、抽象类
package com.dsj.demo.staticfactory.service;
public abstract class FoodsService {
/**
* 烹饪
*/
public abstract void cook();
}
1.2.2、实现类
FishServiceImpl
package com.dsj.demo.staticfactory.service;
public class FishServiceImpl extends FoodsService {
@Override
public void cook() {
System.out.println("服务员,来一盘红烧鱼 !!!");
}
}
MeetServiceImpl
package com.dsj.demo.staticfactory.service;
/**
* @author Pengzf
*/
public class MeetServiceImpl extends FoodsService {
@Override
public void cook() {
System.out.println("服务员,来一盘红烧肉 !!!");
}
}
1.2.3、静态工厂类
StaticFactoryBeans
package com.dsj.demo.staticfactory;
import com.dsj.demo.staticfactory.service.FishServiceImpl;
import com.dsj.demo.staticfactory.service.FoodsService;
import com.dsj.demo.staticfactory.service.MeetServiceImpl;
public class StaticFactoryBeans {
public static FoodsService createFishBean () {
return new FishServiceImpl();
}
public static FoodsService createMeetBean() {
return new MeetServiceImpl();
}
}
1.2.4、测试类
package com.dsj.demo.staticfactory;
import com.dsj.demo.staticfactory.service.FoodsService;
public class TestStaticFactory {
public static void main(String[] args) {
FoodsService foodsService1 = StaticFactoryBeans.createFishBean();
foodsService1.cook();
FoodsService foodsService2 = StaticFactoryBeans.createMeetBean();
foodsService2.cook();
}
}
- 测试类执行结果如下:
服务员,来一盘红烧鱼 !!!
服务员,来一盘红烧肉 !!!
2、抽象工厂模式
- 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
- 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
2.1、适用场景
-
一个系统要独立于它的产品的创建、组合和表示时。
-
一个系统要由多个产品系列中的一个来配置时。
-
需要强调一系列相关的产品对象的设计以便进行联合使用时。
-
提供一个产品类库,而只想显示它们的接口而不是实现时。
-
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
2.2、案例介绍
该案例是多个产品族,每个产品族又存在多个不同产品的场景。实际工作中,可能只有一个产品族,可根据实际场景,将该案例简化使用。该案例所想表达的是抽象工厂的思想,具体可根据不同业务场景,酌情优化调整使用。
- 代码结构:
2.2.1、抽象类
- 产品抽象类 (
CarService
)
package com.dsj.demo.abstractfactory.service;
public abstract class CarService {
/**
* 驾驶
*/
public abstract void driver();
}
- 产品族抽象类 - 奥迪 (
AudiService
)
package com.dsj.demo.abstractfactory.service;
public abstract class AudiService extends CarService {
/**
* 自我介绍
*/
public abstract void selfIntroduction();
}
- 产品族抽象类 - 沃尔沃 (
VolvoService
)
package com.dsj.demo.abstractfactory.service;
public abstract class VolvoService extends CarService {
/**
* 售后
*/
public abstract void afterSale ();
}
2.2.2、实现类
- 奥迪系列 - A4 (
AudiA4ServiceImpl
)
package com.dsj.demo.abstractfactory.service;
public class AudiA4ServiceImpl extends AudiService{
@Override
public void driver() {
System.out.println("驾驶奥迪A4 !!!");
}
@Override
public void selfIntroduction() {
System.out.println("这里是奥迪A4 !!!");
}
}
- 奥迪系列 - A6 (
AudiA6ServiceImpl
)
package com.dsj.demo.abstractfactory.service;
public class AudiA6ServiceImpl extends AudiService{
@Override
public void driver() {
System.out.println("驾驶奥迪A6 !!!");
}
@Override
public void selfIntroduction() {
System.out.println("这里是奥迪A6 !!!");
}
}
- 沃尔沃系列 - S90(
VolvoS90ServiceImpl
)
package com.dsj.demo.abstractfactory.service;
public class VolvoS90ServiceImpl extends VolvoService {
@Override
public void driver() {
System.out.println("驾驶 沃尔沃 S90, 倍爽!!!");
}
@Override
public void afterSale() {
System.out.println("沃尔沃 S90, 为您提供尊贵售后服务!!!");
}
}
- 沃尔沃系列 - XC60(
VolVoXC60ServiceImpl
)
package com.dsj.demo.abstractfactory.service;
public class VolVoXC60ServiceImpl extends VolvoService {
@Override
public void driver() {
System.out.println("驾驶沃尔沃 XC60,倍爽!");
}
@Override
public void afterSale() {
System.out.println("沃尔沃 XC60, 为您提供尊贵售后服务!!!");
}
}
2.2.3、工厂类
- 抽象工厂类 - (
AbstractFactoryBean
)
package com.dsj.demo.abstractfactory;
import com.dsj.demo.abstractfactory.service.CarService;
public abstract class AbstractFactoryBean {
/**
*
* @param cl
* @return
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public abstract CarService getCarService(Class cl) throws ClassNotFoundException,
IllegalAccessException, InstantiationException;
}
- 产品族工厂类 - 奥迪(
AudiFactoryBean
)
package com.dsj.demo.abstractfactory;
import com.dsj.demo.abstractfactory.service.AudiService;
public class AudiFactoryBean extends AbstractFactoryBean {
@Override
public AudiService getCarService(Class cl) throws IllegalAccessException, InstantiationException {
return (AudiService) cl.newInstance();
}
}
- 产品族工厂类 - 沃尔沃(
VolvoFactoryBean
)
package com.dsj.demo.abstractfactory;
import com.dsj.demo.abstractfactory.service.VolvoService;
/**
* @author Pengzf
*/
public class VolvoFactoryBean extends AbstractFactoryBean {
@Override
public VolvoService getCarService(Class cl) throws IllegalAccessException, InstantiationException {
return (VolvoService) cl.newInstance();
}
}
- 超级工厂类
package com.dsj.demo.abstractfactory;
public class FactoryProducer {
public static AbstractFactoryBean getFactory(Class cl) throws IllegalAccessException, InstantiationException {
System.out.println("创建工厂:" + cl.getName());
return (AbstractFactoryBean) cl.newInstance();
}
}
2.2.4、测试类
package com.dsj.demo.abstractfactory;
import com.dsj.demo.abstractfactory.service.*;
public class TestAbstractFactory {
public static void main(String[] args) throws IllegalAccessException, InstantiationException,
ClassNotFoundException {
AbstractFactoryBean audiFactoryBean = FactoryProducer.getFactory(AudiFactoryBean.class);
AudiService audiAFourServiceImpl = (AudiService) audiFactoryBean.getCarService(AudiA4ServiceImpl.class);
audiAFourServiceImpl.driver();
audiAFourServiceImpl.selfIntroduction();
AudiService audiA6ServiceImpl = (AudiService) audiFactoryBean.getCarService(AudiA6ServiceImpl.class);
audiA6ServiceImpl.driver();
audiA6ServiceImpl.selfIntroduction();
System.out.println("--------------------------------------");
AbstractFactoryBean volvoFactoryBean = FactoryProducer.getFactory(VolvoFactoryBean.class);
VolvoService volvoS90ServiceImpl = (VolvoService) volvoFactoryBean.getCarService(VolvoS90ServiceImpl.class);
volvoS90ServiceImpl.driver();
volvoS90ServiceImpl.afterSale();
VolvoService volVoXC60ServiceImpl = (VolvoService)volvoFactoryBean.getCarService(VolVoXC60ServiceImpl.class);
volVoXC60ServiceImpl.driver();
volVoXC60ServiceImpl.afterSale();
}
}
- 测试类执行结果如下:
创建工厂:com.dsj.demo.abstractfactory.AudiFactoryBean
驾驶奥迪A4 !!!
这里是奥迪A4 !!!
驾驶奥迪A6 !!!
这里是奥迪A6 !!!
--------------------------------------
创建工厂:com.dsj.demo.abstractfactory.VolvoFactoryBean
驾驶 沃尔沃 S90, 倍爽!!!
沃尔沃 S90, 为您提供尊贵售后服务!!!
驾驶沃尔沃 XC60,倍爽!
沃尔沃 XC60, 为您提供尊贵售后服务!!!
.