设计模式之简单工厂/工厂方法/抽象工厂

这三个设计模式都属于创建型模式,之间具有关联性,就放在一起讲解。其实简单工厂模式是工厂方法的一个特例,并不是23种设计模式的一种。

使用java来写的这几个设计模式。java文件目录树如下所示:

[email protected]:~/code/designpattern/SimpleFactory/src$ tree
.
├── Client.java
└── zy
    ├── abstractfactory
    │   ├── AccerFactory.java
    │   ├── AppleFactory.java
    │   └── ComputerAbstractFactoy.java
    ├── factory
    │   ├── ComputerFactory.java
    │   ├── DesktopComputerFactory.java
    │   └── LaptopFactory.java
    ├── product
    │   ├── AccerDesktopComputer.java
    │   ├── AccerLaptop.java
    │   ├── AppleDesktopComputer.java
    │   ├── AppleLaptop.java
    │   ├── Computer.java
    │   ├── DesktopComputer.java
    │   └── Laptop.java
    └── simplefactory
        └── ComputerSimpleFactory.java

5 directories, 15 files

通过一个教研室购买电脑的场景来描述动机和相应的优缺点。

一个教研室会购买一定数量的电脑来让学生干活,比较早些的时候购买的是台式机,

1. 下面看看普通的创建方法。

//Computer.java
package zy.product;

public interface Computer {
	void uname();
}
//Laptop.java
package zy.product;

public class Laptop implements Computer {
	public void uname()
	{
		System.out.println("我是笔记本,更加便于携带");
	}

}
//DesktopComputer.java
package zy.product;

public class DesktopComputer implements Computer {
	public void uname()
	{
		System.out.println("我是台式机,屏幕更大");
	}

}
//一般调用的测试方法
	public static void normalTest() {
		Computer labComputer1 = new Laptop();
		labComputer1.uname();
		Computer labComputer2 = new Laptop();
		labComputer2.uname();
		Computer labComputer3 = new Laptop();
		labComputer3.uname();
		Computer labComputer4 = new Laptop();
		labComputer4.uname();
		Computer labComputer5 = new Laptop();
		labComputer5.uname();
	}

这里,教研室需要5台笔记本,但是如果过两年,教研室需要5台台式机,那么就需要更改每一个创建对象的语句。这样的可读性和可维护性都不好。

2. 简单工厂模式

思路是通过一个简单的工厂来进行电脑的创建,让客户端直接调用工厂来得到电脑,从而自己不用管电脑是如何生产的。 看如下代码:

//ComputerSimpleFactory.java
package zy.simplefactory;

import zy.product.Computer;
import zy.product.DesktopComputer;
import zy.product.Laptop;

public class ComputerSimpleFactory {
	public static Computer createComputer(String computerName) {
		if( "Laptop".equals(computerName)) {
			return new Laptop();
		}
		else if( "DesktopComputer".equals(computerName)) {
			return new DesktopComputer();
		}
		else
			return new Laptop();
	}

}
//简单工厂的测试方法
	public static void simpleFactoryTest() {
		//实验室要5台笔记本
		/*
		Computer labComputer1 = ComputerFactory.createComputer("Labtop");
		labComputer1.uname();
		Computer labComputer2 = ComputerFactory.createComputer("Labtop");
		labComputer2.uname();
		Computer labComputer3 = ComputerFactory.createComputer("Labtop");
		labComputer3.uname();
		Computer labComputer4 = ComputerFactory.createComputer("Labtop");
		labComputer4.uname();
		Computer labComputer5 = ComputerFactory.createComputer("Labtop");
		labComputer5.uname();
		*/

		//实验室更改需求,要5台台式机
		Computer labComputer1 = ComputerSimpleFactory.createComputer("DesktopComputer");
		labComputer1.uname();
		Computer labComputer2 = ComputerSimpleFactory.createComputer("DesktopComputer");
		labComputer2.uname();
		Computer labComputer3 = ComputerSimpleFactory.createComputer("DesktopComputer");
		labComputer3.uname();
		Computer labComputer4 = ComputerSimpleFactory.createComputer("DesktopComputer");
		labComputer4.uname();
		Computer labComputer5 = ComputerSimpleFactory.createComputer("DesktopComputer");
		labComputer5.uname();
	}

可以看到,直接调用工厂类的静态方法来生产笔记本就可以了。统一的接口可读性更好。并且便于维护。

3. 工厂方法模式

上面的简单工厂模式,有个缺点就是如果增加了一种电脑的种类,比如超极本。 就需要修改工厂的静态生产方法,违背了开放-封闭原则,对修改也进行了开放。

