设计模式总结 之 创建型

设计模式总结 之 创建型

参考:
http://blog.csdn.net/jason0539
设计模式和原则 强烈推荐 http://blog.csdn.net/zhengzhb/article/category/926691
总共有24中设计模式,分为3类:
 创建型模式,共种:单例模式简单工厂、抽象工厂模式、工厂方法模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

1. 单例模式  SingleTon

结构解析:
java中 单例类中私有化构造函数和实例化对象    防止创建新实例和直接访问实例   饭后提供访问实例的方法
scala中直接object即可
public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法   
    public static Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
    }  
}  

最简单的模式,单列类只有一个实例,类中静态实现,对外提供访问该例的方法
scala中实现只需要 一个Object就可以实现单例模式
object LoadBalance {
  //服务器组
  val servers = new ArrayBuffer[String]()

  /**
   * 增加服务器
   * @param server 服务器名
   */

  def addServer(server: String) {
    println(s"add server :$server")
    servers += server
  }

  /**
   * 删除服务器
   * @param server 服务器名
   */
  def removeServer(server: String) {
    println(s"remove server : $server")
    servers -= server
  }

  /**
   * 随机获取服务器转发
   * @return 服务器名
   */

  def getServers(): String = {
    servers(Random.nextInt(servers.length))
  }
}

/**
 * 单例测试客户端
 */
object Client extends App {

  Console.println("singleTon Client Test")
  // 构建负载均衡器1
  val balance1 = LoadBalance
  // 构建负载均衡器2
  val balance2 = LoadBalance

  //判断两个balance是否一致

  println(s"两个均衡器是否一致 :  ${balance1.eq(balance2)}")

  //添加服务器
  balance1.addServer("server1")
  balance1.addServer("server2")
  balance1.addServer("server3")
  balance1.addServer("server4")

  //随机获取服务器

  for (i <- 1 to 10) {
    println(s"get server : ${balance1.getServers()}")
  }

  //使用balance2删除 服务器

  balance2.removeServer("server1")

  //随机获取服务器

  for (i <- 1 to 10) {
    println(s"get server : ${balance1.getServers()}")
  }

}


2. 简单工厂 SimpleFactory

结构解析:
抽象类产品 
具体类产品
工厂  :根据输入参数选择返回具体的产品

简单工厂模式,根据外界给定的原料,在加上自身封装好的判断,生产出不同类型的相应的产品、对象。

简单工厂模式使用场景:工厂类负责创建的对象比较少;客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心

abstract  class Chart {
    def display():Unit
}

/**
 * 柱状图,继承抽象图
 */
class  HistogramChart extends  Chart{
    println("初始化柱状图")

    /**
     * 展示方法
     */
    override def display(): Unit = {
        println("显示柱状图")
    }
}

/**
 * 饼状图,继承抽象图
 */
class  PieChart extends  Chart{
    println("初始化饼状图")

    /**
     * 展示方法
     */
    override def display(): Unit = {
        println("显示饼状图")
    }
}


/**
 * 折线图,继承抽象图
 */
class LineChart extends  Chart{
    println("初始化折线图")

    /**
     * 展示方法
     */
    override def display(): Unit = {
        println("显示折线图")
    }
}


/**
 * 工厂方法,用于产出具体产品
 */
object  Chart {
    /**
     * 通过模式匹配更加优雅实现
     * @param style 产品类型
     * @return 具体产品
     */
    def apply(style:String) = style match {
        case "histogram" => println("创建柱状图");new HistogramChart
        case "pie" => println("创建饼状图");new PieChart
        case "line" =>println("创建折线图"); new LineChart
    }
}


/**
 * Created by ctao on 2015/8/6.
 * 测试客户端
 */
object Client2 extends  App{
    //产出饼状图
    val pie = Chart("pie")
    pie.display()
    //产出柱状图
    val histogram = Chart("histogram")
    histogram.display()
    //产出折线图
    val line = Chart("line")
    line.display()

}

3. 抽象工厂 AbstractFactory

结构解析:
抽象工厂:接口
具体工厂:object
抽象产品:接口
具体产品:具体工厂中的内部类
抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
/**
 * 皮肤工厂特质
 */

trait SkinFactory {
  
  def createButton():Button
  def createTextField():TextField
  
}

/**
 * 按钮特质
 */
trait Button{
  def display():Unit
}

/**
*文本框特质
*/

trait   TextField{
  def display():Unit
}

/**
* 春天皮肤工厂
*/

object SpringSkinFactory extends SkinFactory{
  
  class SpringButton extends Button{
    override def display():Unit=println("Spring Button")
  }
  
  class SpringTextField extends TextField {
    override def display():Unit=println("Spring TextField ")
  }
  
  override def createButton():Button=new SpringButton
  
  override def createTextField():TextField =new SpringTextField
}

/**
* 夏天皮肤工厂
*/

object SummerSkinFactory extends SkinFactory{
  
  class SummerButton extends Button{
    override def display():Unit=println("Summer Button")
  }
  
  class SummerTextField extends TextField {
    override def display():Unit=println("Summer TextField ")
  }
  
  override def createButton():Button=new SummerButton
  
  override def createTextField():TextField =new SummerTextField
}



/**
*客户端测试
* 
*/

object Client3 extends App{
  /**
   * 创建皮肤工厂
   */
  val factory :SkinFactory =  SpringSkinFactory
  
  factory.createButton().display()
  factory.createTextField().display()
}

4.工厂模式 Factory

简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。

抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。

结构解析:
工厂接口:Factory
具体工厂:object 每个工厂返回自己的产品 DatabaseLoggerFactory
产品接口:Logger
具体产品:DataBaseLogger FilLogger

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品

