小编最近又复习了一遍Java版的工厂模式模式,分享读者们一下,欢迎阅读啊!
【设计模式一 工厂模式Factory】
在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢?
解决方案:建立一个工厂来创建对象。
【工厂三姐妹定义】
1、简单工厂模式:由一个工厂类根据传入的参量决定创建哪一种产品类的实现。
2、工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
3、抽象工厂模式:创建一系列相关的对象的接口,而无需制定他们具体的类。
这三种模式是从上到下逐步抽象,并且更具有一般性。GoF将工厂分为两类:工厂方法模式与抽象工厂模式,简单工厂看为工厂方法模式的一种特例。
【分析】 我们已生产电视机为例
1、简单工厂模式
客户要一个电视机,则就去创建一个电视机工厂,把创建电视的操作一些都放到了工厂里面去,客户直接使用工厂的创建方法,传入电视机的型号就可以了。
电视接口:
package com.bjpowernode.pattern;
public interface TV {
public void turnOn();
public void turnOff();
}
海尔电视类:
package com.bjpowernode.pattern;
public class HaiErTV implements TV {
public void turnOff() {
System.out.println("HaiErTV.turnOff()");
}
public void turnOn() {
System.out.println("HaiErTV.turnOn()");
}
}
长虹电视类:
package com.bjpowernode.pattern;
public class ChangHongTV implements TV {
public void turnOff() {
System.out.println("ChangHongTV.turnOff()");
}
public void turnOn() {
System.out.println("ChangHongTV.turnOn()");
}
}
电视工厂类:
package com.bjpowernode.pattern;
//采用简单工厂将产品创建细节隐藏
//这样产品发生改变不会对客户造成影响
public class TVFactory {
public static final String HAI_ER = "海尔";
public static final String CHANG_HONG = "长虹";
public static TV createTV(String type) {
TV tv = null;
if (HAI_ER.equals(type)) {
//构造海尔的电视
//.....
//......
//......
//增加一个步骤
tv = new HaiErTV();
}else if (CHANG_HONG.equals(type)) {
//构造长虹的电视
//.....
//......
//......
//......
//.......
tv = new ChangHongTV();
}else {
throw new RuntimeException("无法生产!");
}
return tv;
}
}
客户端:
package com.bjpowernode.pattern;
public class Client {
public static void main(String[] args) {
//取得海尔的电视
//TV tv = TVFactory.createTV(TVFactory.HAI_ER);
//取得长虹的电视
TV tv = TVFactory.createTV(TVFactory.CHANG_HONG);
tv.turnOn();
}
}
现在需求改了:客户想要新增一种新的电视品牌,都要在工厂类中增加相应的创建业务逻辑,也就是要新增else if ,这显然违背了开闭原则。简单来说就是只有一个工厂类对应这些产品,加入新的产品会累坏工厂的。所以相应的出现了工厂方法模式。工厂类定义成了接口,而每新增的电视机类型,就增加该电视机类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。
2、工厂方法模式
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“电视工厂类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!
电视接口:
package com.bjpowernode.pattern;
public interface TV {
public void turnOn();
public void turnOff();
}
海尔电视类:
package com.bjpowernode.pattern;
public class HaiErTV implements TV {
public void turnOff() {
System.out.println("HaiErTV.turnOff()");
}
public void turnOn() {
System.out.println("HaiErTV.turnOn()");
}
}
长虹电视类:
package com.bjpowernode.pattern;
public class ChangHongTV implements TV {
public void turnOff() {
System.out.println("ChangHongTV.turnOff()");
}
public void turnOn() {
System.out.println("ChangHongTV.turnOn()");
}
}
电视工厂接口:
package com.bjpowernode.pattern;
public interface TVFactory {
public TV createTV();
}
海尔工厂类:
package com.bjpowernode.pattern;
public class TVFactory4HaiEr implements TVFactory {
public TV createTV() {
//构造海尔的电视
//.....
//......
//......
//增加一个步骤
return new HaiErTV();
}
}
长虹工厂类:
package com.bjpowernode.pattern;
public class TVFactory4ChangHong implements TVFactory {
public TV createTV() {
//构造长虹的电视
//.....
//......
//......
//......
//.......
return new ChangHongTV();
}
}
客户端:
package com.bjpowernode.pattern;
public class Client {
public static void main(String[] args) {
//取得海尔的工厂
//TVFactory factory = new TVFactory4HaiEr();
//取得海信的工厂
//TVFactory factory = new TVFactory4HaiXin();
//取得长虹的工厂
TVFactory factory = new TVFactory4ChangHong();
TV tv = factory.createTV();
tv.turnOn();
}
}
工厂方法模式的优点:支持OCP原则(开闭原则),面向对象接口,解耦合
使用场景:隐藏产品创建细节,单一系列产品创建
随着客户的要求越来越高,电视机需要配置笔记本电脑。于是这个工厂开始生产电视机和笔记本电脑。这时候工厂有二个系列的产品:电视机和笔记本电脑.电视机必须使用对应的笔记本电脑才能使用.这时候分别使用一个电视机工厂和一个笔记本工厂都不能满足我们的需求,我们必须确认电视机跟笔记本的对应关系。因此把电视机工厂跟笔记本工厂联系在一起。因此出现了抽象工厂模式。
3、抽象工厂
给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件:
1)系统中有多个产品族,而系统一次只可能消费其中一族产品。
2)同属于同一个产品族的产品以其使用。
电视接口:
package com.bjpowernode.pattern;
public interface ProductTV {
public void resolution();
}
电视A类:
package com.bjpowernode.pattern;
public class TVA implements ProductTV {
public void resolution() {
System.out.println("电视A");
}
}
电视B类:
package com.bjpowernode.pattern;
public class TVB implements ProductTV {
public void resolution() {
System.out.println("电视B");
}
}
笔记本接口:
package com.bjpowernode.pattern;
public interface ProductComputer {
public void keyBoard();
}
笔记本A类:
package com.bjpowernode.pattern;
public class ComputerA implements ProductComputer {
public void keyBoard() {
System.out.println("笔记本A");
}
}
笔记本B类:
package com.bjpowernode.pattern;
public class ComputerB implements ProductComputer {
public void keyBoard() {
System.out.println("笔记本B");
}
}
工厂接口:
package com.bjpowernode.pattern;
public interface Factory {
public ProductComputer productComputer();
public ProductTV productTV();
}
工厂A接口:
package com.bjpowernode.pattern;
public class FactoryA implements Factory {
public ProductComputer productComputer() {
return new ComputerA();
}
public ProductTV productTV() {
return new TVA();
}
}
工厂B接口:
package com.bjpowernode.pattern;
public class FactoryB implements Factory {
public ProductComputer productComputer() {
return new ComputerB();
}
public ProductTV productTV() {
return new TVB();
}
}
客户端:
package com.bjpowernode.pattern;
public class Client {
public static void main(String[] args) {
//取得A工厂
Factory factory = new FactoryA();
//取得A工厂中的笔记本工厂
ProductComputer computerA=factory.productComputer();
computerA.keyBoard();
}
}
优点:对产品的增加支持OCP原则
缺点:对产品系列的增加不支持OPC原则
使用场景:对多个系列产品的创建
好了今天的博客小编就写到这里了,欢迎小伙伴们的留言。。。