设计模式相关文章
----单例模式原理-JAVA设计模式
----工厂模式原理-JAVA设计模式
代理模式原理-JAVA设计模式
----建造者模式(Bulider模式)详解—JAVA设计模式
工厂模式介绍
- 什么是工厂模式
工厂模式提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离
,工厂模式分为简单工厂、工厂方法、抽象工厂模式
- 作用
- 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式
- 利用工厂模式可以降低程序的耦合性,为后期的维护修改提供了很大的便利
- 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦
一、简单工厂模式
- 什么是简单工厂模式
简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护 - 原理
用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
- 结构
抽象产品类:定义具体产品的公共接口
具体产品类:继承抽象产品类,定义生产的具体产品
工厂类:通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例 - 代码实现
- 创建抽象产品类,定义具体产品的公共接口
public interface Car {
public void run();
}
- 创建具体产品类(继承抽象产品类),定义生产的具体产品
//具体产品类比亚迪
class Byd extends Car {
@Override
public void run() {
System.out.println("生产出了比亚迪");
}
}
//具体产品类本田
class BenTian extends Car {
@Override
public void run() {
System.out.println("生产出了本田");
}
}
- 创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例
class Factory {
public static Product Manufacture(String ProductName){
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
switch (ProductName){
case "A":
return new Byd();
case "B":
return new BenTian ();
default:
return null;
}
}
}
- 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例
//工厂产品生产流程
public class SimpleFactoryPattern {
public static void main(String[] args){
Factory mFactory = new Factory();
//客户要比亚迪
try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
mFactory.Manufacture("A").run();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要本田
try {
mFactory.Manufacture("B").run();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要奔驰
try {
mFactory.Manufacture("D").run();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
}
}
- 结果输出
生产出了比亚迪
生产出了本田
没有这一类产品
- 优点
- 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦
- 把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程
- 缺点
- 很明显工厂类集中了所有实例的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响
- 违反GRASPR的高内聚的责任分配原则
- 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构
二、工厂方法
- 什么是工厂方法
工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节 - 原理
用来生产同一等级结构中的固定产品。(支持拓展增加产品)
-
结构
抽象工厂类:定义具体工厂的公共接口
抽象产品类:定义具体产品的公共接口
具体产品类:继承抽象产品类,定义生产的具体产品
具体工厂类:继承抽象工厂类,定义创建对应具体产品实例的方法 -
代码实现
- 创建抽象工厂类,定义具体工厂的公共接口
abstract class Factory{
public abstract Car Manufacture();
}
- 创建抽象产品类 ,定义具体产品的公共接口
public interface Car {
public void run();
}
- 创建具体产品类(继承抽象产品类),定义生产的具体产品
//具体产品类比亚迪
class Byd extends Car {
@Override
public void run() {
System.out.println("生产出了比亚迪");
}
}
//具体产品类本田
class BenTian extends Car {
@Override
public void run() {
System.out.println("生产出了本田");
}
}
- 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法
//工厂A类 - 生产比亚迪
class FactoryA extends Factory{
@Override
public Product Manufacture() {
return new Byd ();
}
}
//工厂B类 - 生产本田
class FactoryB extends Factory{
@Override
public Car Manufacture() {
return new BenTian ();
}
}
- 演示创建工厂的具体实例
//生产工作流程
public class FactoryPattern {
public static void main(String[] args){
//客户要比亚迪
FactoryA mFactoryA = new FactoryA();
mFactoryA.Manufacture().run();
//客户要本田
FactoryB mFactoryB = new FactoryB();
mFactoryB.Manufacture().run();
}
}
- 结果输出
生产出了比亚迪
生产出了本田
- 优点
- 更符合开-闭原则,新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
- 符合单一职责原则,每个具体工厂类只负责创建对应的产品
- 不使用静态工厂方法,可以形成基于继承的等级结构
- 缺点
- 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
- 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类
- 一个具体工厂只能创建一种具体产品
三、抽象工厂模式
- 什么是抽象工厂模式
抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品 - 原理
用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)
- 结构
创建抽象产品族类 :定义抽象产品的公共接口
创建抽象产品类 :继承抽象产品族类,定义具体产品的公共接口
创建抽象工厂类:定义具体工厂的公共接口;
具体产品类:继承抽象产品类,定义生产的具体产品
具体工厂类:继承抽象工厂类,定义创建对应具体产品实例的方法 - 代码实现
- 创建抽象产品族类 ,定义具体产品的公共接口
abstract class Product {
public abstract void run();
}
- 创建抽象产品类 ,定义具体产品的公共接口
//车间产品抽象类
abstract class HouseProduct extends Product {
@Override
public abstract void run();
}
//汽车产品抽象类
abstract class CarProduct extends Product {
@Override
public abstract void run();
}
- 创建抽象工厂类,定义具体工厂的公共接口
abstract class Factory{
//车间抽象类
public abstract Product HouseFactory();
//汽车抽象类
public abstract Product CarFactory();
}
- 创建具体产品类(继承抽象产品类),定义生产的具体产品
//具体产品类比亚迪
class BydCar extends CarProduct {
@Override
public void run() {
System.out.println("生产出了比亚迪");
}
}
//具体产品类本田
class BenTianCar extends CarProduct {
@Override
public void run() {
System.out.println("生产出了本田");
}
}
//具体产品类比亚迪车间
class BydHouse extends HouseFactory{
@Override
public void run() {
System.out.println("比亚迪车间");
}
}
//具体产品类本田车间
class BenTianHouse extends HouseFactory{
@Override
public void run() {
System.out.println("本田车间");
}
}
- 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法
//工厂A类 - 生产比亚迪和比亚迪车间
class FactoryA extends Factory{
@Override
public Product HouseFactory() {
return new BydHouse();
}
@Override
public Product CarFactory() {
return new BydCar();
}
}
//工厂B类 - 生产本田和本田车间
class FactoryB extends Factory{
@Override
public Product HouseFactory() {
return new BentianHouse();
}
@Override
public Product CarFactory() {
return new BenTianCar ();
}
}
- 演示创建工厂的具体实例
//生产工作流程
public class FactoryPattern {
public static void main(String[] args){
//客户要比亚迪
FactoryA mFactoryA = new FactoryA();
mFactoryA.HouseFactory().run();
mFactoryA.CarFactory().run();
System.out.println("----------");
//客户要本田
FactoryB mFactoryB = new FactoryB();
mFactoryB.Manufacture().run();
mFactoryB.CarFactory().run();
}
}
- 结果输出
比亚迪车间
生产出了比亚迪
----------
本田车间
生产出了本田
- 优点
- 降低耦合
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展 - 更符合开-闭原则
新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可 - 符合单一职责原则
每个具体工厂类只负责创建对应的产品 - 不使用静态工厂方法,可以形成基于继承的等级结构
- 缺点
- 抽象工厂模式很难支持新种类产品的变化
- 抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
设计模式相关文章
----单例模式原理-JAVA设计模式
----工厂模式原理-JAVA设计模式
代理模式原理-JAVA设计模式
----建造者模式(Bulider模式)详解—JAVA设计模式