java设计模式设计原理_JAVA设计模式讲解(原理+实例)——装饰模式

首先看一个具体例子

代码类之间的关系如下:

19fd00025f7953929999.jpg

解释:第一部分,是父类,之所以要这个父类是因为Mocha或者soy内部持有一个父类的引用,只有持有这个引用,才可以既覆盖父类(通过继承)的方法又装饰父类(通过调用父类的引用的相同的方法(不同的方法也可以调))的方法。第二部分,就是已经实现了父类大部分方法的子类,也就是被装饰的类(通过Mocha和Soy来增强)。第三部分,一个装饰器,用来表述哪些方法需要子类去实现(抽象类)。第四部分,装饰第二部分的类,可以在第二部分类的基础上,进行二次开发。

接下来看下官方的类图:

19ff000241b6ca733dda.jpg

官方装饰模式类图

可以看出,和我们的例子差不多。

废话不多说,直接上代码。

Beverage:

public abstract class Beverage {

protected String description = "Unknown Beverage";

public String getDescription() {

return description;

}

public abstract double cost();

}

DarkRoast:

public class DarkRoast extends Beverage {

public DarkRoast() {

description = "DarkRoast";

}

public double cost() {

return .99;

}

}

CondimentDecorator:

public abstract class CondimentDecorator extends Beverage {

public abstract String getDescription();

}

Mocha:

public class Mocha extends CondimentDecorator {

Beverage beverage;

public Mocha(Beverage beverage) {

this.beverage = beverage;

}

public String getDescription() {

return beverage.getDescription() + ", Mocha";

}

public double cost() {

return .20 + beverage.cost();

}

}

Whip:

public class Whip extends CondimentDecorator {

Beverage beverage;

public Whip(Beverage beverage) {

this.beverage = beverage;

}

public String getDescription() {

return beverage.getDescription() + ", Whip";

}

public double cost() {

return .10 + beverage.cost();

}

}

main主函数:

Beverage beverage2 = new DarkRoast();

beverage2 = new Mocha(beverage2);

//这里传入的beverage2不是Beverage beverage2 = new DarkRoast();而是经过修饰后的 beverage2 = new Mocha(beverage2);每次传入的都是经过修饰后的

beverage2 = new Mocha(beverage2);

beverage2 = new Whip(beverage2);

System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

输出结果:

DarkRoast, Mocha, Mocha, Whip $1.49

运行过程如下图所示:

19fd0002660c44a23416.jpg

运行过程1

下面解释下:第一次new DarkRoast();的时候beverage2指向堆中的DarkRoast;

第二次beverage2 = new Mocha(beverage2)(第一个Mocha中有个成员变量Beverage beverage;),Mocha中的成员变量beverage指向了之前的beverage2,由于beverage2指向DarkRoast,也就是说Mocha中的成员变量beverage也指向DarkRoast。

再次,beverage2 = new Mocha(beverage2),第二个Mocha中的成员变量beverage也指向之前的beverage2 ,由于beverage2 还是指向第一个Mocha,所以第二个Mocha中的beverage也指向第一个Mocha,这里之所以都可以指向Mocha或者beverage2是因为他们发父类型是一样的。

最后,beverage2 = new Whip(beverage2);原理也是一样。其实,这里的beverage2只是用来接收不同的对象,保持一个引用。也可以每次都使用一个新的Beverage beverageNew来接收,这样的话,每次传入的就是这个新的beverageNew。使用每次new一个新对象的流程图如下:

19fe000253f8759ce9b1.jpg

运行过程2

打印结果也是一样。

当然,也可以这样写代码:

Beverage beverage2 = new DarkRoast();

beverage2 = new Whip(new Mocha(new Mocha(beverage2)));

System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

这样写的代码的流程图其实就是少了两条指向new出来的Mocha对象的虚线。

好了,java装饰模式到此讲完了。下一篇继续模式之路。。。喜欢请关注作者。谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多例设计模式是单例模式的一种变体。它允许创建有限数量的实例,而不是像单例模式一样只创建一个实例。在Java多例模式中,每个实例都有一个唯一的名称,以便在需要时可以使用。 下面是一个Java多例模式的示例代码: ```java public class Database { private static Map<String, Database> instances = new HashMap<String, Database>(); private String name; private Database(String name) { this.name = name; } public static synchronized Database getInstance(String name) { if (!instances.containsKey(name)) { instances.put(name, new Database(name)); } return instances.get(name); } public String getName() { return name; } } ``` 在这个示例中,我们创建了一个名为Database的类,它有一个私有构造函数和一个静态的getInstance方法,该方法根据名称获取或创建一个实例。我们使用一个Map来存储实例,以便在需要时可以检索它们。如果需要创建一个新的实例,我们将它添加到Map中。 以下是一个使用多例模式创建数据库实例的示例: ```java Database db1 = Database.getInstance("db1"); Database db2 = Database.getInstance("db2"); Database db3 = Database.getInstance("db1"); System.out.println(db1.getName()); // Output: db1 System.out.println(db2.getName()); // Output: db2 System.out.println(db3.getName()); // Output: db1 ``` 在这个示例中,我们创建了三个Database实例,其中两个具有不同的名称,但具有相同的名称的实例是相同的。我们使用getName方法来检索实例的名称,并验证它们是否正确。 总的来说,Java多例模式是一个灵活和有用的设计模式,允许我们创建有限数量的实例,并根据需要使用它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值