常用设计模式之工厂方法模式、抽象工厂模式

设计模式有23种之多,但是我目前常用到可能就那么几种,之前一遍文章已经对单例模式做了详细的解释了,(java中单例模式的多种实现),所以今天这篇文章主要要对设计模式中常用的创造型模式中的另外两种模式 :工厂方法模式、抽象工厂模式进行浅谈一番。

1.在讲到两种模式之前,我们先来了解一下简单工厂模式(注:简单工厂不属于23中设计模式),简单工厂模式分为三种:简单普通工厂、多方法工厂、静态多方法工厂。

接下来将会用一个实例来仔细讲一下三种模式:该实例是使用一个设计者的接口,我们这边有两个他的实现(手游设计和动漫设计):

/**
 * 创建一个设计游戏和 设计动漫的共同接口 (普通简单工厂方法)
 * @author leo
 *
 */
public interface Designer {
	/**
	 * 设计方法
	 */
	public void design();
}
以及他的两个实现:

/**
 * 动漫设计实现类
 * @author leo
 *
 */
public class CartoonDesigner implements Designer{

	@Override
	public void design() {
		System.out.println("我们只设计动漫,不卖萌!");
		
	}
}
/**
 * 手机游戏设计类
 * @author leo
 *
 */
public class GameDesigner implements Designer{

	@Override
	public void design() {
		System.out.println("我们只设计游戏,不搞基!");
		
	}

}
①普通简单工厂模式的,我们要创建一个普通工厂类,

/**
 * 创建设计工厂类
 * @author leo
 *
 */
public class DesignFactory {
	/**
	 *  根据闯进来的字符串的类型不同,来创建不同的对象,
	 * @param type
	 * @return
	 */
	public  Designer product(String type){
		if(type.isEmpty()){
			return null;
		}else if("game".equals(type)){
			return new GameDesigner();
		}else if("cartoon".equals(type)){
			return new CartoonDesigner();
		}
		return null;
	}
}
②.对于普通简单工厂而言;万一用户在创建对象时,用户传递进来的参数有错就无法创建对象,这样风险过于大。所以就可以第二种诞生:根据不同方法创建不同对象的工厂类。

/**
 * 多个方法简单工厂类
 * @author leo
 *
 */
public class DesignMoreFactory {
		/**
		 * 创建卡通设计对象
		 * @return
		 */
		public Designer createCartoonDesigner(){
			return new CartoonDesigner();
		}
		/**
		 * 创建游戏设计对象
		 * @return
		 */
		public Designer createGameDesigner(){
			return new GameDesigner();
		}
}
③.对于第一二种而言,都是需要创建对象后,才能去调用的对象的方法,这样也很不实用。所以第三种方法就结合了第一二种工厂类的缺陷应运而生的;静态多种方法工厂类。

/**
 * 静态多方法工厂类
 * @author leo
 *
 */
public class DesignStaticFactory {
	/**
	 * 创建卡通设计对象
	 * @return
	 */
	public static Designer createCartoonDesigner(){
		return new CartoonDesigner();
	}
	/**
	 * 创建游戏设计对象
	 * @return
	 */
	public static Designer createGameDesigner(){
		return new GameDesigner();
	}
}

④,三种工厂类写完之后,测试下

<pre name="code" class="java">public class TestDesignerFactory {
	public static void main(String[] args) {
		DesignFactory factory = new DesignFactory();
		//工厂获取 对象
		Designer designer = factory.product("cartoon");
		designer.design();
		
		DesignMoreFactory factory2 = new DesignMoreFactory();
		//多方法工厂 
		Designer designer2 =factory2.createGameDesigner();
		designer2.design();
		//静态多方法工厂
		Designer designer3 =DesignStaticFactory.createCartoonDesigner();
		designer3.design();
	}
}

 

打印出来的:我们只设计动漫,不卖萌!
我们只设计游戏,不搞基!
我们只设计动漫,不卖萌!

总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

2.工厂方法模式:简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改, 这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到工厂方法模式(factoryMethod), 创建一个工厂接口(Provider)和创建多个工厂实现类。
①例子还是上面那个例子:然后我们创建工厂类的接口:

/**
 * 简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,
 * 这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到工厂方法模式(factoryMethod),
 * 创建一个工厂接口(Provider)和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,
 * 不需要修改之前的代码。
 * @author leo 
 *
 */
public interface Provider {
	public Designer produceDesigner();
}
然后创建实现的两个工厂类:

游戏设计工厂类:

/**
 * 实现工厂接口的 游戏设计工厂类
 * @author leo
 *
 */
public class GamesFactory implements Provider{

	@Override
	public Designer produceDesigner() {
		
		return new GameDesigner();
	}

}
动漫设计工厂类:

/**
 * 实现工厂接口的 动漫设计工厂类
 * @author leo
 *
 */
public class CartoonDesignerFactory implements Provider{
	/**
	 * 
	 */
	@Override
	public Designer produceDesigner() {
		return new CartoonDesigner();
	}

}

写个测试类测试下:
public class TestDesignerFactory {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		GamesFactory factory = new GamesFactory() ;
		Designer designer = factory.produceDesigner();
		designer.design();
		
	}

}
3. 抽象工厂模式

工厂方法模式和抽象工厂模式不好分清楚,他们的区别如下:

<span style="font-size:10px;">工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。   
    
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。</span>
<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px;"><span style="font-size:10px;">工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。</span></span>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值