JAVA23种设计模式(1)-创造型模式6种

JAVA23种设计模式(1)-创造型模式6种

1.设计模式的正确打开方式:

设计模式是由多年来从事开发设计工作的工程师对一些普遍问题的通用解决方式,算考试的话,也许它就是标准答案, 对于面向对象的程序员来说,在他的架构之路上,能理解并用活设计模式绝对是受益匪浅的一件事情,当然也不是所有的代码都必须使用设计模式去做,简单的项目工程是不需要设计模式.
而然,在漫长的迭代开发中,设计模式的一些思维是可以很好地帮助我们去重构工程架构,而到达节省大量开发和测试的时间,设计模式可以说面向对象编程的精髓,是架构师的进阶之路.当然对设计模式的掌握绝对不是记住或者背下来套用.
最好的方式,是根据自己项目的需求,从学过的模式中得到启发,把模式的思想贯彻在自己的工程中.但这并不是容易的事情,如果抽空看一下android系统源代码以及第3方开源库,大神们的代码中有都有设计模式的影子.所以这是一个长期学习的过程

2.设计模式的思想的理解:

模式的思想的核心是着眼于长期开发,对于长期中可能需要变更的代码,用接口或者抽象在业务逻辑中与其他类进行交互,也即是需要变化的代码和不变的代码要分隔开,浓缩成两字: 解耦

3.设计模式的6个原则:
 3.1 开闭原则:对修改关闭,对拓展开放,这是最核心原则,需求改动不要通过修改,而是通过扩展.
 3.2 里氏替换原则:代码中子类出现的地方,父类就能出现
 3.3 依赖倒转原则:针对于接口或者抽象编程,而不针对于具体实现类
 3.4 接口隔离原则:每个接口中最好只定义一个函数
 3.5 迪米特原则:一个实体应当尽可能少的与其他实体发生相互作用
 3.6 合成/复用原则:多用合成,少用复用

 原则的意思就是尽量往上靠拢,而不是严格要求,就好像为减少工程内存开销,要少用静态(static)和服务,以及少开线程一样,工程设计是要找最优解而不死硬
4.创造型设计模式(6种)
4.1单例模式(Singleton最常用):
   一句话:确保一个类只有一个实例,并提供一个全局访问点

public class Singleton
{
    private static Singleton instance/*=new Singleton()*/;//饱汉式,适合开销较小的实体类
    private Singleton(){}//构造函数私有保证无法调用

    //饿汉式
    public static Singleton getInstance()
    {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}
4.2 原型模式(Prototype):
一句话:通过复制现有实例来创建新的实例,无需知道相应类的信息

即是 通过调用object.clone()来实例大数量对象而不是通过构造函数来new一个,与单例相对,两者不可以用在一起.比起你new一个,然后再赋值同样的数据当然要好很多.

clone是一个非常复杂的过程,JVM在进行new时到达底层代码其实就是C的 malloc数据空间,然后再做一系列的初始化操作,而初始化的操作有可能会多次malloc,因为只能构造执行时才知道这个对象整个需要的空间。而clone她已经知道整个数据空间的大小,可以直接malloc一整块数据空间,然后调用如memcopy这样的操作,把内存复制,当然实际没这么简单,而浅clone时memcopy的,就是指针地址,而深clone,就需要为每个数据再次去malloc数据空间,再进行memcpy内存数据。( 大神指点改进咯!)

适用场合:就是需要复制一个与原型实例相同数据与结构相同的实例

就像set中必须要实现equals这个方法一样,使用clone()这个方法必须要在类中复写clone这个方法,并且类要实现cloneable这个接口

Object的clone方法只会拷贝对象中的基本的数据类型,对于数组\容器\引用对象都不会拷贝,这就是浅拷贝.如果要实现深拷贝,必须将原型模式中的数组,容器对象,引用对象另行拷贝

//深度克隆
 public class Human implements Cloneable
{
    private String name;
    private String sex;
    private ArrayList<String> familyMember;
    @Override
    protected Object clone()  
    {
        Human human=null;
        try
        {
            human= (Human)super.clone();
            //数组\容器\引用对象 深度拷贝
            human.familyMember= (ArrayList<String>) familyMember.clone();
            return human;
        }
        catch (CloneNotSupportedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return human;

    }   
    public Human ( String name,String sex,ArrayList<String> familyMember) {
        this.name=name;
        this.sex=sex;
        this.familyMember=familyMember;
    }
}
//浅度克隆
 public class Human implements Cloneable
{
    private String name;
    private String sex;
    @Override
    protected Object clone()  
    {
        Human human=null;
        try
        {
            human= (Human)super.clone();
            //  浅度拷贝,只需要将引用克隆即可

            return human;
        }
        catch (CloneNotSupportedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return human;

    }   
    public Human ( String name,String sex ) {
        this.name=name;
        this.sex=sex;
    }
}
4.3 简单工厂(SimpleFactory):

一句话:定义一个创建对象的类,由这个类来封装实例化对象的行为

工厂模式很好体现了依赖倒转原则,逻辑代码中针对接口编程而非实例,实例化集中在工厂中也方便管理和扩展
//1.定义一个产品类的接口
 public interface Car {
    void drive();
}
//2.定义产品1
public class Benz implements Car{
    @Override
    public void drive() {
        System.out.println("drive a Benz"); 
    }
}
//3.定义产品2
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("drive a BMW"); 
    }
}
//4.提供静态方式生成
public class Factory {
    public static Car createCar(String brand)
    {
         if("Benz".equals(brand))
         {
             return new Benz();

         }else if("BMW".equals(brand))
         {
             return new BMW();
         }
       return null; 
    }
}
//5.测试使用,使用接口操作而非实例
public class Main {
    public static void main(String[] args) {
        Car car =Factory.createCar("Benz");
        car.drive();
    }
}
4.4 工厂方法模式(SimpleMethod):

一句话:定义一个工厂接口,由工厂子类决定要实例化的产品类,工厂方法模式将对象的实例化推迟到子类

