设计模式之工厂模式

三、设计模式

4. 工厂模式(Factory Method Pattern)

4.1 简介

工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。

4.2 分类

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

核心本质:

  • 实例化对象,用工厂方法代替new操作。
  • 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦
①简单工厂模式
定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

结构

分配角色:

  • Factory:工厂角色

工厂角色负责实现创建所有实例的内部逻辑

  • Product:抽象产品角色

抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口

  • ConcreteProduct:具体产品角色

具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例

结构图

代码实现

公共接口

public interface Car {

	void run();
}

实例

Benze public class Benze implements Car {

	[@Override](https://my.oschina.net/u/1162528)
	public void run() {

		System.out.println("奔驰再跑------");
	}

}

Audi

public class Audi implements Car {

	[@Override](https://my.oschina.net/u/1162528)
	public void run() {

		System.out.println("奥迪再跑------");
	}

}

定义工厂类

public class CarFactory {

	public static Car creatCar(String type) {
		if("奥迪".equals(type)) {
			return new Audi();
		}else if ("奔驰".equals(type)) {
			return new Benze();
		}else {
			return null;
		}
	}

}

测试类

import com.tcwong.Car;
import com.tcwong.CarFactory;

public class Test  {

	@org.junit.Test
	public void test() {

		Car car1 = CarFactory.creatCar("奔驰");
		Car car2 = CarFactory.creatCar("奥迪");
		car1.run();
		car2.run();
	}

}

输出

优点
  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点
  • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
使用环境
  • 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
②工厂方法模式
定义

工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

分配角色
  • Product:抽象产品
  • ConcreteProduct:具体产品
  • Factory:抽象工厂
  • ConcreteFactory:具体工厂
结构图

代码实现

公共实体接口

public interface Car {

	void run();
}

实体类1

public class Audi implements Car {

	[@Override](https://my.oschina.net/u/1162528)
	public void run() {

		System.out.println("奥迪再跑------");
	}

}

实体类2

public class Benze implements Car {

	[@Override](https://my.oschina.net/u/1162528)
	public void run() {

		System.out.println("奔驰再跑------");
	}

}

公共工厂接口

public interface ICarFactory {

	Car creatCar();

}

实例工厂1

public class AudiFactory implements ICarFactory {

	@Override
	public Car creatCar() {
		return new Audi();
	}

}

实例工厂2

public class BenzeFactory implements ICarFactory {

	@Override
	public Car creatCar() {
		return new Benze();
	}

}

测试类

public class Test1 {

	@Test
	public void test() {

		Car audi = new AudiFactory().creatCar();

		Car bense = new BenzeFactory().creatCar();

		audi.run();
		bense.run();
	}

}

输出

优点
  • 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
  • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
  • 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
缺点
  • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

使用范围
  • 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
  • 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
③抽象工厂模式
定义

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

分配角色
  • AbstractFactory:抽象工厂
  • ConcreteFactory:具体工厂
  • AbstractProduct:抽象产品
  • Product:具体产品
结构图

代码实现

定义实体公共接口

public interface Engine {

	void run();

	void start();

}

public interface Seat {


	void massege();
}

public interface Tyre {

	void revolve();
}

实体具体类

public class LuxuryEngine implements Engine {

	@Override
	public void run() {
		System.out.println("跑的快");

	}

	@Override
	public void start() {
		System.out.println("自启动");

	}

}


public class LowEngine implements Engine {

	@Override
	public void run() {
		System.out.println("跑的慢");

	}

	@Override
	public void start() {

		System.out.println("手动启动");
	}

}


public class LuxurySeat implements Seat {

	@Override
	public void massege() {

		System.out.println("真皮沙发");

	}

}

public class LowSeat implements Seat {

	@Override
	public void massege() {

		System.out.println("假皮沙发");
	}

}

public class LuxuryTyre implements Tyre {

	@Override
	public void revolve() {

		System.out.println("寿命长");
	}

}

public class LowTyre implements Tyre {

	@Override
	public void revolve() {

		System.out.println("寿命短");
	}

}

工厂接口

public interface ICarAbstractFactory {


	Engine  createEngine();
	Seat  createSeat();
	Tyre  createTyre();

}

工厂实现

public class LuxuryCarFactory implements ICarAbstractFactory {

	@Override
	public Engine createEngine() {
		return new LuxuryEngine();
	}

	@Override
	public Seat createSeat() {
		return new LuxurySeat();
	}

	@Override
	public Tyre createTyre() {
		return new LuxuryTyre();
	}

}

public class LowCarFactory implements ICarAbstractFactory {

	@Override
	public Engine createEngine() {
		return new LowEngine();
	}

	@Override
	public Seat createSeat() {
		return new LowSeat();
	}

	@Override
	public Tyre createTyre() {
		return new LowTyre();
	}

}

测试类

public class Test3 {

	@Test
	public void test() {
		LuxuryCarFactory luxuryCarFactory = new LuxuryCarFactory();
		Engine engine = luxuryCarFactory.createEngine();
		Seat seat = luxuryCarFactory.createSeat();
		Tyre tyre = luxuryCarFactory.createTyre();
		seat.massege();
		tyre.revolve();
		engine.run();
		engine.start();

		LowCarFactory lowCarFactory = new LowCarFactory();
		Engine engine2 = lowCarFactory.createEngine();
		Seat seat2 = lowCarFactory.createSeat();
		Tyre tyre2 = lowCarFactory.createTyre();
		seat2.massege();
		tyre2.revolve();
		engine2.run();
		engine2.start();


	}

}

优点
  • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
  • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
  • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点
  • 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
  • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。

4.3 面向对象设计的基本原则

  • OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭。
  • DIP(依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程。
  • LoD(迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信

转载于:https://my.oschina.net/tcwong/blog/3047641

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂模式是一种常见的创建型设计模式,用于创建对象,而不是通过直接调用构造函数来创建它们。工厂模式定义了一个接口,用于创建相关对象,但是让子类决定要实例化的类。在C++中,工厂模式可以通过以下步骤实现: 1. 创建一个抽象基类,该类定义了一个纯虚拟函数,该函数将返回一个指向基类的指针。这个基类就是我们的工厂接口。 ```c++ class Product { public: virtual ~Product() {} virtual void operation() = 0; }; ``` 2. 创建具体的产品类,它们继承自抽象基类,并实现了其纯虚拟函数。这些类就是我们的具体产品。 ```c++ class ConcreteProductA : public Product { public: void operation() override { /* 具体产品 A 的操作 */ } }; class ConcreteProductB : public Product { public: void operation() override { /* 具体产品 B 的操作 */ } }; ``` 3. 创建一个工厂类,该类实现了工厂接口,并根据需要创建具体的产品。这个工厂类就是我们的具体工厂。 ```c++ class Factory { public: virtual ~Factory() {} virtual std::unique_ptr<Product> createProduct() = 0; }; class ConcreteFactoryA : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductA>(); } }; class ConcreteFactoryB : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductB>(); } }; ``` 4. 在客户端代码中使用具体工厂创建具体产品。 ```c++ int main() { std::unique_ptr<Factory> factory = std::make_unique<ConcreteFactoryA>(); std::unique_ptr<Product> product = factory->createProduct(); product->operation(); return 0; } ``` 这就是工厂模式的基本实现方式。通过这种方式,我们可以将对象的创建过程与客户端代码分离,从而更好地实现模块化和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值