工厂设计模式是java中要求掌握的三大重点设计模式之一,本文将围绕它展开详细叙述。
工厂设计模式分为三种,即简单工厂模式,工厂方法模式和抽象工厂模式。下面将以购买笔记本为线索展将一依次开展开叙述:
1.简单工厂模式
简单工厂模式:专门定义一个类用来创建其它类的实例,被创建的实例通常都具有共同的父类。
这里我们相当于是创建生产电脑的工厂,客户需要购买什么样的电脑,只要输入类型编号就可以获取该电脑。将类的实例化交给工厂易于解耦。
类图如下:
代码如下:
public class BuyComputer{
//调用接口
public void buy(Computer computer){
computer.printComputer();
}
//简单工厂模式
public static void code1(){
BuyComputer client=new BuyComputer();
//1.通过入口方法的参数决定实例化的对象
/*if(args.length==0){
System.out.println("需要传入参数,指定创建的计算机类型");
}else{
String type=args[0];
Computer computer=ComputerFactory.getInstance(type);
if(computer==null){
System.out.println("需要传入参数,指定创建的计算机类型");
}else{h
client.buy(computer);
}
}*/
//2.通过交互式用户输入的方式
java.util.Scanner scanner=new java.util.Scanner(System.in);
while(true){
System.out.println("需要传入参数,指定创建的计算机类型,输入q退出程序");
String value=scanner.nextLine();
if(value.equals("q")){
break;
}
Computer computer=ComputerFactory.getInstance(value);
if(computer==null){
System.out.println("需要传入参数,指定创建的计算机类型");
}else{
client.buy(computer);
}
}
}
public static void main(String[] args){
code1();
}
}
interface Computer{
void printComputer();
}
//计算机实例化对象工厂(简单工厂模式)
class ComputerFactory{
public static Computer getInstance(String type){
Computer computer=null;
if(type==null){
return computer;
}
switch(type){
case "mac":
computer=new MacBookComputer();
break;
case "leishe":
computer=new LeiSheComputer();
break;
case "alienware":
computer=new AlienwareComputer();
break;
default:
System.out.println("暂时没有此类笔记本");
}
return computer;
}
}
class MacBookComputer implements Computer{
public void printComputer(){
System.out.println("这是一台MacBook计算机");
}
}
class LeiSheComputer implements Computer{
public void printComputer(){
System.out.println("这是一台LeiShe计算机");
}
}
优点:
(1)简单易于实现;
(2)把类的实例化交给工厂,易于解耦;
缺点:
(1)添加具体产品需要修改工厂违反OCP开放封闭原则;
2.工厂方法模式
工厂方法模式:定义一个用来创建对象的接口,让子类决定实例化哪一个类,让子类决定实例化延迟到子类。
工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象,针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。
我们将之前的 ComputerFactory变为ComputerFactory1 抽象成一个接口,那么创建相应具体的工厂类去实现该接口的方法。
类图如下:
代码如下:
public class BuyComputer{
public void buy(Computer computer){
computer.printComputer();
}
//工厂模式
public static void code2(){
BuyComputer client=new BuyComputer();
java.util.Scanner scanner=new java.util.Scanner(System.in);
while(true){
System.out.println("需要传入参数,指定创建的计算机类型,输入q退出程序");
String value=scanner.nextLine();
if(value.equals("q")){
break;
}
ComputerFactory1 computerfactory=null;
switch(value){
case "mac":
computerfactory=new MacBookComputerFactory();
break;
case "leishe":
computerfactory=new LeiSheComputerFactory();
break;
default:
System.out.println("暂时没有此类笔记本工厂");
}
Computer computer=ComputerFactory.getInstance(value);
if(computerfactory==null){
System.out.println("需要传入参数,指定创建的计算机类型");
}else{
Computer computer1=computerfactory.createComputer();
client.buy(computer1);
}
}
}
public static void main(String[] args){
code2();
}
}
interface Computer{
void printComputer();
}
//工厂方法模式
interface ComputerFactory1{
Computer createComputer();
}
class MacBookComputer implements Computer{
public void printComputer(){
System.out.println("这是一台MacBook计算机");
}
}
class MacBookComputerFactory implements ComputerFactory1{
public Computer createComputer(){
return new MacBookComputer();
}
}
class LeiSheComputer implements Computer{
public void printComputer(){
System.out.println("这是一台LeiShe计算机");
}
}
class LeiSheComputerFactory implements ComputerFactory1{
public Computer createComputer(){
return new LeiSheComputer();
}
}
优点:
(1)降低了代码耦合度,对象的生成交给子类去完成;
(2)实现了开放封闭原则 —— 每次添加子产品 不需要修改原有代码;
缺点:
(1)增加了代码量,每个具体产品都需要一个具体工厂;
(2)当增加抽象产品 也就是添加一个其他产品族 需要修改工厂 违背OCP;
3.抽象工厂模式
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
工厂方法模式和抽象工厂模式基本类似,可以这么理解:当工厂只生产一个产品的时候,即为工厂方法模式,而工厂如果生产两个或以上的商品即变为抽象工厂模式。
我们在抽象工厂接口中新增创建系统的方法,并由实例工厂类去实现。
类图如下:
代码如下:
public class BuyComputer{
public void buy(Computer computer){
computer.printComputer();
}
//抽象工厂模式
public static void buy(Production production){
production.printInfo();
}
public static void main(String[] args){
BuyComputer client=new BuyComputer();
//ProductionFactory factory=new AppleFactory();
//Production production=factory;
//production.printInfo();
client.buy(new AppleFactory());
}
}
interface Production{
void printInfo();
}
interface Computer{
void printComputer();
}
interface OperatorSystem{
void printSystem();
}
//抽象工厂模式
interface ProductionFactory extends Production{
Computer createComputer();
OperatorSystem createSystem();
}
class MacBookComputer implements Computer{
public void printComputer(){
System.out.println("这是一台MacBook计算机");
}
}
class MacOs implements OperatorSystem{
public void printSystem(){
System.out.println("这是MacOs操作系统");
}
}
//apple的工厂
class AppleFactory implements ProductionFactory{
public Computer createComputer(){
return new MacBookComputer();
}
public OperatorSystem createSystem(){
return new MacOs();
}
public void printInfo(){
this.createComputer().printComputer();
this.createSystem().printSystem();
}
}
class LeiSheComputer implements Computer{
public void printComputer(){
System.out.println("这是一台LeiShe计算机");
}
}
class Windows implements OperatorSystem{
public void printSystem(){
System.out.println("这是Windows操作系统");
}
}
//MS的工厂
class MSFactory implements ProductionFactory{
public Computer createComputer(){
return new LeiSheComputer();
}
public OperatorSystem createSystem(){
return new Windows();
}
public void printInfo(){
this.createComputer().printComputer();
this.createSystem().printSystem();
}
}
优点:
(1)代码解耦;
(2)实现多个产品族(相关联产品组成的家族),而工厂方法模式的单个产品,可以满足更多的生产需求;
(3)很好的满足OCP开放封闭原则;
(4)抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类 对于复杂对象的生产;
(5)相当灵活易扩展;
缺点:
(1)扩展产品族相当麻烦 而且扩展产品族会违反OCP,因为要修改所有的工厂;
(2)由于抽象工厂模式是工厂方法模式的扩展 总体的来说 很笨重;