针对这个缺点,利用父类和子类之间虚函数的多态性,动态绑定,可以方便的创建对象。代码如下:

//ComputerFactory.java
package zy.factory;

import zy.product.Computer;

public interface ComputerFactory {
	public Computer createComputer();

}
//LaptopFactory.java
package zy.factory;

import zy.product.Computer;
import zy.product.Laptop;

public class LaptopFactory implements ComputerFactory{
	public Computer createComputer() {
		return new Laptop();
	}
}
//DesktopComputerFactory.java
package zy.factory;

import zy.product.Computer;
import zy.product.DesktopComputer;

public class DesktopComputerFactory implements ComputerFactory{
	public Computer createComputer() {
		return new DesktopComputer();
	}
}
//工厂方法的测试方法
	public static void factoryTest() {
		//原来需求
		ComputerFactory factory = new LaptopFactory();
		//需求更改:
		//ComputerFactory factory = new DesktopComputerFactory();
		Computer labComputer1 = factory.createComputer();
		labComputer1.uname();
		Computer labComputer2 = factory.createComputer();
		labComputer2.uname();
		Computer labComputer3 = factory.createComputer();
		labComputer3.uname();
		Computer labComputer4 = factory.createComputer();
		labComputer4.uname();
		Computer labComputer5 = factory.createComputer();
		labComputer5.uname();
	}	

可以看到,如果增加了一个超极本的种类,不用修改现有的代码,直接增加一个超极本的工厂即可。并且客户端的需求代码,也只用更换一个工厂即可。 比简单工厂具有更好的可扩展性。 工厂方法模式,又叫做虚构造模式,就是通过这个方法来代替构造函数的作用。

4. 抽象工厂模式

教研室本来是用的宏碁牌子的电脑,但是现在变成土豪了,要更换成苹果的电脑。 如果使用工厂方法,就需要*2倍的建造工厂,代码量变大了许多。 这时候可以采取抽象工厂模式,将多个相关的工厂方法放在一个工厂里,比如将生产电脑(包括笔记本/台式机)的方法放在苹果厂里和宏碁厂里。这样减少了代码量。 把一些具体的相关产品抽象到了一个工厂里。

//AppleLaptop.java
package zy.product;

public class AppleLaptop extends Laptop{
	public void uname()
	{
		System.out.println("我是苹果笔记本,更加便于携带");
	}
}
//AppleDesktopComputer.java
package zy.product;

public class AppleDesktopComputer extends DesktopComputer{
	public void uname()
	{
		System.out.println("我是苹果台式机,屏幕更大");
	}
}
//AccerLaptop.java
package zy.product;

public class AccerLaptop extends Laptop {
	public void uname()
	{
		System.out.println("我是宏碁笔记本,更加方便携带");
	}
}
//AccerDesktopComputer.java
package zy.product;

public class AccerDesktopComputer extends DesktopComputer {
	public void uname()
	{
		System.out.println("我是宏碁台式机,屏幕更大");
	}
}
//ComputerAbstractFactoy.java
package zy.abstractfactory;

import zy.product.DesktopComputer;
import zy.product.Laptop;

public interface ComputerAbstractFactoy {
	public Laptop createLaptop();
	public DesktopComputer createDesktopComputer();

}
//AppleFactory.java
package zy.abstractfactory;

import zy.product.AppleDesktopComputer;
import zy.product.AppleLaptop;
import zy.product.DesktopComputer;
import zy.product.Laptop;

public class AppleFactory implements ComputerAbstractFactoy{
	public Laptop createLaptop() {
		return new AppleLaptop();
	}

	public DesktopComputer createDesktopComputer() {
		return new AppleDesktopComputer();
	}

}
//AccerFactory.java
package zy.abstractfactory;

import zy.product.AccerDesktopComputer;
import zy.product.AccerLaptop;

import zy.product.DesktopComputer;
import zy.product.Laptop;

public class AccerFactory implements ComputerAbstractFactoy{
	public Laptop createLaptop() {
		return new AccerLaptop();
	}

	public DesktopComputer createDesktopComputer() {
		return new AccerDesktopComputer();
	}

}
//抽象工厂的测试方法
	public static void abstratFactoryTest() {
		//原来需求,苹果的笔记本
		ComputerAbstractFactoy factory = new AppleFactory();
		//现在的需求,宏碁的笔记本
		//ComputerAbstractFactoy factory = new AccerFactory();
		Computer labComputer1 = factory.createLaptop();
		labComputer1.uname();
		Computer labComputer2 = factory.createLaptop();
		labComputer2.uname();
		Computer labComputer3 = factory.createLaptop();
		labComputer3.uname();
		Computer labComputer4 = factory.createLaptop();
		labComputer4.uname();
		Computer labComputer5 = factory.createLaptop();
		labComputer5.uname();
	}

