工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
工厂模式的形态
工厂模式主要用一下几种形态:
1:简单工厂(Simple Factory)。
2:工厂方法(Factory Method)。
3:抽象工厂(Abstract Factory)。
一、简单工厂
有一天妹子说要去旅游
我说:去哪里
妹子说:我也不知道,但必须要有好吃的,你推荐下
我想了会了,这样吧,我给你写个App程序,可以通过它去重庆,四川,山东等地
就这样我就写了一个简单工厂
先写一个枚举类,供选择
package com.Factory;
public enum EnumCity {
CHONGQING,
SICHUAN,
SHANDONG
}
一个抽象的城市类,并写了个抽象方法,用于子类实现
package com.Factory;
public abstract class BaseCity {
public abstract void specialFood();
public void doEat(){
System.out.println("带她吃东西去!!! 买买买");
}
}
哈哈,第一个城市,重庆
听说重庆妹子腿长且火辣,吃着火锅。。。
package com.Factory;
public class Chongqing extends BaseCity{
@Override
public void specialFood() {
System.out.println("长腿妹子,爱吃火锅");
}
}
山东,想到青岛海边的比基尼,吃着大虾,论个买的那种
package com.Factory;
public class Shandong extends BaseCity{
@Override
public void specialFood() {
System.out.println("比基尼美女,爱吃大虾");
}
}
好了城市都写好,这样实现一个简单工厂给妹子,
妹子你自己想去哪,只要选地址就行,特色小吃什么的都一目了然
package com.Factory;
public class TripFactory {
public BaseCity createCity(EnumCity city){
BaseCity baseTrip = null;
switch (city) {
case CHONGQIN:
baseTrip = new Chongqing();
case SHANDONG:
baseTrip = new Shandong();
default:
baseTrip = new Shandong();
}
return baseTrip;
}
}
妹子正在使用,
于是妹子就选了一个重庆
package com.Factory;
public class TripMain {
public static void main(String[] args) {
BaseCity t2 = new TripFactory().createCity(EnumCity.Chongqing);
t2.specialFood();
t2.doEat();
}
}
控制台输出:
“比基尼美女,爱吃大虾
带她吃东西去!!! 买买买”
“你真棒,么么哒!”妹子很高兴的亲了我一口
于是我们开心的准备着去重庆
工厂模式三中状态中结构最为简单的。主要有一个方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。
二、工厂方法
第二天,妹子跟我讲,要不我们去西藏吧,
尼玛,有种想屎的感觉
这样的节奏,昨天还是重庆,今天又是西藏,鬼知道明天是什么
每次我得枚举里新增一个城市,TripFactory.createCity() 又要破坏了,关键是后面加的地方一多,就难维护了,破坏了面向对象设计原则,开闭原则。
怎么办?
脑子一机灵,我于是就这么写了
设计一个接口ITripFactory类,提供createCity();接口方法
package com.Factory;
public interface ITripFactory {
public BaseCity createCity();
}
并实现一个西藏城市工厂类,
package com.Factory;
public class XizangCityFactory implements ITripFactory{
@Override
public BaseCity createCity( ) {
return new Xizang();
}
}
分别重新实现重庆、山东工厂类
package com.Factory;
public class ChongqingCityFactory implements ITripFactory{
@Override
public BaseCity createCity( ) {
return new Chongqing();
}
}
package com.Factory;
public class ShandongCityFactory implements ITripFactory{
@Override
public BaseCity createCity( ) {
return new Shandong();
}
}
哈哈,终于写完了
这下好了,你去西藏是吧,new一个西藏Factory就可以了,然后心里想着你明天要去三亚,我也就直接写一个三亚Factory就好了,不用在破坏我的原有的代码了。
package com.Factory;
public class TripMain {
public static void main(String[] args) {
/* BaseCity t2 = new TripFactory().createCity(EnumCity.CHONGQING);
t2.specialFood();
t2.doEat();*/
ITripFactory TripFactory = new XizangCityFactory();
BaseCity city = TripFactory.createCity();
city.specialFood();
city.doEat();
}
}
于是我和妹子很开心的去了西藏
工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。
三、抽象工厂
喝马奶酒,吃牦牛肉
带她吃东西去!!! 买买买
可是到了晚上了,尼玛,忘了住宿了,住哪里了
妹子说那怎么办吧
好吧,我又得修改下了,
于是和之前城市一样,我建了一个旅馆的抽象类
package com.Factory;
public abstract class BaseHotel {
public abstract void Price();
public void doSleep(){
System.out.println("和她好好睡一觉");
}
}
并提供了一下几种类型:民宿、酒店型的
民宿:
package com.Factory;
public class MingsuHotel extends BaseHotel {
@Override
public void Price() {
System.out.println("1000元一晚");
}
}
酒店:
package com.Factory;
public class JiuDianHotel extends BaseHotel {
@Override
public void Price() {
System.out.println("800元一晚");
}
}
并同样通过ITripFactory 住宿的生产接口
package com.Factory;
public interface ITripFactory {
public BaseCity createCity();
public BaseHotel createHotel();
}
每一个城市工厂分别实现了,具体城市和住宿类型实力的生产
西藏
package com.Factory;
public class XizangCityFactory implements ITripFactory{
@Override
public BaseCity createCity( ) {
return new Xizang();
}
@Override
public BaseHotel createHotel() {
// TODO Auto-generated method stub
return new MingsuHotel();
}
}
山东
package com.Factory;
public class ShandongCityFactory implements ITripFactory{
@Override
public BaseCity createCity( ) {
return new Shandong();
}
@Override
public BaseHotel createHotel() {
// TODO Auto-generated method stub
return new JiuDianHotel();
}
}
青岛
package com.Factory;
public class ChongqingCityFactory implements ITripFactory{
@Override
public BaseCity createCity( ) {
return new Chongqing();
}
@Override
public BaseHotel createHotel() {
// TODO Auto-generated method stub
return new MingsuHotel();
}
}
哈哈,终于ok了,妹子,可以安心的睡个好觉了
package com.Factory;
public class TripMain {
public static void main(String[] args) {
/* BaseCity t2 = new TripFactory().createCity(EnumCity.CHONGQING);
t2.specialFood();
t2.doEat();*/
ITripFactory TripFactory = new XizangCityFactory();
BaseCity city = TripFactory.createCity();
city.specialFood();
city.doEat();
BaseHotel hotel = TripFactory.createHotel();
hotel.Price();
hotel.doSleep();
}
}
于是:
喝马奶酒,吃牦牛肉
带她吃东西去!!! 买买买
1000元一晚
和她好好睡一觉
抽象工厂:意的意图在于创建一系列互相关联或互相依赖的对象。<<Java设计模式>>
我自己觉得抽象工厂是在工厂方法的基础上引进了分类管理的概念....
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点
我们的抽象工厂就完成了。有上面可以看出,在运用上我觉得工厂方法和抽象工厂,都有自己的应用场景,并没有什么优劣之分,但在应用抽象工厂之前,要先对创建的对象进行系统的分类,这点很重要,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路.
关于工厂模式另外两种实现方式:
1. xml方式
https://my.oschina.net/u/923324/blog/832612
2. annotation方式
https://my.oschina.net/u/923324/blog/832269