您的位置:首页 > 编程语言 > Java开发

java设计模式之工厂模式(简单工厂,工厂方法,抽象工厂)

2016-10-31 16:49 836 查看
什么是工厂模式呢,简单点来说:假如你想开车,没有工厂的话你就得自己手动去造一辆汽车,其实你只是想开车而已,没必要费时费力自己去造一

辆吧。如果自己造一辆的话,那么你就 “深入了具体的实现” 中了,但你的目的只是开车而已,不是造车,有了工厂模式,你就不用做这个了,想开车的

话去工厂取一辆就行了。。。

一:简单工厂模式

其包括以下3个角色:

1,抽象产品角色:它一般是具体产品继承的父类或者实现的接口

2,工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品

3,具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现 

抽象产品角色 :Mobile.java

package simplefactory;
/**
*工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
*抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
*具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
* 简单工厂不利于产生系列产品(不符合开闭原则)
*
*/

/**抽象产品角色,这里以生产手机为列*/
abstract  class Mobile {

}



具体产品角色:HuaWeiMobile.java

package simplefactory;
/**
* 具体产品角色
* @author Administrator
*
*/
public class HuaWeiMobile extends Mobile {
public HuaWeiMoblie(){
System.out.println("生产华为手机");
}
}

具体产品角色:XiaoMiMobile.java

package simplefactory;
/**
* 具体产品角色
* @author Administrator
*
*/
public class XiaoMiMobile extends Mobile {
public XiaoMiMobile(){
System.out.println("生产小米手机");
}
}


工厂类角色:SimpleFactory.java

package simplefactory;
/**
* 工厂类角色
* @author Administrator
* 缺点:每当增加一个手机系列时,就要修改下面的逻辑(不符合开闭原则,对扩展开放,对修改关闭)
* 这个缺点可以通过“工厂方法模式”解决
*/
public class SimpleFactory {

public Mobile createMobile(String type){
switch (type) {
case "huawei":
return new HuaWeiMobile();
case "xiaomi":
return new XiaoMiMobile();
default:
break;
}
return null;
}
}

测试 Client.java

package simplefactory;

import static org.junit.Assert.*;

import org.junit.Test;

public class ClientTest {
/**客户端对具体的生产过程是不可见的(无new操作符)*/
@Test
public void test1() {
SimpleFactory factoryBean=new SimpleFactory();
Mobile mobile1=factoryBean.createMobile("huawei");
Mobile mobile2=factoryBean.createMobile("xiaomi");
}

}

对于简单工厂角色,我们可以看出,每增加一个产品时,我们都要被迫检查工厂类,添加新的逻辑,对于这个缺陷,我们可以通过工厂方法模式来解决。

二:工厂方法模式

对于工厂方法模式,有以下几个角色:

   *抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 

  *具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 

  * 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 

  *具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。 

抽象工厂类:FactoryInterface.java

package factorymethod;
/**
* 工厂方法模式组成:
*抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
*具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
* 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
*具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
*
* 和简单工厂模式相比:对象工厂不再是一个类,而是由一系列的工厂子类,当增加一个新的系列时
* 只需增加一个工厂子类并实现 工厂的接口 FactoryMethodBeanInterface
* 缺点:每增加一个系列时,就得增加一个工厂子类。会造成大量的工厂子类。
* 这个缺点可以通过“抽象工厂模式”解决
*/
public interface FactoryInterface {
Mobile createMobile();
}

具体工厂角色:HuaweiMobileFactory.java

package factorymethod;

public class HuaweiMobileFactory implements FactoryInterface {

@Override
public Mobile createMobile() {

return new HuaWeiMoblie();
}

}

具体工厂角色:XiaoMiMobileFactory.java

package factorymethod;

public class XiaoMiMobileFactory implements FactoryInterface {

@Override
public Mobile createMobile() {
return new XiaoMiMobile();
}

}

抽象产品角色:Mobile.java

package factorymethod;
/**
*工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
*抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
*具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
* 简单工厂不利于产生系列产品(不符合开闭原则)
*
*/
/**抽象产品角色,这里以生产手机为列*/
abstract  class Mobile {

}

具体产品角色:HuaWeiMobile.java

package factorymethod;
/**
* 具体产品角色
* @author Administrator
*
*/
public class HuaWeiMoblie extends Mobile {
public HuaWeiMoblie(){
System.out.println("生产华为手机");
}
}

具体产品角色:XiaoMiMobile.java

package factorymethod;
/**
* 具体产品角色
* @author Administrator
*
*/
public class XiaoMiMobile extends Mobile {
public XiaoMiMobile(){
System.out.println("生产小米手机");
}
}
测试:ClientTest.java

