设计模式--工厂模式 (工厂方法、简单工厂、抽象工厂)
工厂方法模式:定义一个用于创建对象的接口,让子类来决定实例化那一个类。工厂方法使一个类的实例化延迟到其子类。
在了解工厂方法前,我们要先了解什么是工厂。现实生活中工厂是生产产品的地方,我们身边的电脑、鼠标、电视等等,都是从各个工厂生产出来的。
如果你对这个图看不明白,那么我们一步步来解释。
----------------------------------------------简单工厂-------------------------------------------------------------------------
就拿我们面前的电脑来说,电脑可以上网。如果只是一台电脑,我们建立一个类就行了,当用到的时候就创建一台电脑就行了。
public class 台式机电脑 {
//上网方法
public void 上网(){
System.out.println("浏览网页");
}
}
public class 电脑测试 {
public static void main(String[] args) {
//创建电脑
台式机电脑 我的电脑 = new 台式机电脑();
我的电脑.上网();
}
}
如果有一天电脑公司要生产笔记本电脑了、
平板电脑、超级本了,这时就需要建立一个工厂,让工厂来完成电脑的创建。
先看看代码:
public class 电脑工厂 {
public 台式机电脑 制造台式机(){
// 返回一台新的台式机电脑
return new 台式机电脑();
}
public 笔记本电脑 制造笔记本电脑(){
// 返回一台新的笔记本电脑
return new 笔记本电脑();
}
public 平板电脑 制造平板电脑(){
// 返回一台新的平板电脑
return new 平板电脑();
}
public 超级本电脑 制造超级本电脑(){
// 返回一台新的笔记本电脑
return new 超级本电脑();
}
}
public class 台式机电脑 {
public void 上网(){
System.out.println("浏览网页");
}
}
public class 笔记本电脑 {
public void 上网() {
System.out.println("浏览网页");
}
}
public class 超级本电脑 {
public void 上网() {
System.out.println("浏览网页");
}
}
public class 平板电脑 {
public void 上网() {
System.out.println("浏览网页");
}
}
public class 电脑测试 {
public static void main(String[] args) {
台式机电脑 台式机 = new 台式机电脑();
台式机.上网();
笔记本电脑 笔记本 = new 笔记本电脑();
笔记本.上网();
平板电脑 平板 = new 平板电脑();
平板.上网();
超级本电脑 超级本 = new 超级本电脑();
超级本.上网();
}
}
我们看到,这样做后,创建太麻烦了,我们应该把这些变化封装起来,让用户调用的时候,只需要根据需要让工厂创建就行
先创建一个电脑工厂:
public class 电脑工厂 {
public 电脑 制造电脑(String 电脑类型){
if(电脑类型.equals("台式机电脑")){
return new 台式机电脑();
}else if(电脑类型.equals("笔记本电脑")){
return new 笔记本电脑();
}else if(电脑类型.equals("平板电脑")){
return new 笔记本电脑();
}else if(电脑类型.equals("超级本电脑")){
return new 笔记本电脑();
}else{
return null;
}
}
}
电脑工厂根据有一个制造电脑的方法,根据传入的电脑类型创建
然后抽象一个电脑接口,所有类型的电脑都实现这个电脑接口;
public interface 电脑 {
public void 上网();
}
public class 笔记本电脑 implements 电脑{
public void 上网() {
System.out.println("浏览网页");
}
}
public class 超级本电脑 implements 电脑{
public void 上网() {
System.out.println("浏览网页");
}
}
public class 台式机电脑 implements 电脑{
public void 上网(){
System.out.println("浏览网页");
}
}
public class 平板电脑 implements 电脑{
public void 上网() {
System.out.println("浏览网页");
}
}
public class 电脑测试 {
public static void main(String[] args) {
电脑工厂 工厂 = new 电脑工厂();
电脑 台式机 = 工厂.制造电脑("台式机电脑");
台式机.上网();
电脑 笔记本 = 工厂.制造电脑("笔记本电脑");
笔记本.上网();
电脑 平板 = 工厂.制造电脑("平板电脑");
平板.上网();
电脑 超级本 = 工厂.制造电脑("超级本电脑");
超级本.上网();
}
}
再看看类图;
【简单工厂】这种模式叫简单工厂模式,它先创建一个产品接口,然后让所有具体产品实现它,然后创建一个产品工厂,在产品工厂中有一个创建产品的方法,在创建产品的方法里,通过传入的产品名称,来返回具体的产品。
工厂方法适用产品比较固定的情况下,也就是产品不会增加或者减少。
如果产品系列可能发生变化,就不适合简单工厂模式了。
----------------------------------------------工厂方法-------------------------------------------------------------------------
如果现在电脑工厂开始生产上网本了,那么,是不是让上网本来实现电脑接口,然后在电脑工厂的创建电脑方法中去修改判断语句呢?
这样就违反面向对象的设计原则—--对修改关闭,对扩展开放。
【对修改关闭,对扩展开发】指的是程序设计时,应该考虑到变化,并将变化的部分给出接口,当新的变化需求来了后,只需要扩展系统的功能就行了,不需要去修改原有代码。只有遵循这样的设计,才能算是优秀的设计。
如何应对产品线的变化呢?工厂方法就是解决这一问题的关键!让我们回头看看工厂方法的类图,然后想想我们如何设计电脑公司产品线!
先看看类图:
public interface 电脑 {
public void 上网();
}
public interface 电脑工厂 {
public 电脑 制造电脑();
}
public class 台式机电脑 implements 电脑{
public void 上网(){
System.out.println("浏览网页");
}
}
public class 上网本电脑 implements 电脑{
public void 上网() {
System.out.println("浏览网页");
}
}
public class 台式机工厂 implements 电脑工厂{
public 电脑 制造电脑() {
return new 台式机电脑();
}
}
public class 上网本工厂 implements 电脑工厂{
public 电脑 制造电脑() {
return new 上网本电脑();
}
}
public class 电脑测试 {
public static void main(String[] args) {
电脑工厂 台式机工厂 = new 台式机工厂();
电脑 台式机 = 台式机工厂.制造电脑();
台式机.上网();
电脑工厂 上网本工厂 = new 上网本工厂();
电脑 上网本 = 上网本工厂.制造电脑();
上网本.上网();
}
}
根据上面的类图和代码,我们再想想,如果再增加一个电脑类型,那么,不需要去修改任何代码,只需要在原有的基础上扩展代码就行了。我们只需要建立一个新电脑类型的工厂,建一个实现了电脑的产品类。就可以了,然后告诉用户,我们有这个产品了,你买的话,我就让工厂给你制造。是不是很简单!
【工厂方法模式】 定义了制造具体产品的接口,然后让子类的具体产品工厂在自己的方法中创建具体的产品。工厂的方法让产品的创建延迟到子类的具体产品工厂中执行。
工厂方法模式适合产品变化的情况,如果产品会发生变化,使用工厂方法模式可以应对这种变化。
但是,如果有多条产品线(产品族),而且产品线或者产品类型会经常变化,那么就不能用工厂方法模式了。
----------------------------------------------抽象工厂-------------------------------------------------------------------------
随着时间的推移,电脑公司的发展越来越大,开始考虑多产品线、精细化发展,电脑公司董事会决定制造手机了!而且装备自己建配件厂,生产外壳的工厂和生产主板的工厂负责各自的产品,然后根据不同的需求送到具体产品工厂去生产产品,这样有利于控制成本和管理。可是新的问题来了,产品工厂与外壳、主板这些配件工厂如何关联呢?
这就要用抽象工厂来处理了。
【抽象工厂】提供一个创建一系列相关相互依赖对象的接口,而无需指定他们具体类。
产品工厂都有一个配件装配流程,流程中的配件都是大体相同的,就点子产品来讲,都会从装主板、显示屏、装外壳这个流程来走,因为这个流程中的主板就是电路板,只有专业的电路板工厂才能制造出来,不能与制造外壳的工厂放到一起,因为技术含量和原料都不同,也不能把手机主板和电脑主板分开,因为这样就不能体现出资源的整合,成本、技术、人才的控制了。所以对于产品工厂来讲,声明装配主板、外壳这个流程中需要(依赖)的对象(外壳、主板),不需要指定具体那个产品类型的产品。当用户的产品那一天发生变化的时候,只需要让用户可以自动配置具体用那个类型的产品。
代码:
//主板接口
public interface 主板 {
}
//手机主板
public class 手机主板 implements 主板{
public void 检测(){
System.out.println("检测手机主板成功");
}
}
//电脑主板
public class 电脑主板 implements 主板{
public void 检测(){
System.out.println("检测电脑主板成功");
}
}
//外壳接口
public interface 外壳 {
}
//手机外壳
public class 手机外壳 implements 外壳{
public void 检测(){
System.out.println("检测手机外壳成功");
}
}
//电脑外壳
public class 电脑外壳 implements 外壳{
public void 检测() {
System.out.println("检测电脑外壳成功");
}
}
//主板接口
public interface 产品工厂 {
主板 装主板();
外壳 装外壳();
}
//手机工厂
public class 手机工厂 implements 产品工厂 {
public 主板 装主板() {
return new 手机主板();
}
public 外壳 装外壳() {
return new 手机外壳();
}
}
//电脑工厂
public class 电脑工厂 implements 产品工厂{
public 主板 装主板() {
return new 电脑主板();
}
public 外壳 装外壳() {
return new 电脑外壳();
}
}
//手机类
public class 手机 {
private 外壳 手机外壳;
private 主板 手机主板;
public void 显示(){
System.out.println("手机做好了,配件有:"+
this.手机主板 + "," + this.手机外壳);
}
// getter & setter
public 外壳 get手机外壳() {
return 手机外壳;
}
public void set手机外壳(外壳 手机外壳) {
this.手机外壳 = 手机外壳;
}
public 主板 get手机主板() {
return 手机主板;
}
public void set手机主板(主板 手机主板) {
this.手机主板 = 手机主板;
}
}
public class 产品测试 {
public static void main(String[] args) {
手机 我的手机 = new 手机();
手机工厂 我的手机工厂 = new 手机工厂();
主板 手机主板 = 我的手机工厂.装主板();
外壳 手机外壳 = 我的手机工厂.装外壳();
我的手机.set手机主板(手机主板);
我的手机.set手机外壳(手机外壳);
我的手机.显示();
}
}
这样的设计最大的好处是易于交换产品系列,比如那天手机主板或者外壳有变化,我们不需要去修改原有代码,只要通过实现主板或者外壳接口,然后在用户调用时传入新添加的主板或者外壳就可以解决问题。在一个应用中只需要在初始化的石化出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。这中模式就是让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂实现分离,不会出现在客户端代码中了。
就像下面的服饰代码,当我们出门时,需要搭配服饰,那么男人和女人会有不同风格的衣服,但是产品系列是一样的,比如上衣,比如裤子,在配衣服的时候不需要去关心具体用什么上衣,只关心某种风格的、或者某种性别的衣服搭配,不需要指定具体衣服。上衣类型增加或者减少都不会影响衣服的搭配。
如果那天觉得男装或者女装不能满足需求,需要添加另外的类型,比如中性服装,这样就可以不修改代码的情况下解决问题:只需要继承服饰类,然后配各种上衣或者裤子就可以了。
是不是超级灵活!
- 大小: 20.7 KB
- 大小: 3.3 KB
- 大小: 17.1 KB
- 大小: 21 KB
- 大小: 25.1 KB
- 大小: 33.4 KB
- 大小: 31.8 KB
分享到:
相关推荐
在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...
java设计模式----抽象工厂模式,简单工厂模式代码 代码内部
设计模式专题之(三)抽象工厂模式---设计模式抽象工厂模式示例代码(python--c++)
抽象工厂模式是设计模式中的一种创建型模式,它提供了一个创建对象族的接口,而无需指定它们的具体类。在.NET开发中,这种模式常用于实现多数据库连接,比如连接到MySQL、SQL Server或Oracle等不同的数据库系统。...
设计模式 - 抽象工厂模式 抽象工厂模式是一种创建型设计模式,它提供了一种方式来创建一组相关或相互依赖的对象,而不需要指定具体的类。该模式允许客户端使用抽象的接口来创建一组相关的产品,而不需要关系实际...
抽象工厂模式是创建型设计模式的一种,它提供了一种创建对象族(一组具有相互依赖关系的对象)的方法,而无需指定具体类。这种模式的核心在于它允许客户端代码与具体实现细节解耦,使得更换一个产品族变得更为容易。...
抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象族的接口,而无需指定具体的类。这种模式允许客户端使用一个通用接口来创建一组相关或相互依赖的对象,而无需了解它们的具体实现。在Java或其他面向...
工厂模式分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 1. **简单工厂模式** 简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要...
本篇文章将对三种主要的工厂模式:简单工厂、工厂方法和抽象工厂进行深入的对比和总结。 **简单工厂模式** 是最基础的工厂模式形式,它提供一个静态方法或类来创建对象。在这个模式中,工厂是负责创建对象的中心...
抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体的类。这种模式允许系统独立于如何创建、组合和表示产品对象的细节进行设计,为产品族(一组相关或相互依赖的对象)提供...
设计模式---抽象工厂模式(Abstract Factory)-UML图 (StarUML)
抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象族的接口,而无需指定其具体的类。这种模式的关键在于“族”,即一系列相关的对象。在抽象工厂模式中,我们创建一个抽象工厂接口,然后为每一种具体...
抽象工厂模式是创建型设计模式中的一种,用于创建一系列相关或相互依赖的对象,而无需指定其具体类。抽象工厂模式强调产品的系列,对于有多个产品等级结构的系统非常有用。在抽象工厂模式中,一个工厂负责创建多个...
抽象工厂模式是设计模式中的一种,它属于创建型模式,主要解决的是当系统有多个产品族,而每个产品族又有多个具体产品时,如何组织代码的问题。在Java中,抽象工厂模式提供了一种创建对象组的方式,使得这些对象属于...
* 抽象工厂模式可以与其他设计模式结合使用,例如工厂方法模式、单例模式等。 抽象工厂模式是一种非常有用的设计模式,它可以帮助我们降低耦合度、提高灵活性和可扩展性。但是,需要注意抽象工厂模式的缺点,并适当...
抽象工厂模式是软件设计模式中的一种创建型模式,它提供了一种创建对象族(一组具有相互依赖关系的对象)的方法,而无需指定它们的具体类。在Java编程中,抽象工厂模式通常用于实现跨平台或者跨框架的接口,使得系统...
工厂方法、简单工厂和抽象工厂是创建型设计模式的三种不同形式,它们都关注于对象的创建过程,但各有其特点和适用场景。 1. **工厂方法(Factory Method)**: 工厂方法模式定义了一个创建对象的接口,但让子类...
"抽象工厂"是设计模式中的一种,属于创建型模式,它提供了一种创建对象族的接口,而无需指定它们的具体类。这个模式的核心在于隔离了产品对象的创建过程,使得系统对具体产品的依赖最小化,从而增强了系统的灵活性和...
**抽象工厂方法(Abstract Factory Pattern)**是一种创建型设计模式,它提供了一种创建对象族的接口,而具体的对象族由子类决定。在C++中,这种模式可以帮助我们隔离对象的创建和使用,使得代码更加灵活,易于扩展...
抽象工厂设计模式抽象工厂设计模式 抽象工厂设计模式 抽象工厂设计模式 抽象工厂设计模式 抽象工厂设计模式 抽象工厂设计模式