Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 适配器适配器模式的任何实例_Oop_Design Patterns_Adapter_Software Design - Fatal编程技术网

Oop 适配器适配器模式的任何实例

Oop 适配器适配器模式的任何实例,oop,design-patterns,adapter,software-design,Oop,Design Patterns,Adapter,Software Design,我想向我的团队演示如何使用。我在网上读了很多书和文章。每个人都在引用一个有助于理解概念的例子(形状、存储卡、电子适配器等),但没有真正的案例研究 你能分享一下适配器模式的案例吗 p、 我试图搜索stackoverflow上的现有问题,但没有找到答案,所以将其作为新问题发布。如果您知道这个问题已经有了答案,那么请重定向。许多适配器的示例都是琐碎的或不现实的(,)。更糟糕的是,许多适配器没有为不同的适配器显示多个适配器。仅调整一个类的接口以与另一个类一起工作似乎是GoF适配器模式的一个弱示例。此模式

我想向我的团队演示如何使用。我在网上读了很多书和文章。每个人都在引用一个有助于理解概念的例子(形状、存储卡、电子适配器等),但没有真正的案例研究

你能分享一下适配器模式的案例吗


p、 我试图搜索stackoverflow上的现有问题,但没有找到答案,所以将其作为新问题发布。如果您知道这个问题已经有了答案,那么请重定向。

许多适配器的示例都是琐碎的或不现实的(,)。更糟糕的是,许多适配器没有为不同的适配器显示多个适配器。仅调整一个类的接口以与另一个类一起工作似乎是GoF适配器模式的一个弱示例。此模式使用继承和多态性,因此我们希望有一个很好的示例为不同的适配器显示多个适配器实现

我发现的最好的例子是在第26章。以下图片来自该书FTP站点上提供的讲师资料

第一个示例展示了应用程序如何使用功能相似(例如,税务计算器、会计模块、信贷授权服务等)但具有不同API的多个实现(适配器)。我们希望避免硬编码我们的域层代码,以处理不同的可能方式来计算税收、售后服务、授权信用卡请求等。这些都是外部模块,可能会有所不同,我们无法修改代码。适配器允许我们在适配器中进行硬编码,而我们的域层代码总是使用相同的接口(IWhateverAdapter接口)

我们在上图中看不到实际的适配器。但是,下图显示了如何在IAccountingAdapter界面中对
postSale(…)
进行多态调用,从而通过SOAP将销售过账到SAP系统

适配器模式充当两个不兼容接口之间的桥梁。 此模式涉及一个名为adapter的类,它是 负责两个独立或不兼容设备之间的通信 接口

现实世界的例子可能是语言翻译或移动充电器。更多信息,请参见youtube视频:


您可以在此处找到用于防御注入攻击的适配器模式的PHP实现:


适配器模式的一个有趣方面是它有两种风格:依赖多重继承的类适配器和依赖组合的对象适配器。上面的示例依赖于组合。

一个真实的示例可以是应用程序中的报告文档。简单的代码如下

我认为适配器对于编程结构非常有用

class WordAdaptee implements IReport{
    public void report(String s) {
        System.out.println(s +" Word");
    }
}

class ExcellAdaptee implements IReport{
    public void report(String s) {
        System.out.println(s +" Excel");
    }
}


class ReportAdapter implements IReport{
    WordAdaptee wordAdaptee=new WordAdaptee();
    @Override
    public void report(String s) {
        wordAdaptee.report(s);
    }
}

interface IReport {
    public void report(String s);
}

public class Main {
    public static void main(String[] args) {

        //create the interface that client wants
        IReport iReport=new ReportAdapter();

        //we want to write a report both from excel and world
        iReport.report("Trial report1 with one adaptee");  //we can directly write the report if one adaptee is avaliable 

        //assume there are N adaptees so it is like in our example
        IReport[] iReport2={new ExcellAdaptee(),new WordAdaptee()};

        //here we can use Polymorphism here  
        for (int i = 0; i < iReport2.length; i++) {
            iReport2[i].report("Trial report 2");
        }
    }
}

一个真实的例子是qtdbus

qt dbus有一个实用程序,用于从提供的xml文件生成适配器和接口代码。下面是这样做的步骤

 1. Create the xml file - this xml file should have the interfaces 
that can be viewed by the qdbus-view in the system either on 
the system or session bus.

    2.With the utility - qdbusxml2cpp , you generate the interface adaptor code. 
This interface adaptor does the demarshalling of the data that is 
received from the client. After demarshalling, it invokes the 
user defined - custom methods ( we can say as adaptee).

    3. At the client side, we generate the interface from the xml file. 
This interface is invoked by the client. The interface does the 
marshalling of the data and invokes the adaptor interface. As told 
in the point number 2, the adaptor interface does the demarshalling 
and calls the adaptee - user defined methods.
您可以在这里看到Qt Dbus的完整示例-


将一个接口转换为另一个接口

适配器模式的任何实例

为了连接电源,我们在世界各地都有不同的接口。 使用适配器,我们可以像wise一样轻松连接


如何把法国人变成正常人

 public interface IPerson
    {
        string Name { get; set; }
    }

    public interface IFrenchPerson
    {
        string Nom { get; set; }
    }

    public class Person : IPerson
    {
        public string Name { get; set; }
    }

    public class FrenchPerson : IFrenchPerson
    {
        public string Nom { get; set; }
    }

    // that is a service that we want to use with our French person
    // we cannot or don't want to change the service contract
    // therefore we need 'l'Adaptateur'
    public class PersonService
    {
        public void PrintName(IPerson person)
        {
            Debug.Write(person.Name);
        }
    }

    public class FrenchPersonAdapter : IPerson
    {
        private readonly IFrenchPerson frenchPerson;

        public FrenchPersonAdapter(IFrenchPerson frenchPerson)
        {
            this.frenchPerson = frenchPerson;
        }

        public string Name 
        {
            get { return frenchPerson.Nom; }
            set { frenchPerson.Nom = value; }
        }
    } 