package factorymethod;

import static org.junit.Assert.*;

import org.junit.Test;

public class ClientTest {
/**这里没有出现huawei和xiaomi 手机的创建细节*/
@Test
public void test() {
FactoryInterface factory1=new XiaoMiMobileFactory();
FactoryInterface factory2=new HuaweiMobileFactory();

factory1.createMobile();
factory2.createMobile();
}

}

由以上工厂方法模式可以看出,每增加一个手机系列时,都要被迫增加一个工厂子类,会造成大量的工厂子类。这个缺陷可以由抽象工厂模式来解决

三:抽象工厂

抽象工厂涉及到一个概念“产品族”,什么叫“产品族”呢?就是相互之间有关联的产品。假如说生产手机,需要cpu和内存 ram,如果按照 工厂方法的模式来写

就要再增加两个子类的工厂,生产cpu的工厂,和生产ram的工厂,那么问题来了:假如华为手机需要华为自己的cpu海思麒麟,小米手机需要高通的cpu,对于

ram也是一样,小米和华为都需要自己的。但是上面的cpu工厂和ram工厂,都只能生产同一种,怎么办?这时,你多么希望有一位脚踏七彩祥云,身穿金甲圣衣

的大英雄来拯救你于水火之中,这就是:抽象工厂模式。抽象工厂模式把华为手机,华为cpu,华为ram,看成一个产品族,把小米手机,小米cpu,小米ram看成

一个产品族。就这样,一个产品族,对应一个工厂。

抽象工厂也有几个角色:

*抽象工厂角色

*具体工厂角色

*抽象产品角色

*具体产品角色

抽象工厂角色:AbstractFactory.java

package abstractfactory;
/**
*
*抽象工厂角色
*
*解决了工厂方法的缺点(每增加一个产品时都要增加一个产品子类,这里要按照工厂方法模式来写的话就要增加cpu的工厂类,和ram
*的工厂类),由于cpu和ram可以看成是一个产品族(都是手机的零件)因此可以把cpu和ram放到一个工厂里边去生产。
*工厂类要实现工厂类的接口,产品类要实现产品类接口
*/
public interface AbstractFactory {
public Cpu createCpu();
public Ram createRam();
}

具体工厂角色:HuaWeiFactory.java

package abstractfactory;

public class HuaWeiFactory implements AbstractFactory {

@Override
public Cpu createCpu() {

return new HuaWeiCpu();
}

@Override
public Ram createRam() {
// TODO Auto-generated method stub
return new HuaWeiRam();
}

}

具体工厂角色:XiaoMiFactory.java

package abstractfactory;

public class XiaoMiFactory implements AbstractFactory {

@Override
public Cpu createCpu() {
return new XiaoMiCpu();
}

@Override
public Ram createRam() {
// TODO Auto-generated method stub
return new XiaoMiRam();
}

}

抽象产品角色:Cpu.java

package abstractfactory;
/**
*
* 抽象产品角色A
*
*/
public interface Cpu {
public void createCpu();
}

具体产品角色:HuaWeiCpu.java

package abstractfactory;

public class HuaWeiCpu implements Cpu {

@Override
public void createCpu() {
System.out.println("生产华为 cpu");
}

}

具体产品角色:XiaoMiCpu.java

package abstractfactory;

public class XiaoMiCpu implements Cpu {

@Override
public void createCpu() {
System.out.println("生产小米 cpu");
}

}

抽象产品角色:Ram.java

package abstractfactory;

public interface Ram {
public void createRam();
}


具体产品角色 HuaWeiRam.java

package abstractfactory;

public class HuaWeiRam implements Ram {

@Override
public void createRam() {
System.out.println("生产华为 ram");

}

}

具体产品角色:XiaoMiRam.java

package abstractfactory;

public class XiaoMiRam implements Ram {

@Override
public void createRam() {
System.out.println("生产小米 ram");

}

}

客户端测试 ClientTest.java

package abstractfactory;

import static org.junit.Assert.*;

import org.junit.Test;

public class ClientTest {

@Test
public void test() {
//华为
AbstractFactory factory1=new HuaWeiFactory();
factory1.createCpu().createCpu();
factory1.createRam().createRam();
System.out.println("-------->");
//小米
AbstractFactory factory2=new XiaoMiFactory();
factory2.createCpu().createCpu();
factory2.createRam().createRam();
}

}


 输出:

生产华为 cpu

生产华为 ram

-------->

生产小米 cpu

生产小米 ram
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: