前言
本文介绍设计模式中的建造者模式,使用的程序实现了一个简单的汉堡套餐的售卖系统。
什么是建造者模式
建造者模式也是创建型模式的一种,其能够将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示
就按本文程序的例子来说,我们现在需要卖汉堡套餐,可是汉堡有牛肉堡、鸡肉堡、素堡等,饮料有咖啡、可乐、橙汁等,如果我们需要得到一个既有汉堡又有饮料的套餐时,就可以通过一个建造者类选择汉堡的种类和饮料的种类形成一个套餐。
本例的类图如下所示:
代码示例
1.Meal类
本例中,不同的汉堡饮料有不同的价格,名称以及包装。不同的组合形成了不同的套餐,所以我们有一个Meal类,可以看作是一个套餐类,其每个实例都是一种组合的套餐。类中使用了一个Items的List用来存放某一套餐中需要哪些食物。
该类中的addItem就是给这个套餐添加食品,例如添加牛肉堡时,就直接用一个实例m,通过m.addItem(new BeefBurger());即可。
代码如下所示(viewList方法中大部分是为了图形界面,该方法不重要)
package BuilderPattern;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
public class Meal extends JFrame {
JFrame jFrame1;
JLabel label1;
JTextArea textArea;
JButton button;
GridBagLayout bagLayout;
Meal(){
jFrame1 = new JFrame();
}
private List<Items> items = new ArrayList<>();
public void addItem(Items item){
items.add(item);
}
public double getTotalPrice(){
double totalPrice=0.0;
for (Items item : items){
totalPrice+=item.setPrice();
}
return totalPrice;
}
public void viewList(){
bagLayout = new GridBagLayout();
jFrame1.setLayout(bagLayout);
String food = "";
String drink = "";
for (Items item : items) {
if(item instanceof Burger){
food = food+item.setName()+" 包装为:"+item.setPack().pack()+" 价格:"+item.setPrice()+"\n";
}
else{
drink = drink+item.setName()+" 包装为:"+item.setPack().pack()+" 价格:"+item.setPrice()+"\n";
}
}
textArea = new JTextArea("食物:\n"+food+"\n饮料:\n"+drink+"\n总价:"+getTotalPrice());
label1 = new JLabel("点餐确认\n",JLabel.CENTER);
Font fnt = new Font("Serief",Font.ITALIC+Font.BOLD,30);
label1.setFont(fnt);
button = new JButton("确定");
button.setSize(50,30);
jFrame1.add(label1);
jFrame1.add(textArea);
jFrame1.add(button);
//jFrame1.setLayout(new GridLayout(7,1).);
jFrame1.setVisible(true);
jFrame1.setSize(500,300);
jFrame1.setLocation(100,100);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.gridwidth = 0;
gridBagConstraints.gridy=2;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 0;
bagLayout.setConstraints(label1,gridBagConstraints);
gridBagConstraints.gridwidth = 0;
gridBagConstraints.gridy=5;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 0;
bagLayout.setConstraints(textArea,gridBagConstraints);
gridBagConstraints.gridwidth = 0;
gridBagConstraints.gridy=7;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 0;
bagLayout.setConstraints(button,gridBagConstraints);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jFrame1.setVisible(false);
}
});
}
}
2.MealBuilder类
这个类就是一个创造者,其中的每个方法都对应的是一个套餐,方法中生成一个Meal实例,并通过上述的addItem方法添加该实例(也就是这个套餐)中的食品,最后返回这个套餐实例。最后在User类中只需要使用这个建造者类生成一个实例,在调用建造者类中的相应方法即可得到相应的套餐
代码如下所示
package BuilderPattern;
public class MealBuilder {
public Meal combo1(){
Meal meal = new Meal();
meal.addItem(new BeefBurger());
meal.addItem(new Coffee());
return meal;
}
public Meal combo2(){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Coffee());
return meal;
}
public Meal combo3(){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Milk());
return meal;
}
public Meal combo4(){
Meal meal = new Meal();
meal.addItem(new BeefBurger());
meal.addItem(new OrangeJuice());
return meal;
}
}
运行截图
项目完整代码可以去GitHub下载
链接:https://github.com/jianqiang-Zhang/DesignPattern
总结
建造者模式和之前的工厂模式都属于创建型模式,但是仔细研究就可以发现这两种设计模式适用的情景并不一样。当需要的某个东西是通过许多东西拼接起来时,并且其需要的东西还能细分种类,这是就可以适用建造者模式。例如当我们组装一台电脑,cpu、主板、显卡、内存等都可以选不同的品牌,就可以适用建造者模式进行设计,这样能使代码更加的高效。