trait Factory {
  def createLogger():Logger
}

trait Logger {
  def writeLog():Unit
}

class DatabaseLogger extends Logger{
  override def writeLog(): Unit=println("数据库日志记录")
}

class FileLogger extends Logger{
  override def writeLog():Unit = println("文件日志记录")
}

object DatabaseLoggerFactory extends Factory{
  override def createLogger(): Logger = new DatabaseLogger
}

object FileLoggerFactory extends Factory{
  override def createLogger():Logger = new FileLogger
}


/**
*测试客户端
*/

object Client4 extends App{
  
  val logger1:Factory = DatabaseLoggerFactory 
  val logger2:Factory = FileLoggerFactory
  logger1.createLogger().writeLog()
  logger2.createLogger().writeLog()
}


5.建造者模式  Builder

结构解析:四要素
1.产品类    Actor
2.抽象创建者  ActorBuilder
3.创建者    HeroBuilder   DevilBuilder 
4.导演类  
创建者模式是创建型模式中最负责的一个设计模式了,创建者负责构建一个对象的各个部分,
并且完成组装的过程.构建模式主要用来针对复杂产品生产,分离部件构建细节,以达到良好的伸缩性。
把构造对象实例的逻辑移到了类的外部,在这个类外部定义了这个类的构造逻辑

trait ActorBuilder {
  protected var actor: Actor

  def buildRole(): Unit
  def buildSex(): Unit
  def buildFace(): Unit
  def buildCostume(): Unit
  val BareHead = false
  def buildHairStye(): Unit

  def creatActor(): Actor

  /*
   * 控制枢纽,控制每一步的顺序
   */
  def construct(ab: ActorBuilder): Actor = {
    //先设置角色,再设置性别,其次是脸型,服装,用钩子程序判断是否是光头,不是光头则设置发型
    ab.buildRole()
    ab.buildSex()
    ab.buildFace()
    ab.buildCostume()
    if (!ab.BareHead) {
      ab.buildHairStye()
    }
    ab.creatActor()
  }
}

class Actor {
  var role: String = _
  var sex: String = _
  var face: String = _
  var costume: String = _
  var hairStye: String = "光头"
}

object HeroBuilder extends ActorBuilder {

  override protected var actor: Actor = new Actor()

  override def buildRole() = actor.role = "英雄"

  override def buildSex() = actor.sex = "男"

  override def buildFace() = actor.face = "英俊"

  override def buildCostume() = actor.costume = "盔甲"

  override def buildHairStye() = actor.hairStye = "飘逸"

  override def creatActor() = actor
}

object DevilBuilder extends ActorBuilder {
  override protected var actor: Actor = new Actor()

  override def buildRole() = actor.role = "恶魔"

  override def buildSex() = actor.sex = "妖"

  override def buildFace() = actor.face = "丑陋"

  override def buildCostume() = actor.costume = "黑衣"

  override def buildHairStye() = actor.hairStye = "我想要头发"

  /**
   * 由于钩子程序的存在并不会执行buildHairStyle
   */
  override val BareHead = true
  override def creatActor() = actor
}

/**
 * 测试客户端
 */

object Client5 extends App {
  val ab1: ActorBuilder = HeroBuilder
  val actor1 = ab1.construct(ab1)
  println(actor1.sex)

  val ab2: ActorBuilder = DevilBuilder
  val actor2 = ab2.construct(ab2)
  println(actor2.sex)
}


6.原型模式 prototype

结构解析:
原型类
原型实现类  java中是重写clone函数让类课被复制
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.

原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
 
   
/**
 * 样例类:周报
 */
case class WeeklyLog(var name: String, var date: String, var context: String, var attachment: Attachment)

/**
 * 附件类样例
 */

case class Attachment(var name: String) {
  def download() = println(s"下载附件,附件名为:$name")
}

//object Client6 extends App { //不使用原型
//  var log_previous = new WeeklyLog("王颖", "周六", "报告内容", new Attachment("报告.ppt"))
//  val log_new = log_previous.copy()
//  /**
//   * 结果为false,由此可以看出为深克隆
//   *   Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中。那么什么是深克隆,什么是浅克隆呢。
//   *
//   *   【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。
//   *
//   *   【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。
//   */
//  println(log_new.eq(log_previous))
//
//  /**
//   * 结果为true,附件对象为浅克隆
//   */
//  println(log_new.attachment.eq(log_previous.attachment))
//}

/**
 * 原型管理器
 */

//*************以下为使用原型

case class OfficeDocument(title: String) {
  def display(): Unit = { println(s"公文标题为:$title") }
}

/**
 * 可行性分析报告
 */

class FAR(title: String) extends OfficeDocument(title)

/**
 * 软件需求规格书
 */
class SRS(title: String) extends OfficeDocument(title)

object PrototypeManager {
  //存储officedocument对象
  var ht = new scala.collection.mutable.HashMap[String, OfficeDocument]

  ht += ("far" -> new FAR("<可行性报告>"))
  ht += ("srs" -> new SRS("<软件规格需求说明书>"))

  //增加文章模板
  def addOfficeDucoment(key: String, officeDocument: OfficeDocument) = ht += (key -> officeDocument)

  //获取模板

  def getOfficeDocument(key: String): OfficeDocument = ht.getOrElse(key, new OfficeDocument("null")).copy()

}

/**
 * 测试客户端
 */
object Client6 extends App {
  //原型管理器

  val pr = PrototypeManager
  //公文对象  从hashmap中获取克隆对象
  val doc1 = pr.getOfficeDocument("")
  val doc2 = pr.getOfficeDocument("")

  doc1.display()
  doc2.display()

  println(doc1.equals(doc2))
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值