我觉得我一直在使用这些模式系列很多次,但是,对我来说,因为它们的定义 非常相似。基本上,似乎所有这些都是关于包装 的另一个对象或对象扩展或 wrap 它们的行为以及额外的东西。
对于通过存储库模式实现缓存机制的快速示例似乎就是这种情况。这是我可能会从。
开始的快速示例C#
代码 public interface IRepository {
IEnumerable<T> GetItems<T>();
}
public class EntityFrameworkRepository : IRepository {
...
}
public class CachedRepository : IRepository {
private IRepository _repository;
private ICacheProvider _cache;
public CachedRepository(IRepository repository, ICacheProvider cache) {
this._repository = repository;
this._cache = cache;
}
public IEnumerable<T> GetItems<T>() {
...
}
}
例如,这些模式中的哪一种适用于这种情况?谁能简要澄清理论和实践中的差异?
从理论上讲它们是相同的,是intent
将一种模式与另一种模式区分开来:
装饰器:
允许对象组合/添加功能,通过将它们与具有相同接口
的类包装。适配器:
允许您在没有已知接口实现的情况下包装对象 因此,它粘附在接口上。关键是将一个接口"翻译"到另一个接口。
包装器:
从未听说过这是一种设计模式,但我想这只是上述
的通用名称您指定的示例我将归类为装饰器:cacherepository decorates
a IRepository
添加缓存功能。
程序员可以编写一个类A类,重点是持有其他类别的对象。类A类。为什么A级包裹在B级上?装饰或适应它。装饰器和适配器是包装纸。
想象A级写作,以便通过调用其B类对象的方法来实现B类的接口。然后,它可以代替B类。除了它使程序员有机会在调用B类对象的方法之前或之后添加一些代码的事实,这是没有其他意义的。此版本A类将称为B类的 Decorator 装饰器在添加一些行为时离开界面相同。
interface ICatInterface {
public void wakeUp();
}
class Cat implements ICatInterface {
public void wakeUp() {
System.out.println("I came. I saw. I napped.");
}
}
class YogaCat implements ICatInterface {
private ICatInterface cat;
public YogaCat(ICatInterface cat) {
this.cat = cat;
}
public void wakeUp() {
System.out.println("[Stretch]"); // <- This is the decoration.
cat.wakeUp();
}
}
请参阅此示例的示例,是一种更复杂的方法,用于在运行时组合不同行为的对象。
想象一下,现在编写了A类以使其实现某些接口C,但主要是通过呼叫对其B类对象的方法实现的。这是将B类可用的方法转换为接口C的一种方法。该类别的A类将称为 ADAPTER 类别的A级。就像您想为手机充电时一样。有一些适配器从墙壁或汽车电源到USB端口。适配器将接口更改为其他接口,但不一定添加任何行为。
interface TakeDirectionsInterface {
public void turnLeft();
public void turnRight();
public void go();
public void stop();
}
class Driver {
public enum TurnDirection
{
CLOCKWISE, COUNTERCLOCKWISE;
}
public enum FootPedal
{
ACCELERATOR, BRAKE, CLUTCH;
}
public void turnSteeringWheel(TurnDirection direction) {
System.out.println("Turning the steering wheel " + direction.toString() + ".");
}
public void pressPedal(FootPedal pedal) {
System.out.println("Pressing the " + pedal.toString() + "pedal.");
}
}
class DriverAdapter implements TakeDirectionsInterface {
private Driver driver;
public DriverAdapter(Driver driver) {
this.driver = driver;
}
public void turnLeft(){
driver.turnSteeringWheel(Driver.TurnDirection.COUNTERCLOCKWISE);
}
public void turnRight(){
driver.turnSteeringWheel(Driver.TurnDirection.CLOCKWISE);
}
public void go(){
driver.pressPedal(Driver.FootPedal.ACCELERATOR);
}
public void stop(){
driver.pressPedal(Driver.FootPedal.BRAKE);
}
}