7、装饰模式(Decorator)
装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例:
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Decorator implements Sourceable {
private Sourceable source;
public Decorator(Sourceable source){
super();
this.source = source;
}
@Override
public void method() {
System.out.println("before decorator!");
source.method();
System.out.println("after decorator!");
}
}
装饰器模式的应用场景:
1、需要扩展一个类的功能。
2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)
装饰模式,突出的是运行期增加行为,这和继承是不同的,继承是在编译期增加行为。
缺点:产生过多相似的对象,不易排错!
class Dumplings //抽象类 饺子
{
public:
virtual ~Dumplings(){}
virtual void showDressing() = 0;
};
class MeatDumplings:public Dumplings //现实类 肉馅饺子
{
public:
~MeatDumplings(){ cout << "~MeatDumplings()" << endl; }
void showDressing()
{
cout << "Add Meat" << endl;
}
};
class DecoratorDumpling:public Dumplings //装饰类
{
public:
DecoratorDumpling(Dumplings* d):m_dumpling(d){}
virtual ~DecoratorDumpling(){ cout << "~DecoratorDumpling()" << endl; }
void showDressing()
{
m_dumpling->showDressing();
}
private:
Dumplings* m_dumpling;
};
class SaltDecorator:public DecoratorDumpling // 装饰类 加盐
{
public:
SaltDecorator(Dumplings* d):DecoratorDumpling(d){}
~SaltDecorator(){ cout << "~SaltDecorator()" << endl; }
void showDressing()
{
DecoratorDumpling::showDressing(); //注意点
addDressing();
}
private:
void addDressing()
{
cout << "Add Salt" << endl;
}
};
class OilDecorator:public DecoratorDumpling //装饰类 加油
{
public:
OilDecorator(Dumplings* d):DecoratorDumpling(d){}
~OilDecorator(){ cout << "~OilDecorator()" << endl; }
void showDressing()
{
DecoratorDumpling::showDressing(); //注意点
addDressing();
}
private:
void addDressing()
{
cout << "Add Oil" << endl;
}
};
class CabbageDecorator:public DecoratorDumpling //装饰类 加蔬菜
{
public:
CabbageDecorator(Dumplings* d):DecoratorDumpling(d){}
~CabbageDecorator(){ cout << "~CabbageDecorator()" << endl; }
void showDressing()
{
DecoratorDumpling::showDressing(); //注意点
addDressing();
}
private:
void addDressing()
{
cout << "Add Cabbage" << endl;
}
};
int main()
{
Dumplings* d = new MeatDumplings; //原始的肉饺子
Dumplings* d1 = new SaltDecorator(d); //加盐后的饺子
Dumplings* d2 = new OilDecorator(d1); //加油后的饺子
Dumplings* d3 = new CabbageDecorator(d2); //加蔬菜后的饺子
d3->showDressing();
delete d;
delete d1;
delete d2;
delete d3;
return 0;
}
8、代理模式(Proxy)
代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。
主要解决:在直接访问对象时带来的问题,比如:要访问的对象在远程服务器上。在面向对象系统中,有些对象由于某些原因,直接访问会给使用者或系统带来很多麻烦,可以在访问此对象时加上一个对此对象的访问层。
关键代码:实现与被代理类组合。
代理可用于:图片预加载、合并HTTP请求(代理收集一定时间内的所有HTTP请求,然后一次性发给服务器)、惰性加载(通过代理处理和收集一些基本操作,然后仅在真正需要本体的时候才加载本体)、缓存代理(缓存请求结果、计算结果)等
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Proxy implements Sourceable {
private Source source;
public Proxy(){
super();
this.source = new Source();
}
@Override
public void method() {
before();
source.method();
atfer();
}
private void atfer() {
System.out.println("after proxy!");
}
private void before() {
System.out.println("before proxy!");
}
}
代理模式的应用场景:
如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法:
1、修改原有的方法来适应。这样违反了“对扩展开放,对修改关闭”的原则。
2、就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。
使用代理模式,可以将功能划分的更加清晰,有助于后期维护!
9、外观模式(Facade)
外观模式:为子系统中的一组接口定义一个一致的界面,外观模式提供了一个高层接口,这个接口使得这一子系统更加容易被使用;对于复杂的系统,系统为客户提供一个简单的接口,把复杂的实现过程封装起来,客户不需要了解系统内部的细节。
public class CPU {
public void startup(){
System.out.println("cpu startup!");
}
public void shutdown(){
System.out.println("cpu shutdown!");
}
}
public class Memory {
public void startup(){
System.out.println("memory startup!");
}
public void shutdown(){
System.out.println("memory shutdown!");
}
}
public class Disk {
public void startup(){
System.out.println("disk startup!");
}
public void shutdown(){
System.out.println("disk shutdown!");
}
}
public class Computer {
private CPU cpu;
private Memory memory;
private Disk disk;
public Computer(){
cpu = new CPU();
memory = new Memory();
disk = new Disk();
}
public void startup(){
System.out.println("start the computer!");
cpu.startup();
memory.startup();
disk.startup();
System.out.println("start computer finished!");
}
public void shutdown(){
System.out.println("begin to close the computer!");
cpu.shutdown();
memory.shutdown();
disk.shutdown();
System.out.println("computer closed!");
}
}