设计模式之建造者模式/生成器模式

生活中我们会常常遇到这样的情况,买一套房子可以有不同的设计与档次,制造同一品牌的电脑也有不同的配置,去吃肯德基也有不同的套餐。房子,电脑,肯德基都是具体的物体,但是却有不同种的配件组成,遇到这样的事物,我们常常需要使用建造者模式或者叫生成器模式。
建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节
以肯德基为例:

在这里插入图片描述
首先写个meal类:

public class Meal
{
	//food和drink是部件
	private String food;
	private String drink;
	
	public void setFood(String food) {
		this.food = food; 
	}

	public void setDrink(String drink) {
		this.drink = drink; 
	}

	public String getFood() {
		return (this.food); 
	}

	public String getDrink() {
		return (this.drink); 
	}
}

再写个创造meal的抽象类,并使两种不同的meal套餐的创造实现该抽象类。

public abstract class MealBuilder
{
	protected Meal meal=new Meal();
	public abstract void buildFood();
	public abstract void buildDrink();
	public Meal getMeal()
	{
		return meal;
	}
}
public class SubMealBuilderA extends MealBuilder
{
	public void buildFood()
	{
		meal.setFood("一个鸡腿堡");
	}
	public void buildDrink()
	{
	    meal.setDrink("一杯可乐");
	}
}  
public class SubMealBuilderB extends MealBuilder
{
	public void buildFood()
	{
		meal.setFood("一个鸡肉卷");
	}
	public void buildDrink()
	{
		 meal.setDrink("一杯果汁");
	}
}

再写一个kfcwaiter类,该类操控着整个大局。根据顾客的需要,提供不同的套餐。但并不是由kfcwaiter亲自做的。

public class KFCWaiter
{
	private MealBuilder mb;
	public void setMealBuilder(MealBuilder mb)
	{
		this.mb=mb;
	}
	public Meal construct()
	{
		mb.buildFood();
		mb.buildDrink();
		return mb.getMeal();
	}
}

通过配置文件使用反射技术为顾客类提供具体套餐
config.xml

<?xml version="1.0"?>
<config>
    <className>SubMealBuilderB</className>
</config>

XMLUtil.java

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil
{
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
	public static Object getBean()
	{
		try
		{
			//创建文档对象
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;							
			doc = builder.parse(new File("config.xml")); 
		
			//获取包含类名的文本节点
			NodeList nl = doc.getElementsByTagName("className");
            Node classNode=nl.item(0).getFirstChild();
            String cName=classNode.getNodeValue();
            
            //通过类名生成实例对象并将其返回
            Class c=Class.forName(cName);
	  	    Object obj=c.newInstance();
            return obj;
           }   
           	catch(Exception e)
           	{
           		e.printStackTrace();
           		return null;
           	}
		}
}

Client.java

public class Client
{
	public static void main(String args[])
	{
		//动态确定套餐种类
	    MealBuilder mb=(MealBuilder)XMLUtil.getBean();
	  //服务员是指挥者
		KFCWaiter waiter=new KFCWaiter();
		//服务员准备套餐
	    waiter.setMealBuilder(mb);
	    //客户获得套餐
	    Meal meal=waiter.construct();
        
        System.out.println("套餐组成:");
        System.out.println(meal.getFood());
        System.out.println(meal.getDrink());
        
	}
}

结果:套餐组成:
一个鸡肉卷
一杯果汁

发布了56 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hpccph15/article/details/82779555