工厂模式可以将对象的使用和创建分离
创建对象的设计模式
一般使用的工厂模式共有三种
这些概念等会儿可以通过代码清晰展示出来
现在有两种牌子的产品,其中海尔可以生产海尔牌的电视机、海尔牌的空调,TCL可以生产TCL牌电视机、TCL牌空调。现在需要生产其中一个产品。
对于这个问题,可以选择任一工厂模式。
三种模式对比如下
interface Product {
void play();
}
class HairTv implements Product {
@Override
public void play() {
System.out.println("HairTV播放中~");
}
}
class TCLTv implements Product {
@Override
public void play() {
System.out.println("HairTV播放中~");
}
}
class HairAirConditioner implements Product{
@Override
public void play() {
System.out.println("HairAirConditioner调温中~");
}
}
class TCLAirConditioner implements Product{
@Override
public void play() {
System.out.println("TCLAirConditioner调温中~");
}
}
class Factory {
public static Product produceProduct(String brand) {
if (brand.equalsIgnoreCase("HairTv")) {
System.out.println("生产海尔电视");
return new HairTv();
} else if (brand.equalsIgnoreCase("TCLTv")) {
System.out.println("生产TCL电视");
return new TCLTv();
}else if(brand.equalsIgnoreCase("HairAirConditioner")) {
System.out.println("生产海尔空调");
return new HairAirConditioner();
} else if(brand.equalsIgnoreCase("TCLAirConditioner")){
System.out.println("生产TCL空调");
return new TCLAirConditioner();
} else {
System.out.println("不支持生产该产品~");
}
return null;
}
}
public class SimpleFactoryDemo {
public static void main(String[] args) {
//根据参数的不同返回不同的实例
Product hairTv = Factory.produceProduct("HairTv");
if (hairTv != null) {
hairTv.play();
}
System.out.println("--------------------");
Product tclAirConditioner = Factory.produceProduct("TCLAirConditioner");
if (tclAirConditioner != null) {
tclAirConditioner.play();
}
System.out.println("--------------------");
Product product = Factory.produceProduct("xxx");
if (product != null) {
product.play();
}
}
}
//电视
public interface TV {
void play();
}
//空调
public interface AirConditioner {
void play();
}
//电视工厂
public interface AirConditionerFactory {
AirConditioner produceAirConditioner();
}
//空调工厂
public interface TVFactory {
TV productTV();
}
海尔产品
//电视
public class HairTV implements TV {
@Override
public void play() {
System.out.println("海尔电视播放中...");
}
}
//电视具体工厂
public class HairTVFactory implements TVFactory {
@Override
public TV productTV() {
System.out.println("生产海尔电视机");
return new HairTV();
}
}
//空调
public class HairAirConditioner implements AirConditioner{
@Override
public void play() {
System.out.println("海尔空调调温中~");
}
}
//空调具体工厂
public class HairAirConditionerFactory implements AirConditionerFactory{
@Override
public AirConditioner produceAirConditioner() {
System.out.println("生产海尔空调");
return new HairAirConditioner();
}
}
TCL产品
//电视
public class TCLTV implements TV {
@Override
public void play() {
System.out.println("TCL电视播放中...");
}
}
//电视具体工厂
public class TCLTVFactory implements TVFactory {
@Override
public TV productTV() {
System.out.println("生产TCL电视");
return new TCLTV();
}
}
//空调
public class TCLAirConditioner implements AirConditioner{
@Override
public void play() {
System.out.println("TCL空调调温中~");
}
}
//空调具体工厂
public class TCLAirConditionerFactory implements AirConditionerFactory{
@Override
public AirConditioner produceAirConditioner() {
System.out.println("生产TCL空调");
return new TCLAirConditioner();
}
}
demo展示
public class FactoryMethodDemo {
public static void main(String[] args) {
TV tv;
AirConditioner airConditioner;
TVFactory tvFactory = new HairTVFactory();
AirConditionerFactory airConditionerFactory = new TCLAirConditionerFactory();
tv = tvFactory.productTV();
if (tv != null) {
tv.play();
}
System.out.println("-------------------");
airConditioner = airConditionerFactory.produceAirConditioner();
if (airConditioner != null) {
airConditioner.play();
}
}
}
//电视
public interface Television {
void play();
}
//空调
public interface AirConditioner {
void changeTemperature();
}
//工厂
public interface EFactory {
Television produceTelevision();
AirConditioner produceAirConditioner();
}
海尔产品
public class HairFactory implements EFactory{
@Override
public Television produceTelevision() {
System.out.println("生产海尔电视");
return new HairTelevision();
}
@Override
public AirConditioner produceAirConditioner() {
System.out.println("生产海尔空调");
return new HairAirConditioner();
}
}
public class HairTelevision implements Television{
@Override
public void play() {
System.out.println("海尔电视播放中...");
}
}
public class HairAirConditioner implements AirConditioner {
@Override
public void changeTemperature() {
System.out.println("海尔空调正在调控温度...");
}
}
TCL产品
public class TCLFactory implements EFactory{
@Override
public Television produceTelevision() {
System.out.println("生产TCL电视");
return new TCLTelevision();
}
@Override
public AirConditioner produceAirConditioner() {
System.out.println("生产TCL空调");
return new TCLAirConditioner();
}
}
public class TCLTelevision implements Television {
@Override
public void play() {
System.out.println("TCL电视播放中...");
}
}
public class TCLAirConditioner implements AirConditioner {
@Override
public void changeTemperature() {
System.out.println("TCL空调正在调控温度中...");
}
}
demo展示
public class AbstractFactoryDemo {
public static void main(String[] args) {
EFactory eFactory;
Television television;
AirConditioner airConditioner;
eFactory = new TCLFactory();
television = eFactory.produceTelevision();
airConditioner = eFactory.produceAirConditioner();
television.play();
airConditioner.changeTemperature();
System.out.println("-----------");
eFactory = new HairFactory();
television = eFactory.produceTelevision();
airConditioner = eFactory.produceAirConditioner();
television.play();
airConditioner.changeTemperature();
}
}
可以看出,简单工厂使用简单,工厂方法如果一家公司(如海尔)生产多个产品类就会爆炸式增长,抽象工厂适用于多个产品的创建。
1)简单工厂
优点:实现简单、使用简单
缺点:不符合开闭原则,增加新类或删除原有的产品类需要改动源代码
2)工厂方法
优点:增加类时无需修改源代码,符合开闭原则
缺点:添加新厂品时,还要添加相应的工厂类,实现复杂。
3)抽象工厂
优点:增加新的产品族很方便,无须修改已有系统,符合“开闭原则”
缺点:增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
比如工厂方法模式的xml配置文件使用
1)methodFactory.xml
表示生产的是Hair电视,想生产其它的,只要将配置文件中的类名修改了即可
<config>
<className>HairTVFactoryclassName>
config>
2)读取xml文件的类:XMLUtil.java文件
public class XMLUtil {
public static Object getBean() {
try {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
//配置文件methodFactory.xml的完整路径
String path = "D:/java代码/twigs/src/year2020/designpattern/greational/factorymethod/methodFactory.xml";
Document doc = builder.parse(new File(path));
NodeList n1 = doc.getElementsByTagName("className");
Node classNode = n1.item(0).getFirstChild();
//cName返回的是工厂类的名字,如HairTVFactory、TCLAirConditioner,只需要修改methodFactory.xml文件即可
String cName = classNode.getNodeValue();
//工厂类的全限定名
String className = "year2020.designpattern.greational.factorymethod." + cName;
Class<?> c = Class.forName(className);
return c.newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
3)代码展示
public class FactoryMethodDemo {
public static void main(String[] args) {
TV tv;
TVFactory tvFactory;
tvFactory = (TVFactory) XMLUtil.getBean();
if (tvFactory != null) {
tv = tvFactory.productTV();
tv.play();
}
}
}
5)温馨提示
对象创建跟Spring搭配食用,效果更加哦~