Scala设计模式UML图例和代码实现实战 结构模式--外观设计模式

 

外观设计模式  (facade design mode)

每当我们构建库或大型系统时,我们通常都依赖于其他库和功能。实现方法有时需要同时使用多个类。

这需要知识。每当我们为某人建立一个图书馆时,我们通常会尝试通过假设他们没有(并且不需要)像我们那样广泛的知识来使用户更简单。

此外,开发人员确保组件在整个应用程序中易于使用。这是外观设计模式可以变得有用的地方。

外观设计模式的目的是用一个简单的界面包装一个复杂的系统,以隐藏使用的复杂性并简化客户端的交互。

我们已经研究了基于包装的其他设计模式。

虽然适配器设计模式将一个接口转换为另一个接口,而装饰器增加了额外的功能,但外观使事情变得更简单。

示例类图对于类图,让我们假设以下设置 - 我们希望我们的用户能够从服务器下载一些数据并以对象的形式对其进行反序列化。服务器以编码形式返回我们的数据,因此我们应首先解码它,然后解析它,最后返回正确的对象。这涉及许多操作并使事情变得复杂。这就是我们使用外观设计模式的原因:

当客户端使用上述应用程序时,他们只需要与DataReader进行交互。 在内部,它将负责下载,解码和反序列化数据。

 

代码示例上图将DataDownloader,DataDecoder和DataDeserializer显示为DataReader中的组合对象。 这很容易实现 - 它们可以使用默认构造函数创建,也可以作为参数传递。 但是,对于我们示例的代码表示,我们选择使用traits而不是类,并将它们与DataReader类混合使用。

我们先来看看DataDownloader,DataDecoder和DataDeserializer特性:

 

 

package com.ivan.nikolov.structural.facade.model

 

case class Person(name: String, age: Int)

 

 

package com.ivan.nikolov.structural.facade

 

import java.util.Base64

 

trait DataDecoder {

def decode(data: Array[Byte]): String =

new String(Base64.getDecoder.decode(data), "UTF-8")

}

 

 

package com.ivan.nikolov.structural.facade

 

import org.json4s._

import org.json4s.jackson.JsonMethods

 

trait DataDeserializer {

implicit val formats = DefaultFormats

def parse[T](data: String)(implicit m: Manifest[T]): T =

JsonMethods.parse(StringInput(data)).extract[T]

}

 

package com.ivan.nikolov.structural.facade

 

import com.typesafe.scalalogging.LazyLogging

 

trait DataDownloader extends LazyLogging {

def download(url: String): Array[Byte] = {

logger.info("Downloading from: {}", url)

Thread.sleep(5000)

// {

// "name": "Ivan",

// "age": 26

// }

// the string below is the Base64 encoded Json above.

"ew0KICAgICJuYW1lIjogIkl2YW4iLA0KICAgICJhZ2UiOiAyNg0KfQ==".getBytes

}

}

 

package com.ivan.nikolov.structural.facade

 

import com.ivan.nikolov.structural.facade.model.Person

 

class DataReader extends DataDownloader with DataDecoder with DataDeserializer {

 

def readPerson(url: String): Person = {

val data = download(url)

val json = decode(data)

parse[Person](json)

}

}

 

object FacadeExample {

def main(args: Array[String]): Unit = {

val reader = new DataReader

System.out.println(s"We just read the following person: ${reader.readPerson("https://www.ivan-nikolov.com/")}")

}

}

 

//前面的实现非常简单,它们彼此分开,因为它们处理不同的任务。

//任何人都可以使用它们 然而,它需要一些知识并使事情变得更复杂。 这就是为什么我们有一个名为DataReader的Facade类:

 

class DataReader extends DataDownloader with DataDecoder with

DataDeserializer {

def readPerson(url: String): Person = {

val data = download(url)

val json = decode(data)

parse[Person](json)

}

}

//这个例子清楚地表明,我们现在有一个简单的调用方法,而不是使用三个不同的接口。 所有复杂性都隐藏在此方法中。 以下清单显示了我们班级的示例用法:

object FacadeExample {

def main(args: Array[String]): Unit = {

val reader = new DataReader

System.out.println(s"We just read the following person:

${reader.readPerson("https://www.ivan-nikolov.com/")}")

}

}

//上面的代码使用我们的库,这些库对客户端是隐藏的,非常简单。 这是一个示例输出:

当然,在前面的例子中,我们可以在DataReader中使用类而不是混合特征。这实际上取决于需求并且应该产生相同的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心自由天使

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值