java设计模式-每天三个设计模式之工厂、单例、建造者
前情提要
在上篇文章中介绍了面向对象程序设计的七个基本原则,分别是单一职责,里式替换、依赖注入、接口分离、迪米特原则、开闭原则、优先使用组合而不是继承原则。
本文重点
- 工厂模式
- 单例模式
- 建造者模式
工厂模式,工厂模式又分为简单工厂、工厂方法、抽象工厂。工厂模式要实现的是将使用者与具体实现分离。
1.简单工厂
角色:使用者,实例工厂(或者静态工厂),抽象产品和产品实现。类图如下
实现代码:
public class CarFactory{
public Car createCar(String name){
if("BMW".equals()){
return new BMW("BMW");
}
if("BENZ".equals()){
return new BENZ("BENZ");
}
}
}
public interface Car{
void run();
}
public class BMW implements Car{
private String name;
public BMW(String name){
this.name = name;
}
public void run(){
System.out.println(name + "开始行驶了...");
}
}
public class BENZ implements Car{
private String name;
public BENZ(String name){
this.name = name;
}
public void run(){
System.out.println(name + "开始行驶了...");
}
}
public class Driver{
public void drive(){
Car bmw = CarFactory.createCar("BMW");
Car benz = CarFactory.createCar("BENZ");
bmw.run();
benz.run();
}
}
使用场景
代替new产生对象时,产品的类型比较少时。
缺点
不符合开闭原则,当新加产品类型的时候,就需要修改工厂中的创建的代码。
工厂方法模式:
角色:抽象工厂,抽象工厂实现,抽象产品,产品,使用者
类图,略。
代码实现:
public class ICarFactory{
Car createBMWCar();
Car createBENZCar();
}
public class CarFactory implements ICarFactory{
public Car createBMWCar(){
return new BMW("BMW");
}
public Car createBENZCar(){
return new BENZ("BENZ");
}
}
public interface Car{
void run();
}
public class BMW implements Car{
private String name;
public BMW(){
this.name = "BMW";
}
public void run(){
System.out.println(name + "开始行驶了...");
}
}
public class BENZ implements Car{
private String name;
public BENZ(){
this.name = "BENZ";
}
public void run(){
System.out.println(name + "开始行驶了...");
}
}
public class Driver{
public void drive(){
Car bmw = CarFactory.createBMWCar();
Car benz = CarFactory.createBENZCar();
bmw.run();
benz.run();
}
}
这样修改简单工厂之后就可以满足开闭原则了。
使用场景:系统产品包含多个产品族,每个产品族又有一系列产品,每次系统只使用一种产品族的产品。
主要缺点:产品族扩展比较难,需要修改的地方较多。
抽象工厂模式
角色:同工厂方法
类图:略
实现代码:
public interface PCFactory{
Cpu createCpu(String name);
KeyBoard createKeyBoard(String name);
}
LenovoPCFactory implements PCFactory{
public Cpu createCpu(){
return LenovoCPU();
}
public KeyBoard createKeyBoard (){
return LenovoKeyBoard ();
}
}
MACPCFactory implements PCFactory{
public Cpu createCpu(){
return MACCPU();
}
public KeyBoard createKeyBoard (){
return MACKeyBoard ();
}
}
public interface Cpu{
}
public class LenovoCpu implements Cpu{
}
public class MACCpu implements Cpu{
}
public interface KeyBoard{
}
public class LenovoKeyBoard implements KeyBoard{
}
public class MACKeyBoard implements KeyBoard{
}
public class Test{
public static void main(String[] args){
MACPCFactory.createCpu();
LenovoPCFactory.createCpu();
LenovoPCFactory.createKeyBoard();
MACPCFactory.createKeyBoard();
}
}
单例模式:
使用场景:全局只需要一个该对象,该对象的初始化比较耗费资源。
代码实现:
饿汉式:
public class Single{
private static final Single instance = new Single();
private Single(){
}
public static final Single getInstance(){
return instance;
}
}
懒汉式:
public class Single{
private volatile Single instance;
public Single(){
if(instance == null){
synchronized(this){
instance = new Single();
}
}else{
return instance;
}
}
public static final Single getInstance(){
return instance;
}
}
内部类同时具备饿汉式和懒汉式有点的实现
public class Single{
private Single(){
}
//静态内部类由虚拟机负责线程安全
private static class SingleHolder{
private static final Single instance = new Single();
}
public static final Single getInstance(){
return SingleHolder.instance;
}
}
建造者模式:
使用场景:如果一个对象比较的复杂,又比较关注产品构造的细节。与工厂模式的主要区别是工厂模式关注产品整体,也就是说只要造出产品即可,通常产品的属性比较少;而建造模式关注产品制造的细节,属性比较多复杂。
代码实现:
public interface Packing {
public String pack();
}
public interface Item {
public String name();
public Packing packing();
public float price();
}
public interface Item {
public String name();
public Packing packing();
public float price();
}
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
public class MealBuilder {
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
public class Test {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " +nonVegMeal.getCost());
}
}
其中建造者模式代码引用http://www.runoob.com/design-pattern/builder-pattern.html一节建造者模式。