设计模式的重要性
设计模式是一种描述软件设计中的最佳实践的方法,它们能帮助我们构建具有良好可维护性、可扩展性和复用性的软件。了解并运用设计模式能够使我们的代码更加简洁、灵活,提高编码效率和降低出错的概率。
代理模式简介与应用场景
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式主要应用于如下场景:访问控制、资源优化、远程访问、延迟加载等。通过代理模式,我们可以在不改变原始对象的基础上,增加额外的功能和处理逻辑。
代理模式在现代软件设计中的地位与价值
代理模式在现代软件设计中的地位不可忽视。许多现代软件系统,如Web服务、数据库访问、安全系统等,都需要使用代理模式来实现访问控制和资源优化。通过合理运用代理模式,我们可以实现对系统的模块化和解耦,使得各个模块更容易扩展和维护。代理模式也可以帮助我们提高软件的性能、安全性和可用性。
代理模式的定义与核心思想
代理模式(Proxy Pattern)是指为一个对象提供一种代理,以控制对这个对象的访问。代理对象可以在客户端和目标对象之间起到一个中介的作用,并可以添加额外的功能。核心思想在于将对象的访问封装在代理对象中,以达到对目标对象的访问进行控制和扩展的目的。
静态代理与动态代理的比较
静态代理是指代理类和目标类在编译期间就已经确定,代理类需要为每一个具体的目标类编写相应的代码。优点是实现简单,易于理解;缺点是当目标类较多时,需要为每个目标类创建代理类,造成代码冗余。
动态代理则是在运行时动态生成代理类的字节码,并加载到JVM中。优点是代理类的生成不依赖于具体的目标类,可以实现通用的代理逻辑;缺点是实现复杂,需要深入了解字节码操作和反射机制。
设计原则与代理模式的关系
代理模式遵循“开闭原则”和“单一职责原则”。通过将目标对象的访问逻辑与具体功能分离,代理模式能够实现对现有代码的封装和扩展,而无需修改原始对象的代码。此外,代理对象专注于实现访问控制和额外功能,而目标对象专注于实现核心业务逻辑,使得每个类的职责更加清晰。
静态代理模式的UML图
静态代理模式的UML图包括以下四个主要角色:
静态代理模式的实现步骤
静态代理模式的示例代码与解析
// Subject接口
public interface Subject {
void request();
}
// RealSubject类
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// Proxy类
public class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("Proxy: Pre-processing.");
realSubject.request();
System.out.println("Proxy: Post-processing.");
}
}
// Client类
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.request();
}
}
动态代理模式的UML图
动态代理模式的UML图包括以下四个主要角色:
动态代理模式的实现步骤
动态代理模式的示例代码与解析
// Subject接口
public interface Subject {
void request();
}
// RealSubject类
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// InvocationHandler类
public class DynamicProxyHandler implements InvocationHandler {
private Object realSubject;
public DynamicProxyHandler(Object realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("DynamicProxy: Pre-processing.");
Object result = method.invoke(realSubject, args);
System.out.println("DynamicProxy: Post-processing.");
return result;
}
}
// Client类
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(), handler);
proxy.request();
}
}
以上代码展示了一个动态代理模式的简单示例。在这个例子中,Subject接口定义了一个request()方法,RealSubject类实现了这个接口并完成实际的业务逻辑。DynamicProxyHandler类实现了InvocationHandler接口,并在调用RealSubject对象的request()方法前后添加了额外的逻辑。在Client类中,我们使用Proxy.newProxyInstance()方法动态生成一个代理对象,并使用该代理对象代替RealSubject对象进行操作。
访问控制与权限管理
代理模式可以用于实现访问控制和权限管理。例如,当一个系统需要对某些操作进行权限控制时,可以通过代理模式实现。代理对象在执行实际操作之前可以检查用户的权限,确保只有具有足够权限的用户才能执行特定的操作。
资源优化与按需加载
代理模式可以实现资源优化和按需加载。例如,在实现一个图片浏览器时,加载大量的高清图片可能会消耗大量的内存和网络资源。通过使用代理模式,可以在需要时才加载图片,从而节省资源。代理对象可以保存图片的URL和大小等信息,当用户真正需要查看图片时,代理对象才会从网络上下载图片并显示。
保护性代理与虚拟代理
保护性代理用于保护目标对象免受不必要的访问。例如,一个数据库系统可能需要限制对敏感数据的访问。保护性代理可以检查用户的权限,确保只有具有特定权限的用户才能访问敏感数据。
虚拟代理可以实现按需加载和资源优化。例如,在一个文档编辑器中,用户可能会插入大量的图片。虚拟代理可以将图片的加载推迟到用户真正需要查看图片时,从而节省资源和提高程序的响应速度。
class LargeObject {
public:
void performOperation() {
// 执行一些耗时操作
}
};
class LargeObjectProxy {
public:
void performOperation() {
if (!largeObject) {
largeObject = new LargeObject();
}
largeObject->performOperation();
}
private:
LargeObject *largeObject = nullptr;
};
class RemoteObject {
public:
virtual void remoteOperation() = 0;
};
class RemoteObjectImpl : public RemoteObject {
public:
void remoteOperation() override {
// 实际执行远程操作的代码
}
};
class RemoteObjectProxy : public RemoteObject {
public:
void remoteOperation() override {
// 进行网络通信,将请求发送给远程对象
// 并获取远程对象的结果
}
};
class ProtectedObject {
public:
virtual void restrictedOperation() = 0;
};
class ProtectedObjectImpl : public ProtectedObject {
public:
void restrictedOperation() override {
// 实际执行受限操作的代码
}
};
class ProtectedObjectProxy : public ProtectedObject {
public:
void restrictedOperation() override {
if (checkAccessPermission()) {
protectedObject->restrictedOperation();
} else {
// 拒绝执行受限操作,可能抛出异常或记录日志
}
}
private:
bool checkAccessPermission() {
// 检查访问权限,返回 true 表示允许访问
return true;
}
ProtectedObject *protectedObject = new ProtectedObjectImpl();
};
#include
#include
class AccessibleObject {
public:
virtual void operation() = 0;
};
class RealObject : public AccessibleObject {
public:
void operation() override {
// 实际执行操作的代码
std::cout << "Real object operation performed." << std::endl;
}
};
class AccessProxy : public AccessibleObject {
public:
AccessProxy() : accessCount(0) {}
void operation() override {
auto startTime = std::chrono::high_resolution_clock::now();
realObject.operation();
auto endTime = std::chrono::high_resolution_clock::now();
accessCount++;
totalTime += std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime).count();
std::cout << "Access count: " << accessCount << ", Total time: " << totalTime << " microseconds" << std::endl;
}
private:
RealObject realObject;
int accessCount;
long long totalTime;
};
#include
template<typename T>
class SmartPointer {
public:
explicit SmartPointer(T *ptr) : rawPointer(ptr) {}
~SmartPointer() {
delete rawPointer;
}
T *operator->() {
return rawPointer;
}
T &operator*() {
return *rawPointer;
}
private:
T *rawPointer;
};
#include
#include
class Cacheable {
public:
virtual int expensiveOperation(int key) = 0;
};
class ExpensiveResource : public Cacheable {
public:
int expensiveOperation(int key) override {
// 实际执行昂贵操作的代码
std::cout << "Performing expensive operation for key: " << key << std::endl;
return key * 2;
}
};
class CacheProxy : public Cacheable {
public:
CacheProxy() : expensiveResource(new ExpensiveResource()) {}
int expensiveOperation(int key) override {
auto it = cache.find(key);
if (it != cache.end()) {
// 从缓存中获取结果
return it->second;
}
// 如果缓存中没有结果,则执行昂贵操作并将结果存入缓存
int result = expensiveResource->expensiveOperation(key);
cache[key] = result;
return result;
}
private:
ExpensiveResource *expensiveResource;
std::unordered_map<int, int> cache;
};
#include
#include
#include
class Loggable {
public:
virtual void performOperation(const std::string &operation) = 0;
};
class TargetObject : public Loggable {
public:
void performOperation(const std::string &operation) override {
std::cout << "Performing operation: " << operation << std::endl;
// 执行操作代码
}
};
class LoggingProxy : public Loggable {
public:
LoggingProxy() : targetObject(new TargetObject()) {}
void performOperation(const std::string &operation) override {
try {
std::cout << "Logging: Attempting operation: " << operation << std::endl;
targetObject->performOperation(operation);
std::cout << "Logging: Operation completed: " << operation << std::endl;
} catch (const std::exception &e) {
std::cout << "Logging: Exception occurred: " << e.what() << std::endl;
}
}
private:
TargetObject *targetObject;
};
#include
#include
#include
class Securable {
public:
virtual void restrictedOperation(const std::string &operation) = 0;
};
class SecureObject : public Securable {
public:
void restrictedOperation(const std::string &operation) override {
// 执行受限操作的代码
std::cout << "Performing restricted operation: " << operation << std::endl;
}
};
class SecurityProxy : public Securable {
public:
SecurityProxy(const std::string &user, const std::string &password)
: secureObject(new SecureObject()) {
// 假设我们已经验证了用户和密码
if (user == "admin" && password == "admin123") {
authenticated = true;
} else {
authenticated = false;
}
}
void restrictedOperation(const std::string &operation) override {
if (authenticated) {
secureObject->restrictedOperation(operation);
} else {
std::cout << "Access denied: Invalid user or password." << std::endl;
}
}
private:
SecureObject *secureObject;
bool authenticated;
};
#include
#include
#include
class AccessControlled {
public:
virtual void performConcurrentOperation(const std::string &operation) = 0;
};
class ControlledObject : public AccessControlled {
public:
void performConcurrentOperation(const std::string &operation) override {
// 执行并发操作的代码
std::cout << "Performing concurrent operation: " << operation << std::endl;
}
};
class AccessControlProxy : public AccessControlled {
public:
AccessControlProxy() : controlledObject(new ControlledObject()) {}
void performConcurrentOperation(const std::string &operation) override {
std::unique_lock<std::mutex> lock(mutex);
if (activeThreads < maxConcurrentThreads) {
++activeThreads;
lock.unlock();
controlledObject->performConcurrentOperation(operation);
lock.lock();
--activeThreads;
} else {
std::cout << "Access denied: Maximum number of concurrent threads reached." << std::endl;
}
}
private:
ControlledObject *controlledObject;
std::mutex mutex;
int activeThreads = 0;
const int maxConcurrentThreads = 3;
};
#include
#include
#include
class Loadable {
public:
virtual void performOperation(const std::string &operation) = 0;
};
class ExpensiveObject : public Loadable {
public:
ExpensiveObject() {
// 模拟昂贵的对象初始化
std::cout << "Initializing expensive object..." << std::endl;
}
void performOperation(const std::string &operation) override {
std::cout << "Performing operation: " << operation << std::endl;
}
};
class VirtualProxy : public Loadable {
public:
void performOperation(const std::string &operation) override {
if (!expensiveObject) {
expensiveObject = std::make_unique<ExpensiveObject>();
}
expensiveObject->performOperation(operation);
}
private:
std::unique_ptr<ExpensiveObject> expensiveObject;
};