桥接模式
姓名:陈阳
学号:07770114
一、模式信息
模式名称:桥接模式
生活场景:考虑一个售楼小区不同的建筑面积、不同楼层的每平米造价成本是不同的。同一建筑面积的屋子,有楼层的高低之分。而同一楼层也会有建筑面积不一样的屋子
终极目标:实现适应于扩充到对各种建筑面积的屋子和各种楼层进行建模的情形。
1.不假思索的思路:通过类继承的方式来做上面的例子。即:先建立楼层类;然后派生出高楼层类、矮楼层类;然后再高楼层类和矮楼层类上分别派生出:大面积房屋类和小面积房屋类。
类结构图:
代码浏览:
loufang.java
public class loufang {
public void loufang(){
String str="楼房";
}
}
gaoloufang.java
public class gaoloufang extends loufang {
public void loufang(){
String str="这是高楼层";
}
}
ailoufang.java
public class ailoufang extends loufang{
public void loufang(){
String str="这是矮楼层";
}
}
glfdwuzi.java
public class glfdwuzi extends gaoloufang{
public void loufang(){
String str="高楼层的大屋子的造价是~~~";
}
}
glfxwuzi.java
public class glfxwuzi extends gaoloufang{
public void loufang(){
String str="高楼层的小屋子的造价是~~~";
}
}
alfdwuzi.java
public class alfdwuzi extends ailoufang{
public void loufang(){
String str="低楼层的大屋子的造价是~~~";
}
}
alfxwuzi.java
public class alfxwuzi extends ailoufang{
public void loufang(){
String str="低楼层的小屋子的造价是~~~";
}
}
存在问题:
1.它在遵循开放-封闭原则的同时,违背了类的单一职责原则,即一个类只有一个引起它变化的原因,而这里引起变化的原因却有两个,即楼层高度类型的变化和房屋面积类型的变化;
2.重复代码会很多,不同的房屋面积在不同的楼层的售价也会有一部分的代码是相同的;
3.类的结构过于复杂,继承关系太多,难于维护;
4.最致命的一点是扩展性太差。如果变化沿着房屋面积的类型和不同的楼层两个方向变化,我们会看到这个类的结构会迅速的变庞大。
2.归纳阶段
归纳步骤一
当前目标:实现房屋面积和楼层的二维度特征类的建立。
思路:通过对象组合的方式,把两个角色之间的继承关系改为了耦合的关系,从而使这两者可以从容自若的各自独立的变化,这就是Bridge模式的本意。
类结构图:
代码浏览:
ArchitectureCost.java
public abstract class ArchitectureCost {//建立抽象者 ArchitectureCose
BuildingDesign design;
double unitPrice;
public abstract double giveCost();
}
BuildingDesign.java
public interface BuildingDesign {
public double computerArea(); //定义实现者的接口
}
BuildingCost.java
public class BuildingCost extends ArchitectureCost{
BuildingCost (BuildingDesign design,double unitPrice){
this.design = design;
this.unitPrice = unitPrice;
}
public double giveCost(){
double area = design.computerArea();
return area*unitPrice;
}
}
HouseDesign.java
public class HouseDesign implements BuildingDesign{
double width,length;
int floorNumber;
HouseDesign(double width,double length,int floorNumber){
this.width=width;
this.length=length;
this.floorNumber=floorNumber;
}
public double computerArea() {
return width * length * floorNumber;
}
}
Application.java
public class Application {
public static void main(String[] args) {
double width = 63, height = 30;
int floorNumber = 8;
double unitPrice = 6867.38;
BuildingDesign design = new HouseDesign(width, height, floorNumber);
System.out
.println("宽" + width + "米,高" + height + "米,层数为" + floorNumber);
ArchitectureCost cost = new BuildingCost(design, unitPrice);
double price = cost.giveCost();
System.out.printf("每平方米造价:" + unitPrice + "元的商业楼的建设成本:%.2f元\n", price);
}
}
设计体会:(如果还有归纳步骤2,此处应该写存在问题!总之,最后的归纳才写设计体会)
1.Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得不同楼层的不同面积的房屋的每平米造价以及建设成本。
3.Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
4.Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。
3.验证阶段:
当前目标:增加一个人的特征维度,证明该模式的适用性;
类结构图:
代码浏览:
Application.java
public class Application {
public static void main(String[] args) {
width = 52;
height = 28;
floorNumber = 6;
unitPrice = 2687.88;
design = new HouseDesign(width, height, floorNumber);
System.out
.println("宽" + width + "米,高" + height + "米,层数为" + floorNumber);
cost = new BuildingCost(design, unitPrice);
price = cost.giveCost();
System.out.printf("每平方米造价:" + unitPrice + "元的商业楼的建设成本:%.2f元\n", price);
}
}
验证结论:
代码浏览:
public class HouseDesign implements BuildingDesign{
double width,length;
int floorNumber;
int windownum;
HouseDesign(double width,double length,int floorNumber,int windownum){
this.width=width;
this.length=length;
this.floorNumber=floorNumber;
this.windownum=windownum;
}
public double computerArea() {
return (width * length * floorNumber*(10+windownum))/10;
}
}
public class Application {
public static void main(String[] args) {
double width = 63, height = 30;
int floorNumber = 8;
double unitPrice = 6867.38;
int windownum=7;
BuildingDesign design = new HouseDesign(width, height, floorNumber,windownum);
System.out
.println("宽:" + width + "米,高:" + height + "米,层数为:" + floorNumber + ",窗户数为:" + windownum + "个");
ArchitectureCost cost = new BuildingCost(design, unitPrice);
double price = cost.giveCost();
System.out.printf("每平方米造价:" + unitPrice + "元的商业楼的建设成本:%.2f元\n", price);
width = 52;
height = 28;
floorNumber = 6;
unitPrice = 2687.88;
windownum = 9;
design = new HouseDesign(width, height, floorNumber,windownum);
System.out
.println("宽:" + width + "米,高:" + height + "米,层数为:" + floorNumber + ",窗户数为:" + windownum + "个");
cost = new BuildingCost(design, unitPrice);
price = cost.giveCost();
System.out.printf("每平方米造价:" + unitPrice + "元的商业楼的建设成本:%.2f元\n", price);
}
}