decorator mode

Keywords: Java github

;

Article Directory

1. Definition

Definition of GOF
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
Dynamically add extra responsibility for work to an object.Decorator mode provides a flexible way to extend functionality instead of subclassifying.

Simply put, there is another, more flexible way to add extra functionality (or enhancements to some methods) to a class, in addition to using inheritance: composition.

2. Implementation

Take a look at a specific case:

  1. Leaders have to write a file read-write interface to support four functions: compressed read-write, cached read-write, encrypted read-write, and data formatted read-write.So we can design an Fstream interface, and then design four classes ZipFstream, BufferFstream, CipherFstream, DataFstream to implement the Fstream interface.As shown in the following figure:

  1. After a few days, the leader said that there are several functions to be added:
    (1) Add a set of interfaces that support both read-write with cache and compressed read-write
    (2) Add a set of interfaces supporting both read-write with cache and encrypted read-write

Using inheritance, we can do the following

Two subclasses have been added, which seems harmless.

  1. A few days later, the leader said, adding functions:
    (1). Add an interface with data format that also supports slow-band storage
    (2) Add an interface that supports both caching, data formatting and compression.
    (3) Add an interface that supports both caching, data formatting, compression and encryption

If we add a subclass for each requirement, it will eventually lead to an explosive increase in the number of subclasses, making it difficult to maintain...

In fact, if you look closely, you will find that there are actually only four "atomic" functions in these requirements:

(1). Read and write with cache
(2). Read and write with data format
(3). Read and write encrypted files
(4). Read and write compressed files

The other needs are a combination of the above four

We can use the decorator mode to achieve these four "atomic" functions, and then the user can use these atomic functions to combine more complex functions

2.1 cpp implementation

//author sbkun
#include <iostream>
using namespace std;

class Fstream{
public:
	virtual ~Fstream() = default;
	Fstream() = default;
	virtual void read() {
		cout<<"base read"<<endl;
	}

protected:
	Fstream(const Fstream&) = delete;
	Fstream& operator=(const Fstream&) = delete;
};

class FilterFstream : public Fstream {
public:
	virtual ~FilterFstream() {
		delete fstream_;
	}
	FilterFstream(Fstream* f) : fstream_(f) {}
protected:
	Fstream* fstream_;
};

class ZipFstream : public FilterFstream{
	public: 
	ZipFstream(Fstream* f): FilterFstream(f)	 { }	
	void read() override {
		cout<<"zip read"<<endl;
		fstream_->read();
	}
};
class CipherFstream : public FilterFstream{
	public:
	CipherFstream(Fstream* f): FilterFstream(f)	 { }	
	void read() override {
		cout<<"cipher read"<<endl;
		fstream_->read();
	}
};

class BufferFstream : public FilterFstream{
	public:
	BufferFstream(Fstream* f): FilterFstream(f)	 { }	
	
	void read() override {
		cout<<"buffer read"<<endl;
		fstream_->read();
	}
};

int main(int argc, char* argv[])
{
	Fstream* f1 = new BufferFstream(new ZipFstream(new CipherFstream(new Fstream)));	
	f1->read();
	delete f1;

	cout<<endl<<"====="<<endl<<endl;

	//Can be any combination of required functions, refreshing	
	Fstream* f2 = new BufferFstream(new CipherFstream(new ZipFstream(new Fstream)));	
	f2->read();
	delete f2;
	return 0;
}

2.2 java implementation

//author sbkun
package decorator;

class Fstream {
    void read() {
        System.out.println("base read");
    }
}

class FilterFstream extends Fstream {
    FilterFstream(Fstream f) {
        this.fstream = f;
    }

    protected Fstream fstream;
}

class BufferFstream extends FilterFstream {
    BufferFstream(Fstream f) {
        super(f);
    }

    void read() {
        System.out.println("buffer read");
        fstream.read();
    }
}

class ZipFstream extends FilterFstream {
    ZipFstream(Fstream f) {
        super(f);
    }

    void read() {
        System.out.println("zip read");
        fstream.read();
    }
}

class CipherFstream extends FilterFstream {
    CipherFstream(Fstream f) {
        super(f);
    }

    void read() {
        System.out.println("cipher read");
        fstream.read();
    }
}

public class DecoratorDemo {
    public static void main(String args[]) {
        Fstream f = new BufferFstream(new CipherFstream(new ZipFstream(new Fstream())));
        f.read();
    }
}

3. Discussion

Decorator mode is used to add additional functionality to a class (or to enhance some methods) and freely combine complex functionality through the nesting of decorators

4. Full code address

All the code for this column has been uploaded to github. I hope you can criticize and correct it a lot
git link

Posted by r00tk1LL on Wed, 10 Jun 2020 09:31:19 -0700