  实际通过工厂子类分出产品的族系
//1.定义一个工厂接口
public interface Factory {
    Car createCar(String brand);
}
//2.定义工厂子类1--中国工厂
public class ChinaFactory implements Factory {

    @Override
    public Car createCar(String brand) {
        if("Benz".equals(brand))
        {
            return new Benz();

        }else if("BMW".equals(brand))
        {
            return new BMW();
        }
        return null; 
    }
}
//3.定义工厂实现类2--欧洲工厂
public class EuropeanFactory implements Factory {
    @Override
    public Car createCar(String brand) {
        if("Benz".equals(brand))
        {
            return new Benz();

        }else if("BMW".equals(brand))
        {
            return new BMW();
        }
      return null; 
    }
}
//4.定义产品接口
public interface Car {
    void drive();
}
//5.定义产品实现类1.宝马
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("drive a BMW");
    }
}

//6.定义产品实现类2.奔驰
public class Benz implements Car{
    @Override
    public void drive() {
        System.out.println("drive a Benz");
    }
}
//测试
public class Main {
    public static void main(String[] args) {
        //中国产地 产品族系的奔驰
       Car car1= new ChinaFactory().createCar("Benz");
       car1.drive();
       //欧洲产品族系的奔驰 
       Car car2=new EuropeanFactory().createCar("Benz");
       car2.drive();
    }
}
4.5 抽象工厂模式(AbstractFactory):

一句话:定义一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类

工厂方法模式和抽象工厂模式不好分清楚,他们的区别如下:

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。

区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

对于过于复杂的创建留给了创建者模式
//1.定义产品1接口
public interface Car {
    void drive();
}
//2.定义产品1实现类1.宝马
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("drive a BMW");

    }
}
//3.定义产品1实现类2.奔驰
public class Benz implements Car{
    @Override
    public void drive() {
        System.out.println("drive a Benz");

    }
}
//4.定义产品2接口
public interface Motor {
    void playShow();
}
//5.定义产品2实现类1--嘉陵摩托车
public class JialinMotor implements Motor {
    @Override
    public void playShow() {
           System.out.println("play a shower with JialinMotor");
    }
}
//6.定义产品2实现类2--哈雷摩托车
public class HarleyMotor implements Motor {
    @Override
    public void playShow() {
        System.out.println("play a shower with HarleyMotor");
    }
}
//7.定义工厂接口(与上个方法相比多出了创建motor)
public interface Factory {
    Car createCar(String brand);
    Motor createMotor(String brand);
}
//8.工厂实现类1.中国工厂
public class ChinaFactory implements Factory {
    @Override
    public Car createCar(String brand) {
        if("Benz".equals(brand))
        {
            return new Benz();

        }else if("BMW".equals(brand))
        {
            return new BMW();
        }
        return null; 
    }
    @Override
    public Motor createMotor(String brand) {
        if("Jialin".equals(brand))
        {
            return new JialinMotor();

        }else if("Harley".equals(brand))
        {
            return new HarleyMotor();
        }
        return null; 
    }
}
// 9.工厂实现类2--欧洲工厂
public class EuropeanFactory implements Factory {
    @Override
    public Car createCar(String brand) {
        if("Benz".equals(brand))
        {
            return new Benz();

        }else if("BMW".equals(brand))
        {
            return new BMW();
        }
      return null; 
    }

