------- android培训、java培训、期待与您交流! ----------
* 装饰设计模式:当想要对已有的对象进行功能加强时,
* 可以自定义类,将已有的对象传入,基于已存在的功能,提供功能加强。
* 那么自定义类称之为装饰类。
*
* 装饰类特点:通常通过构造方法将被装饰的对象传入,并基于装饰对象已有的功能进行加强
* 例如:IO流中fileReader对象提供了read方法读取数据,
* 但它有个装饰类bufferedReader 提供了readLine()方法一行一行读取数据,在filereader对象功能上提供更强的读取数据方法,所以称之为装饰设计模式。
public class PersonDemo {
/**
* @author Administrator
*/
public static void main(String[] args) {
Person p=new Person();
supperPerson sPerson=newsupperPerson(p);
sPerson.supperChifan();
}
}
class Person{
public void chifan(){
System.out.println("吃饭吃饭");
}
}
//自定义类,对被装饰类的对象功能进行加强
class supperPerson{
private Person p;//定义被装饰对象
//通过构造方法将被装饰的对象传入
public supperPerson(Person p){
this.p=p;
}
//对被装饰对象功能进行加强
public void supperChifan(){
System.out.println("喝点小酒");
p.chifan();
System.out.println("那就开始吃饭吧");
}
}
继承与装饰模式
继承:是使用已存在的类的定义作为基础建立新的类。新类可以增加数据或新的功能,也可以使用父类的方法,但不能选择性的继承父类。优点:提高了代码的重用行,降低了项目开发周期。
装饰模式:对已有的对象的功能进行加强。特点:通常通过构造函数将被增强的对象传入,并基于被装饰(增强对象)已有的功能加强。
myReader--------专门用于读取数据的类
|---MyTextReader
|--MyBufferTextReader
|---MyMediaReader
|--MyBufferMediaReader
上面这种体系说明:myReader下有MyTextReader,MyMediaReader两个子类。MyTextReader下有MyBufferTextReader子类,提供更高效率读取数据的子类,同理MyMediaReader也是一样。因此我们发现如果myreader下有多个子类的话,那么每个子类下都有提供更高效率读取数据的子类。所以这样显得代码有些臃肿。
于是我们把所有提高读取数据效率的类全部抽取出来,MuBufferReader。
classMyBufferReader{
private MyTextReader text;
private MyMediaReader media;
.............
MyBufferReader(MyTextReader text){}
MyBufferReader(MyMediaReader media){}
.............
}
上面这种我们也发现如果存在多个读取数据的类,那么这里将会有多个构造函数将被增加的对象传入.因此发现这样扩展性极差。
如何提高扩展性呢?? --------找到参数的共同类型,通过多态的形式,可以提高扩展性。
class MyBufferReaderextends MyReader{
private MyReader r;
MyBufferReader(MyReader r){}//这就是运用装饰设计模式特征,将被增强的对象通过构造函数传入。
}
因为MyTextReader MyMediaReader 都属于myReader的子类,所以现在结构体系如下:
myReader--------专门用于读取数据的类
|---MyTextReader
|---MyMediaReader
|---MyBufferReader
总结:装饰模式比继承更灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提高了更强的功能,所以装饰类和被装饰类属于一个体系中。
享元设计模式:flyweight
概念:如果很多很小的对象他们有很多相同的东西,那么就可以把他们变成一个对象。还有一些不同的东西,可以作为方法的属性作外部参数的形式传入。称之为外部状态。相同的属性称之为内部状态。
也就是说:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说(这里引用GOF书中的例子)一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象。如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了。那么如果要是每个字母都共享一个对象,那么就大大节约了资源。
比如说,一个咖啡店有几种口味的咖啡(拿铁、摩卡、卡布奇诺等等),如果这家店接到分订单要几十杯咖啡。那么显然咖啡的口味就可以设置成共享的,而不必为每一杯单独生成。代码实现如下:
importjava.util.*;
public abstractclass Order {
// 执行卖出动作
public abstract void sell();
}
public classFlavorOrder extends Order {
public String flavor;
// 获取咖啡口味
public FlavorOrder(String flavor) {
this.flavor = flavor;
}
@Override
public void sell() {
// TODO Auto-generated method stub
System.out.println("卖出一份" + flavor + "的咖啡。");
}
}
public classFlavorFactory {
private Map<String, Order> flavorPool = new HashMap<String,Order>();
// 静态工厂,负责生成订单对象
private static FlavorFactory flavorFactory = new FlavorFactory();
privateFlavorFactory() {
}
public staticFlavorFactory getInstance() {
return flavorFactory;
}
public OrdergetOrder(String flavor) {
Order order = null;
if(flavorPool.containsKey(flavor)) {// 如果此映射包含指定键的映射关系,则返回 true
order = flavorPool.get(flavor);
}else {
order = new FlavorOrder(flavor);
flavorPool.put(flavor, order);
}
return order;
}
public intgetTotalFlavorsMade() {
return flavorPool.size();
}
}
public classClient {
// 客户下的订单
private static List<Order> orders = new ArrayList<Order>();
// 订单对象生成工厂
private static FlavorFactory flavorFactory;
// 增加订单
private static void takeOrders(String flavor) {
orders.add(flavorFactory.getOrder(flavor));
}
public staticvoid main(String[] args) {
// 订单生成工厂
flavorFactory = FlavorFactory.getInstance();
//增加订单
takeOrders("摩卡");
takeOrders("卡布奇诺");
takeOrders("香草星冰乐");
takeOrders("香草星冰乐");
takeOrders("拿铁");
takeOrders("卡布奇诺");
takeOrders("拿铁");
takeOrders("卡布奇诺");
takeOrders("摩卡");
takeOrders("香草星冰乐");
takeOrders("卡布奇诺");
takeOrders("摩卡");
takeOrders("香草星冰乐");
takeOrders("拿铁");
takeOrders("拿铁");
//卖咖啡
for (Order order : orders) {
order.sell();
}
//打印生成的订单java对象数量
System.out.println("\n客户一共买了 " + orders.size() + " 杯咖啡! ");
//打印生成的订单java对象数量
System.out.println("共生成了 " +flavorFactory.getTotalFlavorsMade()
+ " 个 FlavorOrder java对象! ");
}
}
打印结果:
卖出一份摩卡的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份拿铁的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份拿铁的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份摩卡的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份卡布奇诺的咖啡。
卖出一份摩卡的咖啡。
卖出一份香草星冰乐的咖啡。
卖出一份拿铁的咖啡。
卖出一份拿铁的咖啡。
客户一共买了 15 杯咖啡!
共生成了 4 个 FlavorOrderjava对象!
正如输入结果对比所示,把口味共享极大减少了对象数目,减小了内存消耗。
------- android培训、java培训、期待与您交流! ----------