文章目录
- 介绍
- 开始
- 架构图(以穿搭举例)
- 样例一(html关于列表和表格的应用)
- 定义抽象工厂(html)
- 定义抽象工厂需要制作抽象产物(托盘)
- 定义具体工厂(列表、表格)
- 定义工厂生产零件(托盘)
- 样例二(衣服关于春季和夏季的穿搭)
- 定义抽象工厂(穿搭)
- 定义抽象工厂需要制作抽象产物(上衣、下装)
- 定义具体工厂(春季、夏季)
- 定义工厂生产零件(上衣、下装)
- 样例三(工厂关于小米和华为的生产)
- 定义抽象工厂(制造工厂)
- 定义抽象工厂需要制作抽象产物(手机、路由器)
- 定义具体工厂(小米工厂、华为工厂)
- 定义工厂生产零件(手机、路由器)
- 测试样例
- 总结
介绍
在抽象工厂模式中,不仅有抽象工厂
,还有抽象零件
,抽象产品
。其中抽象工厂主要的工作职责将抽象零件
组装成抽象产品
。
第一大段,这么多抽象,抽象
的含义到底是啥?它指:不考虑具体怎样实现,而是仅关注接口(API)的状态
。
综上所诉:在 Abstract Factory 模式中将会出现抽象工厂,它会将抽象零件组装为抽象产品。也就是说,
我们并不关心零件的具体实现,而是只关心接口(API)。我们仅使用该接口(API)将零件组装成为产品
。
开始
架构图(以穿搭举例)
抽象工厂作为主接口,不具备任何含义,只记录有上衣和下装。在季节工厂里面(也可以叫做季节产品),他们生产了一系列相应季节的上衣和下装。但对上衣和下装同时是比较抽象的,需要对上衣和下装(也可以叫做零件)赋予真正的含义,如:在上衣中有短袖、衬衫;在下装中,有牛仔裤和短裤。
通过具体的零件,才有了品牌打出了季节产品,最后统称抽象为上衣、下装。
样例一(html关于列表和表格的应用)
定义抽象工厂(html)
public interface HtmlFactory {
/**
* 创建一个抽象托盘
*
* @return
*/
TrayService createTray();
}
定义抽象工厂需要制作抽象产物(托盘)
为什么要单独定义一个item接口,是因为对于html代码,我们的产物有<a>标签
,<b>标签
等,最后都是需要一个html的模板所以,定义了一个item接口,让后续的抽象产物继承。
public interface Item {
/**
* 生成 html 代码
*/
String makeHTML();
}
public interface TrayService extends Item {
}
定义具体工厂(列表、表格)
@Service
@Slf4j
public class ListHtmlFactory implements HtmlFactory {
@Resource(name = "listTrayServiceImpl")
private TrayService trayService;
@Override
public TrayService createTray() {
return trayService;
}
}
@Service
@Slf4j
public class TableHtmlFactory implements HtmlFactory {
@Resource(name = "tableTrayServiceImpl")
private TrayService trayService;
@Override
public TrayService createTray() {
return trayService;
}
}
定义工厂生产零件(托盘)
@Service
@Slf4j
public class ListTrayServiceImpl implements TrayService {
@Override
public String makeHTML() {
return "<ul>\n" +
" <li>咖啡</li>\n" +
" <li>茶</li>\n" +
" <li>牛奶</li>\n" +
"</ul>";
}
}
@Service
@Slf4j
public class TableTrayServiceImpl implements TrayService {
@Override
public String makeHTML() {
return "<table>\n" +
" <tr>\n" +
" <th>月份</th>\n" +
" <th>储蓄</th>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>一月</td>\n" +
" <td>¥3400</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>二月</td>\n" +
" <td>¥4500</td>\n" +
" </tr>\n" +
"</table>";
}
}
样例二(衣服关于春季和夏季的穿搭)
定义抽象工厂(穿搭)
public interface WearFactory {
/**
* 创建一个 衣服
*
* @return
*/
ClothesService createClothe();
/**
* 创建一个 裤子
*
* @return
*/
TrousersService createTrouser();
}
定义抽象工厂需要制作抽象产物(上衣、下装)
public interface ClothesService {
/**
* 短袖
*/
void shortSleeve();
/**
* 衬衫
*/
void shirt();
}
public interface TrousersService {
/**
* 牛仔裤
*/
void jeans();
/**
* 短裤
*/
void shorts();
}
定义具体工厂(春季、夏季)
@Service
@Slf4j
public class SpringWearFactory implements WearFactory {
@Resource(name = "springClothesServiceImpl")
private ClothesService clothesService;
@Resource(name = "springTrousersServiceImpl")
private TrousersService trousersService;
@Override
public ClothesService createClothe() {
return clothesService;
}
@Override
public TrousersService createTrouser() {
return trousersService;
}
}
@Service
@Slf4j
public class SummerWearFactory implements WearFactory {
@Resource(name = "summerClothesServiceImpl")
private ClothesService clothesService;
@Resource(name = "summerTrousersServiceImpl")
private TrousersService trousersService;
@Override
public ClothesService createClothe() {
return clothesService;
}
@Override
public TrousersService createTrouser() {
return trousersService;
}
}
定义工厂生产零件(上衣、下装)
@Service
@Slf4j
public class SpringClothesServiceImpl implements ClothesService {
@Override
public void shortSleeve() {
System.out.println("制作了---春季款---短袖");
}
@Override
public void shirt() {
System.out.println("制作了---春季款---衬衫");
}
}
@Service
@Slf4j
public class SpringTrousersServiceImpl implements TrousersService {
@Override
public void jeans() {
System.out.println("制作了---春季款---牛仔裤");
}
@Override
public void shorts() {
System.out.println("制作了---春季款---短裤");
}
}
@Service
@Slf4j
public class SummerClothesServiceImpl implements ClothesService {
@Override
public void shortSleeve() {
System.out.println("制作了---夏季款---短袖");
}
@Override
public void shirt() {
System.out.println("制作了---夏季款---衬衫");
}
}
@Service
@Slf4j
public class SummerTrousersServiceImpl implements TrousersService {
@Override
public void jeans() {
System.out.println("制作了---夏季款---牛仔裤");
}
@Override
public void shorts() {
System.out.println("制作了---夏季款---短裤");
}
}
样例三(工厂关于小米和华为的生产)
定义抽象工厂(制造工厂)
public interface ProductFactory {
/**
* 创建一个抽象手机
*
* @return
*/
PhoneService createPhone();
/**
* 创建一个抽象路由器
*
* @return
*/
RouterService createRouter();
}
定义抽象工厂需要制作抽象产物(手机、路由器)
public interface PhoneService {
/**
* 开机
*/
void power();
/**
* 关机
*/
void shutdown();
/**
* 打电话
*/
void call();
}
public interface RouterService {
/**
* 开机
*/
void power();
/**
* 关机
*/
void shutdown();
/**
* 路由器 设置
*/
void setting();
}
定义具体工厂(小米工厂、华为工厂)
@Service
@Slf4j
public class XiaomiProductFactory implements ProductFactory {
@Resource(name = "xiaomiPhoneServiceImpl")
private PhoneService phoneService;
@Resource(name = "xiaomiRouterServiceImpl")
private RouterService routerService;
@Override
public PhoneService createPhone() {
return phoneService;
}
@Override
public RouterService createRouter() {
return routerService;
}
}
@Service
@Slf4j
public class HuaweiProductFactory implements ProductFactory {
@Resource(name = "huaweiPhoneServiceImpl")
private PhoneService phoneService;
@Resource(name = "huaweiRouterServiceImpl")
private RouterService routerService;
@Override
public PhoneService createPhone() {
return phoneService;
}
@Override
public RouterService createRouter() {
return routerService;
}
}
定义工厂生产零件(手机、路由器)
@Service
@Slf4j
public class XiaomiPhoneServiceImpl implements PhoneService {
@Override
public void power() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
@Override
public void call() {
System.out.println("小米手机打电话");
}
}
@Service
@Slf4j
public class XiaomiRouterServiceImpl implements RouterService {
@Override
public void power() {
System.out.println("小米路由器开机");
}
@Override
public void shutdown() {
System.out.println("小米路由器关机");
}
@Override
public void setting() {
System.out.println("小米路由器开始设置wifi");
}
}
@Service
@Slf4j
public class HuaweiPhoneServiceImpl implements PhoneService {
@Override
public void power() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
@Override
public void call() {
System.out.println("华为手机打电话");
}
}
@Service
@Slf4j
public class HuaweiRouterServiceImpl implements RouterService {
@Override
public void power() {
System.out.println("华为路由器开机");
}
@Override
public void shutdown() {
System.out.println("华为路由器关机");
}
@Override
public void setting() {
System.out.println("华为路由器开始设置wifi");
}
}
测试样例
@Slf4j
@SpringBootTest(classes = AbstractFactoryApplication.class)
public class TestAbstractFactory {
@Resource
private Map<String, HtmlFactory> htmlFactoryMap;
@Resource
private Map<String, ProductFactory> productFactoryMap;
@Resource
private Map<String, WearFactory> wearFactoryMap;
@Test
public void testPage() {
for (Map.Entry<String, HtmlFactory> map : htmlFactoryMap.entrySet()) {
log.info("这是 : {} 工厂", map.getKey());
System.out.println(map.getValue().createTray().makeHTML());
}
}
@Test
public void testProduct() {
for (Map.Entry<String, ProductFactory> map : productFactoryMap.entrySet()) {
log.info("这是 : {} 工厂", map.getKey());
ProductFactory value = map.getValue();
PhoneService phone = value.createPhone();
RouterService router = value.createRouter();
log.info("phone begin");
phone.power();phone.call();phone.shutdown();
log.info("router begin");
router.power();router.setting();router.shutdown();
}
}
@Test
public void testWear() {
for (Map.Entry<String, WearFactory> map : wearFactoryMap.entrySet()) {
log.info("这是 : {} 工厂", map.getKey());
WearFactory value = map.getValue();
ClothesService clothe = value.createClothe();
TrousersService trouser = value.createTrouser();
log.info("clothe begin");
clothe.shortSleeve();clothe.shirt();
log.info("trouser begin");
trouser.jeans();trouser.shorts();
}
}
}
总结
如果现在要建立一个工厂是非常容易能创建的,但如果要增加新的零件每个工厂都要实现零件制作方法,因此非常麻烦。
一句话表述:易于增加具体的工厂,难以增加新的零件