zoukankan      html  css  js  c++  java
  • Java设计模式简介--策略模式--工厂方法模式--详细请看其他的两篇文章

    ------------------------- strategy(策略模式) -------------------------
    我们有一个设计原则:
    找出应用中相同之处,且不容易发生变化的东西,把它们抽取到抽象类中,让子类去继承它们;
    找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

    简单来说:

    1.就是把相同的方法,而且不用怎么改动的,放到一个抽象类中

      比如:

      

     鸭子具有如下行为:叫声(duack),游泳(Swimming),会飞(fly),外观显示(display

    叫声:可能有两种:吱吱叫和嘎嘎叫

    游泳:只有一种方式

    会飞:会不会飞

    外观显示:有红头鸭,有普通鸭

     

    需要进行如下设计:

    把duack和fly用接口表示,然后创建两个类分别实现,比如:

    public interface FlyBehavior{
         public void fly();     
     }
     public interface QuackBehavior{
         public void quack();
     }

     我们在定义一些针对FlyBehavior的具体实现。
     public class FlyWithWings implements FlyBehavior{
        public void  fly(){
         //
    实现了所有有翅膀的鸭子飞行行为。
       }
     }

    public class FlyNoWay implements FlyBehavior{
     
        public void  fly(){
          //
    什么都不做,不会飞
        }
     }   

    针对QuackBehavior的几种具体实现。
    public class Quack implements QuackBehavior{
        public void quack(){
          //
    实现呱呱叫的鸭子
      }
    }
     
    public class Squeak implements QuackBehavior{
        public void quack(){
          //
    实现吱吱叫的鸭子 
      }
    }
     
    public class MuteQuack implements QuackBehavior{
        public void quack(){
          //
    什么都不做,不会叫
      }
    }

    点评一:
    这样的设计,可以让飞行和呱呱叫的动作被其他的对象复用,因为这些行为已经与鸭子类无关了。而我们增加一些新

    的行为,不会影响到既有的行为类,也不会影响“使用”到飞行行为的鸭子类。

    最后我们看看Duck 如何设计。
    public class Duck{        --------->
    在抽象类中,声明各接口,定义各接口对应的方法.
          FlyBehavior flyBehavior;//
    接口
          QuackBehavior quackBehavior;//
    接口
           public Duck(){}
           public abstract void display();
           public void swim(){
            //
    实现游泳的行为
            }

    Public void setFlyBehavior(FlyBehavior flyBehovior) {

             This.flyBehavior = flyBehovior;

    }

     

    Public void setQuackBehavior(QuackBehovior quackBehovior) {

             This.quackBehovior = quackBehovior;

    }
           public void performFly(){
                flyBehavior.fly();  -->
    由于是接口,会根据继承类实现的方式,而调用相应的方法.
         }
         public void performQuack(){
              quackBehavior.quack();();
        }
     }

     

     

    class DuackTest extends Duack {

     

       @Override

       public void display() {

          System.out.println("this is redheadduack---");

       }

      

      

    }

    public class StrategyTest {

       public static void main(String[] args) {

          FlyBehavior flyable = new FlyWin();

          QuackBehavior duackable = new DuackZhi();

     

          DuackTest duackTest = new DuackTest();

          duackTest. setFlyBehavior(flyable);

          duacktest.setDuackBehavior(duackable);

          duackTest.isFly();

          duackTest.isDuack();

          duackTest.display();

       }

    }

     

    2.工厂方法模式(一般使用静态工厂模式)

    1、工厂方法模式(Factory Method)

    工厂方法模式分为三种:

    11、普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图:

    举例如下:(我们举一个发送邮件和短信的例子)

    首先,创建二者的共同接口:

    1. public interface Sender {  
    2.     public void Send();  
    3. }  

    其次,创建实现类:

    1. public class MailSender implements Sender {  
    2.     @Override  
    3.     public void Send() {  
    4.         System.out.println("this is mailsender!");  
    5.     }  
    6. }  
    1. public class SmsSender implements Sender {  
    2.   
    3.     @Override  
    4.     public void Send() {  
    5.         System.out.println("this is sms sender!");  
    6.     }  
    7. }  

    最后,建工厂类:

    1. public class SendFactory {  
    2.   
    3.     public Sender produce(String type) {  
    4.         if ("mail".equals(type)) {  
    5.             return new MailSender();  
    6.         } else if ("sms".equals(type)) {  
    7.             return new SmsSender();  
    8.         } else {  
    9.             System.out.println("请输入正确的类型!");  
    10.             return null;  
    11.         }  
    12.     }  
    13. }  

    我们来测试下:

    1. public class FactoryTest {  
    2.   
    3.     public static void main(String[] args) {  
    4.         SendFactory factory = new SendFactory();  
    5.         Sender sender = factory.produce("sms");  
    6.         sender.Send();  
    7.     }  
    8. }  

    输出:this is sms sender!

    22、多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:

    将上面的代码做下修改,改动下SendFactory类就行,如下:

    [java] view plaincopypublic class SendFactory {  
       public Sender produceMail(){  
    1.         return new MailSender();  
    2.     }  
    3.       
    4.     public Sender produceSms(){  
    5.         return new SmsSender();  
    6.     }  
    7. }  

    测试类如下:

    1. public class FactoryTest {  
    2.   
    3.     public static void main(String[] args) {  
    4.         SendFactory factory = new SendFactory();  
    5.         Sender sender = factory.produceMail();  
    6.         sender.Send();  
    7.     }  
    8. }  

    输出:this is mailsender!

    33、静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

    1. public class SendFactory {  
    2.       
    3.     public static Sender produceMail(){  
    4.         return new MailSender();  
    5.     }  
    6.       
    7.     public static Sender produceSms(){  
    8.         return new SmsSender();  
    9.     }  
    10. }  
    1. public class FactoryTest {  
    2.   
    3.     public static void main(String[] args) {      
    4.         Sender sender = SendFactory.produceMail();  
    5.         sender.Send();  
    6.     }  
    7. }  

    输出:this is mailsender!

    总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

  • 相关阅读:
    net core 使用 rabbitmq
    asp.net core WebApi 返回 HttpResponseMessage
    asp.net core 2.1 WebApi 快速入门
    JQuery EasyUI combobox动态添加option
    php截取字符去掉最后一个字符
    JQuery EasyUI Combobox的onChange事件
    对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
    Access2007 操作或事件已被禁用模式阻止解决办法
    Easyui 中 Tabsr的常用方法
    Win 7 IE11不能下载文件,右键另存为也不行
  • 原文地址:https://www.cnblogs.com/handsome1013/p/5307115.html
Copyright © 2011-2022 走看看