梦想中的我自己,身价过亿,有两个大公司,一个是房地产公司,一个是服装制造公司,其实是什么公司我倒是不关心,我关心的是它赚不赚钱,赚了多少,这才是我关心的。先用类图表示一下我这两个公司:
代码如下:
public abstract class Corp {
protected abstract void product();
protected abstract void sell();
/**
* 先生产,再销售
*/
public void makeMoney() {
this.product();
this.sell();
}
}
public class HouseCorp extends Corp {
@Override
protected void product() {
System.out.println("承建XX市XX小区...");
}
@Override
protected void sell() {
System.out.println("首付20万,海景别墅任意挑!");
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("房地产公司赚大钱咯!");
}
}
public class ClothCorp extends Corp {
@Override
protected void product() {
System.out.println("低奢新品牌服饰首发...");
}
@Override
protected void sell() {
System.out.println("买两件一件!");
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("服装公司赚小钱...");
}
}
两个公司都有了,我肯定会关心两个公司的运营情况,我要知道它是生产什么的,赚多少钱,Client代码如下:
public class Client {
public static void main(String[] args) {
System.out.println("-------房地产公司是这个样子运行的-------");
HouseCorp houseCorp = new HouseCorp();
houseCorp.makeMoney();
System.out.println();
System.out.println("-------服装公司是这样运行的-------");
ClothCorp clothCorp = new ClothCorp();
clothCorp.makeMoney();
}
}
运行结果:
-------房地产公司是这个样子运行的-------
承建XX市XX小区...
首付20万,海景别墅任意挑!
房地产公司赚大钱咯!
-------服装公司是这样运行的-------
低奢新品牌服饰首发...
买两件一件!
服装公司赚小钱...
我发现,服装公司赚的小钱满足不了我,我打算把服装公司改为IPad公司,修改类图如下:
IPad公司的代码如下:
public class IPadCorp extends Corp {
@Override
protected void product() {
System.out.println("新IPad配置大升级!");
}
@Override
protected void sell() {
System.out.println("新IPad6期分期免息,还在等什么?");
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("苹果的产品果然赚钱!");
}
}
为了查看公司运营情况,还需要修改Client的代码:
public class Client {
public static void main(String[] args) {
System.out.println("-------房地产公司是这个样子运行的-------");
HouseCorp houseCorp = new HouseCorp();
houseCorp.makeMoney();
System.out.println();
System.out.println("-------服装公司是这样运行的-------");
IPadCorp ipadCorp = new IPadCorp();
ipadCorp.makeMoney();
}
}
确实,只用修改了几句话,我的服装厂就开始变成iPad生产车间,但是我制造了IPad,就不能制造服装了啊,那我以后想要制造MP4,改装后我的IPad就不能生产了啊,这样不行,成本太高了,于是我们修改一下类图:
代码如下:
/**
* 整个公司的产品类
*/
public abstract class Product {
public abstract void beProducted();
public abstract void beSelled();
}
/**
* 公司盖的房子
*/
public class House extends Product {
@Override
public void beProducted() {
System.out.println("承建XX市XX小区...");
}
@Override
public void beSelled() {
System.out.println("首付20万,海景别墅任意挑!");
}
}
/**
* 公司制造的服装
*/
public class Cloth extends Product {
@Override
public void beProducted() {
System.out.println("低奢新品牌服饰首发...");
}
@Override
public void beSelled() {
System.out.println("买两件送一件!");
}
}
/**
* 公司制造的IPad
*/
public class IPad extends Product {
@Override
public void beProducted() {
System.out.println("新IPad配置大升级!");
}
@Override
public void beSelled() {
System.out.println("新IPad6期分期免息,还在等什么?");
}
}
/**
* 公司的抽象类
*/
public abstract class Corp {
// 定义一个产品对象,具体是什么还不知道
private Product product;
// 构造函数,由子类定义传递具体的产品进来
public Corp(Product product) {
this.product = product;
}
// 赚钱的方式肯定都是一样的
public void makeMoney() {
this.product.beProducted();
this.product.beSelled();
}
}
/**
* @description: 房地产公司盖房子
*/
public class HouseCorp extends Corp {
public HouseCorp(House house) {
super(house);
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("房地产公司赚大钱咯!");
}
}
/**
* @description: 制造公司搞制造,具体生产什么还不知道
*/
public class MakeCrop extends Corp {
/**
* 制造什么产品,等被调用的时候才知道
*/
public MakeCrop(Product product) {
super(product);
}
@Override
public void makeMoney() {
super.makeMoney();
System.out.println("造啥都能赚钱!");
}
}
HouseCorp类和MakeCorp类的区别是在有参构造的参数类型上,HouseCorp类比较明确,我就是只要House类,所以直接定义传递进来的必须是House类,一个类尽可能少的承担职责,那方法也是一样,既然HouseCorp类已经非常明确只生产House产品,那为什么不定义成House类型呢?MakeCorp就不同了,它是确定不了生产什么类型。
Client代码如下:
public class Client {
public static void main(String[] args) {
System.out.println("-------房地产公司是这个样子运行的-------");
House house = new House();
HouseCorp houseCorp = new HouseCorp(house);
houseCorp.makeMoney();
System.out.println();
System.out.println("-------制造公司是这样运行的-------");
MakeCorp makeCorp = new MakeCorp(new Cloth());
makeCorp.makeMoney();
}
}
运行结果:
-------房地产公司是这个样子运行的-------
承建XX市XX小区...
首付20万,海景别墅任意挑!
房地产公司赚大钱咯!
-------制造公司是这样运行的-------
低奢新品牌服饰首发...
买两件送一件!
造啥都能赚钱!
而现在想让制造公司制造IPad,这就非常简单了,代码如下:
public class Client {
public static void main(String[] args) {
System.out.println("-------房地产公司是这个样子运行的-------");
House house = new House();
HouseCorp houseCorp = new HouseCorp(house);
houseCorp.makeMoney();
System.out.println();
System.out.println("-------制造公司是这样运行的-------");
// 把制造服装的公司改为制造IPad就这么简单
// MakeCorp makeCorp = new MakeCorp(new Cloth());
MakeCorp makeCorp = new MakeCorp(new IPad());
makeCorp.makeMoney();
}
}
看上面的代码,就修改了一句代码就完成了生产产品的转换。我们深入的思考一下,我现在只有房地产公司和制造公司,以后我还要开其他公司这么办?新增加公司对我们上面的类图没有大的修改,充其量是扩展:
- 增加公司,要么继承Corp类,要么继承HouseCorp或MakeCorp,不用再修改原有的类了;
- 增加产品,继承Product类,或者继承House类,你要把房子分为公寓房、别墅、商业用房等等;
你都是在扩展,唯一你要修改的就是Client类,也就是说Corp类和Product类都可以自由的扩展,而不会对整个应用产生太的变更,这就是桥梁模式。
为什么叫桥梁模式?我们看一下桥梁模式的通用类图:
看到中间那根带箭头的线了吗?是不是类似一个桥,连接了两个类?所以就叫桥梁模式。
我们再把桥梁模式的几个概念熟悉一下,我把Corp类以及它的两个实现类放到了Abstraction包中,把House以及相关的三个实现类放到了Implementor包中,这两个包分别对应了桥梁模式的业务抽象角色(Abstraction)和业务实现角色(Implementor),这两个角色大家只要记住一句话就成:业务抽象角色引用业务实现角色,或者说业务抽象角色的部分实现是由业务实现角色完成的,很简单,别想那么复杂了。
桥梁模式的优点就是类间解耦,我们上面已经提到,两个角色都可以自己的扩展下去,不会相互影响,这个也符合OCP原则。
本文原书:
《您的设计模式》 作者:CBF4LIFE
网友评论