    @Override
    public Motor createMotor(String brand) {
        if("Jialin".equals(brand))
        {
            return new JialinMotor();

        }else if("Harley".equals(brand))
        {
            return new HarleyMotor();
        }
        return null; 
    }
}
//10.测试
public class Main {
    public static void main(String[] args) {

        Factory chinaFactory=new ChinaFactory();
        Factory europeanFactory=new EuropeanFactory();

        //中国产地  生成的奔驰
       Car car1= chinaFactory.createCar("Benz");
       car1.drive();
       //中国产地  生成的哈雷摩托车
       Motor motor1= chinaFactory.createMotor("Harley");
       motor1.playShow();

       //欧洲产地 生成的宝马
       Car car2=europeanFactory.createCar("BMW");
       car2.drive();

       //中国产地  生成的嘉陵摩托车
       Motor motor2= europeanFactory.createMotor("Jialin");
       motor2.playShow();
    }
}
4.6建造者模式(Builder):

一句话:封装一个复杂对象构造过程,并允许按步骤构建

比如,android中的dialog的组件就是用builder去create出来的,使用的过程就是可以把标题,按键,内容,事件等等作为组件一个一个添加到dialog中去生成,生成器模式本身需要和其他模式结合使用,最经常结合的就是模板模式(用于生成具体的子类),其他要根据实际情况而定。

看过最通俗的理解是这样的:就好象我要一座房子住,可是我不知道怎么盖(简单的砌墙,层次较低),也不知道怎么样设计(建几个房间,几个门好看,层次较高), 于是我需要找一帮民工,他们会砌墙,还得找个设计师,他知道怎么设计,我还要确保民工听设计师的领导,而设计师本身也不干活,光是下命令,这里砌一堵墙,这里砌一扇门,这样民工开始建设,最后,我可以向民工要房子了。在这个过程中,设计师是什么也没有,除了他在脑子里的设计和命令,所以要房子也是跟民工要,记住了!就象国内好多企业上erp一样,上erp,首先得找软件公司呀,找到软件公司后,软件公司说,我只知道怎么写软件,就知道怎么实现,不清楚整个erp的流程。好,那我们还得找一个咨询公司,好,找到德勤了,德勤说好,我要软件怎么做,软件公司怎么做,我就能保证软件能为你们提供erp系统了。

此模式是为了让设计和施工解耦,互不干扰。
//1.设计师,可以表示生成环境
 public class Designer {
    public Designer() {
    }
    public void order(Builder builder) {
        builder.makeWindow();
        builder.makeFloor();
    }
}
//2.建造者接口
public interface Builder {
    public void makeWindow();
    public void makeFloor();
    public Room getRoom();
}
//3.建造者实现类--建造者(包括了我们对产品的要求)
public class Mingong implements Builder {
    private String window = "";
    private String floor = "";
    public Mingong() {
    }
    public void makeWindow() {
        window = new String("window");
    }
    public void makeFloor() {
        floor = new String("floor");
    }
    public Room getRoom() {
        if ((!window.equals("")) && (!floor.equals(""))) {
            Room r = new Room();
            r.setFloor(floor);
            r.setWindow(window);
            return r;
        } else
            return null;
    }
}
//4.产品
public class Room {
    private String window = "";
    private String floor = "";
    public Room() {
    }

    public String getFloor() {
        return floor;
    }

    public void setFloor(String floor) {
        this.floor = floor;
    }

    public String getWindow() {
        return window;
    }

    public void setWindow(String window) {
        this.window = window;
    }
}
//5.生成过程-在这个设计师(环境)生成者构建出一个产品
public class Client {
    public Client() {
    }
    public static void main(String[] args) {
        Builder mingong = new Mingong();
        Designer designer = new Designer();
        designer.order(mingong);
        Room r = mingong.getRoom();
        System.out.println(r.getWindow);// 会输出window,表示构建成功。
    }
}
 这个模式是专业造轮子用得上,关键是理解一下面向对象的核心思想,把环境,构建过程,产品要求给分开

欢迎加入技术博客达人群-235496381 互相交流,这里有技术美女调戏,有开发小哥勾搭
我是”努力的人最幸运”!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值