范例

    var service = new PersonService();
    var person = new Person();
    var frenchPerson = new FrenchPerson();

    service.PrintName(person);
    service.PrintName(new FrenchPersonAdapter(frenchPerson));

当您有一个无法更改但需要使用的接口时,请使用适配器。当你是办公室里的新人时,你不能让白发服从你的规则——你必须适应他们的规则。这里是一个真实的例子,我曾经参与过一个真实的项目,其中用户界面是给定的

您有一个应用程序,它将文件中的所有行读取到列表数据结构中,并在网格中显示它们(让我们调用底层数据存储接口IDataStore)。用户可以通过单击按钮“首页”、“上一页”、“下一页”、“最后一页”浏览这些数据。一切正常

现在,应用程序需要与生产日志一起使用,这些日志太大,无法读入内存,但用户仍然需要浏览它!一种解决方案是实现一个缓存,用于存储第一页、下一页、上一页和最后一页。我们想要的是当用户单击“下一页”时,我们从缓存返回页面并更新缓存;当他们单击最后一页时,我们从缓存返回最后一页。在后台,我们有一个文件流来完成所有的工作。这样我们的内存中只有四页,而不是整个文件

您可以使用适配器将此新的缓存功能添加到应用程序中,而用户不会注意到它。我们扩展了当前的IDataStore并称之为CacheDataStore。如果要加载的文件很大,则使用CacheDataStore。当我们请求第一页、下一页、上一页和最后一页时,信息被路由到缓存

谁知道呢,明天老板想开始从数据库表读取文件。您所做的只是将IDataStore扩展到SQLDataStore,就像在缓存中一样,在后台设置连接。当他们单击下一页时,您将生成必要的sql查询以从数据库中获取接下来的几百行


本质上,应用程序的原始接口没有改变。我们只是简单地采用了现代而酷的功能来使用它,同时保留了传统的界面。

下面是一个模拟将模拟数据转换为数字数据的示例

它提供了一个将浮点数字数据转换为二进制数据的适配器,在现实世界中可能没有用处,它只是帮助解释适配器模式的概念


代码 AnalogSignal.java

包eric.designpattern.adapter;
公共接口模拟信号{
float[]getAnalog();
void setAnalog(浮点[]模拟数据);
void printAnalog();
}
DigitSignal.java

包eric.designpattern.adapter;
    var service = new PersonService();
    var person = new Person();
    var frenchPerson = new FrenchPerson();

    service.PrintName(person);
    service.PrintName(new FrenchPersonAdapter(frenchPerson));
interface NokiaInterface {
    chargementNokia(x:boolean):void
}


class SamsungAdapter implements NokiaInterface {
//nokia chargement adapted to samsung
    chargementNokia(x:boolean){
        const old= new SamsungCharger();
        let y:number = x ? 20 : 1;
        old.charge(y);
      }
}


class SamsungCharger {
      charge(x:number){
            console.log("chrgement x ==>", x);
      }
}


function main() {
      //charge samsung with nokia charger
      const adapter = new SamsungAdapter();
      adapter.chargementNokia(true);
}
public interface IWetherFinder {
    public double getTemperature(String cityName);
}

class WeatherFinder implements IWetherFinder{
   @Override
   public double getTemperature(String cityName){
     return 40;
   }
}

interface IWeatherFinderClient
{
   public double getTemperature(String zipcode);
}  

public class WeatherAdapter implements IWeatherFinderClient {

    @Override
    public double getTemperature(String zipcode) {

        //method to get cityname by zipcode 
        String cityName = getCityName(zipcode);

        //invoke actual service
        IWetherFinder wetherFinder = new WeatherFinder();
        return wetherFinder.getTemperature(cityName);
    }

    private String getCityName(String zipCode) {
        return "Banaglore";
    }
}
abstract public boolean set(string $id, mixed $value, integer $expire=0, ICacheDependency $dependency=NULL)
abstract public mixed get(string $id)
    public function get(string $key, callable $callback, float $beta = null, array &$metadata = null);
    class YiiToSymfonyCacheAdapter implements \Yii\system\caching\ICache
    {
        private \Symfony\Contracts\Cache\CacheInterface $symfonyCache;

        public function __construct(\Symfony\Contracts\Cache\CacheInterface $symfonyCache)
        {
            $this->symfonyCache = $symfonyCache;
        }

      
      public boolean set(string $id, mixed $value, integer $expire=0, ICacheDependency 
       $dependency=NULL) 
      {

          // https://symfony.com/doc/current/cache.html
          return $this->symfonyCache->get(
              $id, 
              function($item) { 
              // some logic .. 
               return $value; 
              }
          );

//          https://github.com/symfony/cache/blob/master/Adapter/MemcachedAdapter.php
// if a class could be called statically, the adapter could call statically also eg. like this
//          return \Symfony\Component\Cache\Adapter\MemcacheAdapter::get(
//              $id, 
//              function($item) { 
//              // some logic .. 
//               return $value; 
//              }
          );
       }

       public mixed get(string $id) 
       {
           // https://github.com/symfony/cache/blob/master/Adapter/FilesystemAdapter.php 
           // if a class could be called statically, the adapter could call statically also eg. like this
           // \Symfony\Component\Cache\Adapter\FileSystemAdapter::get($id)
           return $this->symfonyCache->get($id) 
       }
    }