可以看到抽象工厂具有比工厂方法更小的规模。 当需要更换一些列产品的时候,只需要更换一个工厂类即可。但是,如果新产品进来的时候,需要修改抽象工厂类的设计,同时修改现有的工厂类的代码。

注:

代码打包在:点击打开链接

时间: 2024-11-03 05:34:11

设计模式之简单工厂/工厂方法/抽象工厂的相关文章

详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

园子里关于23种设计模式的博文已经可以说是成千上万.车载斗量.屯街塞巷.不计其数.数不胜数.摩肩接踵.汗牛充栋.车水马龙.门庭若市.琳琅满目直至让人眼花缭乱了.在这样的大环境下之所以来写设计模式类的博文,并不是像一些"非主流"的爱情观那样"宁缺毋滥". 只是其一呢,因为相当于给自己做一个总结,加深一下自己这方面的认识,因为掌握了和把它写出来我感觉后者还可以对技能有一个提升,其二呢是因为最近公司有一个内部的training需要讲设计模式. v写在前面 在这里呢,需要向

创建和使用解耦——工厂模式详解(工厂方法+抽象工厂)

1.前言 直接new一个对象是最简单的创建对象的方式,但大量出现在业务代码中会带来至少两个问题.1:创建对象的细节直接暴露在业务代码中,修改实现细节必须修改相关的大量客户端代码.2:直接面向具体类型编程,违反了面向接口编程的原则,系统进行扩展时也不得不进行大量修改.要使得系统具有的良好的可扩展性以及后期易于维护,必须实现对产品的获取和对产品的使用解耦.要做到这两点,首先要对客户端代码屏蔽掉创建产品的细节,其次,客户端必须面向产品的抽象编程,利用java的多态特性在运行时才确定具体的产品.而这,正

2 简单工厂模式、工厂模式、抽象工厂模式

简单工厂模式: -----------------------------------Pizza.java-------------------- package com; public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public abstract void cut(); } -----------------------------------APizza.

《大话设计模式》学习笔记11:抽象工厂模式

切换数据库类型示例: 1.User类: public class User { public int Id { get; set; } public string Name { get; set; } } 2.AbstractProduct(以User为例): public interface IUser { void Insert(User user); User GetUser(int id); } 3.Product(以User.SQL Server为例): public class Sq

设计模式学习笔记(十一:抽象工厂模式)

1.1概述 提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类.这就是抽象工厂模式的定义. 设计某些系统时可能需要为用户提供一系列相关的对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否则用户不仅要清楚地知道使用哪些类来创建这些对象,而且还必须要清楚对象之间是如何关联的,使得用户的代码和这些类形成紧耦合.缺乏弹性.不利于维护. 例如,军队要为士兵(用户)提供机关枪.手枪以及相应的子弹,但军队系统不希望由士兵提供来生产机关枪.手枪以及子弹,

Delphi 设计模式:《HeadFirst设计模式》Delphi代码---工厂模式之抽象工厂[转]

 1 2 {<HeadFirst设计模式>工厂模式之抽象工厂 } 3 { 抽象工厂的产品                       } 4 { 编译工具:Delphi7.0                  } 5 { E-Mail :[email protected]          } 6 7unit uPizzaIngredient; 8 9interface1011type12  TDough = class(TObject)13  end;1415  TThinCrustDoug

工厂模式[3] 抽象工厂 Abstract Factory

简介 1.简单工厂,或静态工厂,产品接口 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类或实现同一接口 优点:客户端可以直接消费产品,而不必关心具体产品的实现(不关心对象的构造方法是怎么new的),消除了客户端直接创建产品对象的责任,实现了对责任的分割. 缺点:工厂类记录了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响:而且当产品种类多.结构复杂的时候,把所有创建工作放进一个工厂中来,会使后期程序的扩展较为困难. 2.工厂方法,工厂接口+产品接口 定义:在

6创建型模式之工厂模式与抽象工厂模式

工厂模式 概念 工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 . 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 类图角色和职责 抽象工厂(Creator)角色 工厂方法模式的核心,任何工厂类都必须实现这个接口. 具体工厂( Concrete  Creator)角

工厂模式和抽象工厂模式

工厂模式: 定义一个用于创建对象的接口,让他的子类决定实例化哪个类.使类的实例化延迟到子类. 1.普通的工厂模式: public class GoodProduct implements Product { private String prodInfo = "Iam the good prod"; public String getProductInfo() { // TODO Auto-generated method stub return this.prodInfo; } pu