源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

java设计模式之建造者模式学习

  • 时间:2020-05-21 20:14 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:java设计模式之建造者模式学习
1 概述 建造者模式(Builder Pattern)主要用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。因此, 建造者模式主要用来解决“对象部分”的需求变化。 这样可以对对象构造的过程进行更加精细的控制。 2 示例 以生产手机为例,每个手机分为屏幕Screen、CPU、Battery。现在要生产两种手机,苹果机和三星。  苹果:  
[u]复制代码[/u] 代码如下:
 package org.scott.builder.before.use; import java.util.ArrayList; import java.util.List; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class ApplePhone {     List<String> parts = new ArrayList<String>();     public void createCPU() {         parts.add("CUP: Qualcomm");     }     public void createScreen() {         parts.add("SCREEN: JDI");     }     public void createBattery() {         parts.add("BATTERY: DeSai");     }     public void show(){         System.out.print("产品部件信息:");         for(String part : parts){             System.out.print(part + "\t");         }     } }  
 三星:  
[u]复制代码[/u] 代码如下:
 package org.scott.builder.before.use; import java.util.ArrayList; import java.util.List; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class SamsungPhone {     List<String> parts = new ArrayList<String>();     public void createCPU() {         parts.add("CUP: MTK");     }     public void createScreen() {         parts.add("SCREEN: Samsung");     }     public void createBattery() {         parts.add("BATTERY: DeSai");     }     public void show(){         System.out.print("产品部件信息:");         for(String part : parts){             System.out.print(part + "\t");         }     } }  
测试客户端:
[u]复制代码[/u] 代码如下:
package org.scott.builder.before.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class BuilerTest {     private static ApplePhone iphone = new ApplePhone();     private static SamsungPhone samPhone = new SamsungPhone();     public static void main(String args[]){         iphone.createCPU();         iphone.createScreen();         iphone.createBattery();         iphone.show();         samPhone.createCPU();         samPhone.createScreen();         samPhone.createBattery();         samPhone.show();     } }
是不是发现个问题?那就是生产手机的每一道工序都是一样的,确切的说是工序名称一样,只是具体的每个工序的处理不同,工序是不变的,就这么几步,每道工序的具体处理是变化的,由此,我们可以把不变的抽取出来,以“不变应万变”,将变化的,交给具体的产品来做。 具体怎么做?这回的Builder模式派上用场了。 首先来个Phone的接口:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; import java.util.ArrayList; import java.util.List; /**  * @author Scott  * @version 2013-11-20  * @description  */ public abstract class Phone {     protected List<String> parts = new ArrayList<String>();     public void add(String part){         parts.add(part);     }     public void show(){         System.out.print("产品部件信息:");         for(String part : parts){             System.out.print(part + "\t");         }     } }
苹果手机类:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class ApplePhone extends Phone{ }
三星手机类:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class SamsungPhone extends Phone{ }
再定义个生产步骤的接口Builder:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public interface Builder {     public void buildCPU();     public void buildScreen();     public void buildBattery();     public Phone getPhone(); }
苹果手机的Builder:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class ApplePhoneBuilder implements Builder{     private Phone phone = new ApplePhone();     @Override     public void buildCPU() {         phone.add("CUP: Qualcomm");     }     @Override     public void buildScreen() {         phone.add("SCREEN: JDI");     }     @Override     public void buildBattery() {         phone.add("BATTERY: DeSai");     }     @Override     public Phone getPhone() {         return phone;     } }
三星手机的Builder:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class SamsungPhoneBuilder implements Builder{     private Phone phone = new SamsungPhone();     @Override     public void buildCPU() {         phone.add("CUP: MTK");            }     @Override     public void buildScreen() {         phone.add("SCREEN: Samsung");     }     @Override     public void buildBattery() {         phone.add("BATTERY: DeSai");            }     @Override     public Phone getPhone() {         return phone;     } }
指导具体生产手机的Director:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class Director {     private Builder builder;     public Director(Builder builder){         this.builder = builder;     }     public void construct(){         builder.buildCPU();         builder.buildScreen();         builder.buildBattery();     } }
最后写个测试类:
[u]复制代码[/u] 代码如下:
package org.scott.builder.after.use; /**  * @author Scott  * @version 2013-11-20  * @description  */ public class BuilderTest {     private static Builder iPhoneBuilder = new ApplePhoneBuilder();     private static Builder samPhoneBuilder  = new SamsungPhoneBuilder();     public static void main(String[] args) {         Director director = new Director(iPhoneBuilder);         director.construct();         Phone phone = iPhoneBuilder.getPhone();         System.out.println("iphone");         phone.show();         director = new Director(samPhoneBuilder);         director.construct();         phone = samPhoneBuilder.getPhone();         System.out.println("\nsamSung");         phone.show();     } }
运行结果:
[u]复制代码[/u] 代码如下:
iphone 产品部件信息:CUP: Qualcomm    SCREEN: JDI    BATTERY: DeSai    samSung 产品部件信息:CUP: MTK    SCREEN: Samsung    BATTERY: DeSai
这里的两个Phone实体类是空的,如果是这种情况,那么它们可以省略掉,如果 Phone接口也可以被省略掉,最终剩下的就只有 Director、Builder、和具体的 Bulider 实现类。并且,ApplePhone类和 SamsungPhone类是有关系的两个类,它们不同的手机品牌,如果遇到两个或多个没有太多关系的类,公共的接口Phone就没有存在的必要,但是这时候,那么 Builder 接口的规定的 getPhone() 方法的返回值怎么确定呢?   无论返回值类型是 ApplePhone还是SamsungPhone,都会产生问题,因为返回结果的类型不统一。此时,可以将 Phone定义成一个空接口(不包含任何方法的接口),再让这些没有相互关系的具体产品类都去实现这个接口,那么 Builder 接口里面规定的 getPhone() 方法的返回值类型依然是 Phone 类型,就解决问题了。不过这种情况下,也就没有使用Builder模式的必要了。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部