这三个设计模式都属于创建型模式,之间具有关联性,就放在一起讲解。其实简单工厂模式是工厂方法的一个特例,并不是23种设计模式的一种。
使用java来写的这几个设计模式。java文件目录树如下所示:
zy@zy:~/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();
}可以看到抽象工厂具有比工厂方法更小的规模。 当需要更换一些列产品的时候,只需要更换一个工厂类即可。但是,如果新产品进来的时候,需要修改抽象工厂类的设计,同时修改现有的工厂类的代码。代码打包在:点击打开链接
原文地址:http://blog.csdn.net/zy416548283/article/details/44087255