软件设计模式(Software Design Pattern),又称 设计模式,是一套被重复应用、少数人通晓的、通过分类编目标、代码设计教训的总结
它形容了在软件设计过程中的一些一直反复产生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计教训的总结,具备肯定的普遍性,能够重复应用。
其目标是为了进步代码的可重用性、代码的可读性和代码的可靠性。
在上一章节工厂模式 (上)- 工厂办法模式中咱们具体去学习了工厂办法模式,然而咱们晓得工厂办法模式思考到的是一类产品的生产,然而在现实生活中许多工厂是综合型的工厂,能生产多等级(品种)的产品,如农场里既养动物又种动物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件业余又有生物业余等,在这种状况下咱们再应用工厂办法模式进行设计便不再适合,而就须要另一种工厂模式 - 形象工厂模式。
形象工厂模式次要用于解决多种类型产品的生产
那么什么是形象工厂模式呢?
形象工厂(AbstractFactory)模式的定义 :是一种为拜访类提供一个创立一组相干或相互依赖对象的接口,且拜访类毋庸指定所要产品的具体类就能失去同族的不同等级的产品的模式构造,这里便呈现了两个概念: 同族 和同等级。
咱们用电器生产工厂示意如下:
图 -1 电器工厂的产品等级与产品族
依据图咱们比照之前的工厂办法模式能够得悉,形象工厂模式是工厂办法模式的降级版本,工厂办法模式只生产一个等级的产品,而形象工厂模式可生产多个等级的产品
而应用形象工厂模式须要满足以下条件:
- 零碎中有多个产品族,每个具体工厂创立同一族但属于不同等级构造的产品。
- 零碎一次只可能生产其中某一族产品,即同族的产品一起应用。
而作为工厂办法模式的升级版,形象工厂模式的组成 同工厂办法模式一样,也是由 形象工厂、具体工厂、形象产品和具体产品 等 4 个因素形成,但形象工厂中办法个数不同,形象产品的个数也不同。
- 形象工厂(Abstract Factory):提供了创立产品的接口,它蕴含多个创立产品的办法 newProduct(),能够创立多个不同等级的产品。
- 具体工厂(Concrete Factory):次要是实现形象工厂中的多个形象办法,实现具体产品的创立。
- 形象产品(Product):定义了产品的标准,形容了产品的次要个性和性能,形象工厂模式有多个形象产品。
- 具体产品(ConcreteProduct):实现了形象产品角色所定义的接口,由具体工厂来创立,它同具体工厂之间是多对一的关系。
绘制结构图如下:
代码如何实现呢?
比方咱们当初有一个需要:有两个农场,第一个农场用于养牛和种菜,第二个农场用于养马和种水果。通过剖析咱们生产的产品为不同的类型,工厂办法模式只能实现同一系列产品的生产,而如果须要生产不同系列的产品,则须要咱们应用形象工厂模式
代码如下:
/**
* @author hz
* @version 1.0
*/
public class FarmTest {public static void main(String[] args) {
try {
Farm f;
Animal a;
Plant p;
// 读取相应的配置信息,用于生产工厂
f = (Farm) ReadXML.getObject();
a = f.newAnimal();
p = f.newPlant();
a.show();
p.show();} catch (Exception e) {System.out.println(e.getMessage());
}
}
}
// 形象产品:动物类
interface Animal {public void show();
}
// 具体产品:马类
class Horse implements Animal {public Horse() {System.out.println("具体马类的生成");
}
public void show() {System.out.println("执行马类的相应操作");
}
}
// 具体产品:牛类
class Cattle implements Animal {public Cattle() {
// 具体牛类的生成
System.out.println("具体牛类的生成");
}
public void show() {System.out.println("执行马类的相应操作");
}
}
// 形象产品:动物类
interface Plant {public void show();
}
// 具体产品:水果类
class Fruitage implements Plant {public Fruitage() {System.out.println("具体水果类生成");
}
public void show() {System.out.println("执行水果类的相应操作");
}
}
// 具体产品:蔬菜类
class Vegetables implements Plant {public Vegetables() {System.out.println("具体蔬菜类生成");
}
public void show() {System.out.println("执行蔬菜类的相应操作");
}
}
// 形象工厂:农场类
interface Farm {public Animal newAnimal();
public Plant newPlant();}
// 具体工厂:农场类 1
class SGfarm implements Farm {public Animal newAnimal() {System.out.println("新牛出世!");
return new Cattle();}
public Plant newPlant() {System.out.println("蔬菜长成!");
return new Vegetables();}
}
// 具体工厂:农场类 2
class SRfarm implements Farm {public Animal newAnimal() {System.out.println("新马出世!");
return new Horse();}
public Plant newPlant() {System.out.println("水果长成!");
return new Fruitage();}
}
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.File;
/**
* @author hz
* @version 1.0
*/
public class ReadXML2 {public static Object getObject() {
try {DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src/AbstractFactory/config.xml"));
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild();
String cName = "AbstractFactory." + classNode.getNodeValue();
System.out.println("新类名:" + cName);
Class<?> c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
} catch (Exception e) {e.printStackTrace();
return null;
}
}
}
那么该模式有什么长处呢?
形象工厂模式是在工厂办法模式的根底之上进行优化而来,所有工厂办法模式的长处都有,
除此之外还具备本人的长处:
- 1. 能够在类的外部对产品族中相关联的多等级产品独特治理,而不用专门引入多个新的类来进行治理。
- 2. 当须要产品族时,形象工厂能够保障客户端始终只应用同一个产品的产品组。
- 3. 形象工厂加强了程序的可扩展性,当减少一个新的产品族时,不须要批改原代码,满足开闭准则。
毛病:
当产品族中须要减少一个新的产品时,所有的工厂类都须要进行批改。减少了零碎的抽象性和了解难度。
依据以上对形象工厂模式的剖析,咱们能够晓得形象工厂模式通常实用于以下场景:
- 当须要创立的对象是一系列互相关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
- 零碎中有多个产品族,但每次只应用其中的某一族产品。如有人只喜爱穿某一个品牌的衣服和鞋。
- 零碎中提供了产品的类库,且所有产品的接口雷同,客户端不依赖产品实例的创立细节和内部结构。
总结:
形象工厂模式的扩大有肯定的“开闭准则”歪斜性:
- 当减少一个新的产品族时只需减少一个新的具体工厂,不须要批改原代码,满足开闭准则。
- 当产品族中须要减少一个新品种的产品时,则所有的工厂类都须要进行批改,不满足开闭准则。
另一方面,当零碎中只存在一个等级构造的产品时,形象工厂模式将进化到工厂办法模式,工厂模式在理论生存中的应用场合很多,具体应用工厂办法模式还是形象工厂模式,则依据咱们理论状况而定。