精华内容
下载资源
问答
  • 题目:在某OA系统中,用户可以创建工作周报,由于某些岗位周周工作存在重复性,因此可以通过复制原有工作周报并进行局部修改来快速新建工作周报。 类图 package cn.factory4; public class ...

    题目:在某OA系统中,用户可以创建工作周报,由于某些岗位周周工作存在重复性,因此可以通过复制原有工作周报并进行局部修改来快速新建工作周报。

    类图


    package cn.factory4;
    
    public class JobWeekly implements Cloneable {
        private String time;
        private String weekly;
        private String keypoint;
        private String mainbody;
        
        public void set(String time,String weekly,String keypoint, String mainbody){
            this.time = time;
            this.weekly = weekly;
            this.keypoint = keypoint;
            this.mainbody = mainbody;
        }
        
        public Object clone(){
            JobWeekly jobweekly = null;
            try {
            	jobweekly = (JobWeekly) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return jobweekly;
        }
        
        public void display(){
        	System.out.print("时间:"+time+"  周数:"+weekly+"  本周重点:"+keypoint+"  正文:"+mainbody);
        }
    
    }
    package cn.factory4;
    
    public class ConcretePrototype implements Cloneable{
    	public Object clone(){
    	Object object = null;
    	try {
    		object = super.clone();
    	} catch (CloneNotSupportedException exception) {
    		System.err.println("Not support cloneable");
    	}
    		return object;
    	}
    }
    package cn.factory4;
    
    public class Client {
        public static void main(String[] args) {
            //原型A对象
            JobWeekly a = new JobWeekly();
            a.set("2015.10.24", "15", "重点是...", "正文是...");
            
            //克隆B对象
            JobWeekly b = (JobWeekly) a.clone();
            
            //输出A和B对象
            System.out.println("----------------A--------------");
            a.display();
            System.out.println();
            System.out.println("----------------B--------------");
            b.display();
            System.out.println();
        }
    }
    
    运行效果图


    展开全文
  • 设计模式创建模式

    千次阅读 2019-03-31 12:17:53
    设计模式创建模式:单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式、建造者模式

    一、简介

    创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题。

    创建型模式(Creational Pattern)

    • 单例模式 Singleton Pattern: 单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
      使用频率:★★★★☆

    • 简单工厂模式 Simple Factory Pattern: 又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
      使用频率:★★★☆☆

    • 工厂方法模式 Factory Method Pattern: 是一种常用的类创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。
      使用频率:★★★★★

    • 抽象工厂模式 Abstract Factory Pattern: 是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
      使用频率:★★★★★

    • 原型模式 Prototype Pattern: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
      使用频率:★★★☆☆

    • 建造者模式 Builder Pattern: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
      使用频率:★★☆☆☆

    二、单例模式

    2.1、饿汉式

    /**
     * 单例模式(饿汉式)
     * 线程安全,没有加锁,执行效率会提高。
     * 类加载时就初始化,浪费内存,容易产生垃圾对象
     * <p>
     * 单例类使用了final修饰,防止被继承
     * 这种写法比较简单,就是在类装载的时候就完成实例化。instance作为类变量,在类初始化过程中,会被收集进<clinit>()方法中,该方法会保障同步,从而避免了线程同步问题。
     * 在类装载的时候就完成实例化,若从未使用过这个实例,则会造成内存的浪费。
     */
    public final class SingleObject1 {
        //创建 SingleObject1 的一个对象
        private static SingleObject1 instance = new SingleObject1();
        //私有化构造函数,这样该类就不会被实例化
        private SingleObject1() {}
        //获取唯一可用的对象
        public static SingleObject1 getInstance() {
            return instance;
        }
        public void say() {
            System.out.println("Hello");
        }
    }
    
    ……
    //调用
    SingleObject1.getInstance().say();//Hello
    

    2.2、懒汉式,线程不安全

    /**
     * 单例模式(懒汉式,线程不安全)
     * 线程不安全,没有加锁。
     * 此方式在确定是单线程的情况下,可以保证创建的对象唯一性
     */
    public final class SingleObject2 {
        //创建 SingleObject1 的一个对象
        private static SingleObject2 instance;
        //私有化构造函数,这样该类就不会被实例化
        private SingleObject2() {}
        //获取唯一可用的对象
        public static SingleObject2 getInstance() {
            if (instance == null) {
                instance = new SingleObject2();
            }
            return instance;
        }
        public void say() {
            System.out.println("Hello");
        }
    }
    
    ……
    //调用
    SingleObject2.getInstance().say();//Hello
    

    2.3、懒汉式,线程安全

    /**
     * 单例模式(懒汉式,线程安全)
     * 线程安全,加锁,执行效率低
     */
    public final class SingleObject3 {
        //创建 SingleObject1 的一个对象
        private static SingleObject3 instance;
        //私有化构造函数,这样该类就不会被实例化
        private SingleObject3() {}
        //获取唯一可用的对象
        public synchronized static  SingleObject3 getInstance() {
            if (instance == null) {
                instance = new SingleObject3();
            }
            return instance;
        }
        public void say() {
            System.out.println("Hello");
        }
    }
    
    ……
    //调用
    SingleObject3.getInstance().say();//Hello
    

    2.4、双检锁/双重校验锁

    /**
     * 单例模式(双检锁/双重校验锁)
     * 线程安全
     * 种方式采用双锁机制,安全且在多线程情况下能保持高性能
     */
    public final class SingleObject4 {
        //创建 SingleObject1 的一个对象
        private volatile static SingleObject4 instance;
        //私有化构造函数,这样该类就不会被实例化
        private SingleObject4() {}
        //获取唯一可用的对象
        public static SingleObject4 getInstance() {
            if (instance == null) {
                synchronized (SingleObject4.class) {
                    if (instance == null) {
                        instance = new SingleObject4();
                    }
                }
            }
            return instance;
        }
        public void say() {
            System.out.println("Hello");
        }
    }
    
    ……
    //调用
    SingleObject4.getInstance().say();//Hello
    

    2.5、静态内部类方式

    /**
     * 单例模式(静态内部类实现模式)
     * 线程安全,调用效率高,可以延时加载
     * 这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。
     * 这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。
     * 这种方式同样利用了 classloader 机制来保证初始化 instance 时只有一个线程,
     * <p>
     * 静态内部类方式是最好也是最常用的几种实现单例模式的方式之一
     */
    public final class SingleObject5 {
    
        private static class SingleObject5Holder {
            private static final SingleObject5 instance = new SingleObject5();
        }
        //私有化构造函数,这样该类就不会被实例化
        private SingleObject5() {}
        //获取唯一可用的对象
        public static SingleObject5 getInstance() {
            return SingleObject5Holder.instance;
        }
        public void say() {
            System.out.println("Hello");
        }
    }
    
    ……
    //调用单例
    SingleObject5.getInstance().say();//Hello
    

    2.6、枚举方式

    /**
     * 单例模式(枚举方式,Android不推荐)
     * 线程安全,调用效率高,不能延时加载,可以防止反射和反序列化调用
     * 这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
     * 这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,
     * 防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。
     * 不能通过 reflection attack 来调用私有构造方法。
     *
     * 枚举实现单例,不推荐在Android平台使用,因为内存消耗会其他方式多一些,Android官方也不推荐枚举,
     * Android平台推荐双重校验或者静态内部类单例,现在的Android开发环境jdk一般都大于1.5了。所以volatile的问题不必担心。
     * Java平台开发的Effective Java一书中推荐使用枚举实现单例,可以保证效率,而且还能解决反序列化创建新对象的问题。
     */
    public  enum SingleObject6 {
        INSTANCE;
    
        public void say() {
            System.out.println("Hello");
        }
    }
    
    ……
    //调用单例
    SingleObject6.INSTANCE.say();//Hello
    

    三、简单工厂模式

    3.1、定义接口

    定义人接口,吃的动作方法.

    public interface Human {
      	//吃动作
        void eat();
    }
    

    3.2、定义具体实现

    定义中国人.

    public class Chinese implements Human {
        @Override
        public void eat() {
            System.out.println("中国人吃饭");
        }
    }
    

    定义美国人.

    public class American implements Human {
        @Override
        public void eat() {
            System.out.println("美国人吃饭");
        }
    }
    

    3.3、定义工厂类

    方式一: 通过type创建工厂类

    public class HumanFactory {
        public static String CHINESE_HUMAN = "CHINESE_HUMAN";
        public static String AMERICAN_HUMAN = "AMERICAN_HUMAN";
    
        /**
         * 创建人类工厂方法
         * @param type {@link #CHINESE_HUMAN}、{@link #AMERICAN_HUMAN}
         * @return 人类
         */
        public Human createHuman(@NotNull String type) {
            if (type.equals(CHINESE_HUMAN)) {
                return new Chinese();
            } else if (type.equals(AMERICAN_HUMAN)) {
                return new American();
            }
            return null;
        }
    }
    

    方式二: 通过java反射方式创建工厂类

    public class HumanFactory2 {
        /**
         * 创建人类工厂方法
         * @param c 中国人、美国人
         * @param <T> 
         * @return 人类
         */
        public <T extends Human> T  createHuman(Class<T> c) {
            T t=null;
            try {
                t = (T) Class.forName(c.getName()).newInstance();
            } catch (InstantiationException e) {
                System.out.println("不支持抽象类或接口");
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                System.out.println("没有足够权限,即不能访问私有对象");
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                System.out.println("类不存在");
                e.printStackTrace();
            }
            return t;
        }
    }
    

    3.5、使用简单工厂模式

    public static void main(String[] args) {
        //----------------------方式一------------------------------
        //创建工厂类
        HumanFactory humanFactory=new HumanFactory();
        //创建美国人
        Human human1 = humanFactory.createHuman(HumanFactory.AMERICAN_HUMAN);
        human1.eat();//美国人吃饭
        //创建中国人
        Human human2 = humanFactory.createHuman(HumanFactory.CHINESE_HUMAN);
        human2.eat();//中国人吃饭
        
        //----------------------方式二------------------------------
         HumanFactory2 humanFactory2 = new HumanFactory2();
         Human human3 = humanFactory2.createHuman(American.class);
         human3.eat();//美国人吃饭
         Human human4 = humanFactory2.createHuman(Chinese.class);
         human4.eat();//中国人吃饭
    }
    

    四、工厂方法模式

    4.1、定义接口

    定义人接口,吃的动作方法.

    public interface Human {
      	//吃动作
        void eat();
    }
    

    定义工厂类接口

    //工厂接口类
    public interface Factory {
        //创建人类
        Human createHuman();
    }
    

    4.2、定义具体实现

    定义中国人.

    public class Chinese implements Human {
        @Override
        public void eat() {
            System.out.println("中国人吃饭");
        }
    }
    

    定义美国人.

    public class American implements Human {
        @Override
        public void eat() {
            System.out.println("美国人吃饭");
        }
    }
    

    定义中国人工厂类

    //中国人工厂类
    public class ChineseFactory implements Factory {
        @Override
        public Human createHuman() {
            return new Chinese();
        }
    }
    

    定义美国人工厂类

    //美国人工厂类
    public class AmericanFactory implements Factory{
        @Override
        public Human createHuman() {
            return new American();
        }
    }
    

    4.3、使用工厂方法模式

    public static void main(String[] args) {
        Factory factory1 = new AmericanFactory();
        Human human1 = factory1.createHuman();
        human1.eat();//美国人吃饭
    
        Factory factory2 = new ChineseFactory();
        Human human2 = factory2.createHuman();
        human2.eat();//中国人吃饭
    }
    

    五、抽象工厂模式

    5.1、定义接口

    定义人接口,吃的动作方法.

    public interface Human {
      	//吃动作
        void eat();
    }
    

    定义水果接口

    //水果接口
    public interface Fruits {
        //水果名称
        String name();
    }
    
    

    定义工厂接口,每个工厂都有制造人和苹果方法

    //工厂接口
    public interface Factory {
        //创建人类
        Human createHuman();
        //创建水果
        Fruits createFruits();
    }
    

    5.2、定义具体实现

    定义中国人

    public class Chinese implements Human {
        @Override
        public void eat() {
            System.out.println("中国人吃饭");
        }
    }
    

    定义美国人

    public class American implements Human {
        @Override
        public void eat() {
            System.out.println("美国人吃饭");
        }
    }
    

    定义苹果

    //苹果实体
    public class Apple implements Fruits{
        @Override
        public String name() {
            System.out.println("苹果");
            return "苹果";
        }
    }
    

    定义葡萄

    //葡萄实体
    public class Grape implements Fruits {
        @Override
        public String name() {
            System.out.println("葡萄");
            return "葡萄";
        }
    }
    

    定义制造中国人和苹果的工厂

    //制造工厂A 制造中国人和苹果
    public class CreateFactoryA  implements Factory{
        @Override
        public Human createHuman() {
            return new Chinese();
        }
        @Override
        public Fruits createFruits() {
            return new Apple();
        }
    }
    

    定义制造美国人和葡萄的工厂

    //制造工厂B 制造美国人和葡萄
    public class CreateFactoryB implements Factory{
        @Override
        public Human createHuman() {
            return new American();
        }
        @Override
        public Fruits createFruits() {
            return new Grape();
        }
    }
    
    

    5.3、使用抽象工厂模式

      public static void main(String[] args) {
            Factory factory1=new CreateFactoryA();
            Human human = factory1.createHuman();
            Fruits fruits = factory1.createFruits();
            human.eat();//中国人吃饭
            fruits.name();//苹果
    
            Factory factory2=new CreateFactoryB();
            Human human2 = factory2.createHuman();
            Fruits fruits2 = factory2.createFruits();
            human2.eat();//美国人吃饭
            fruits2.name();//葡萄
        }
    

    六、原型模式

    原型模式是一个创建型的模式。原型二字表明了改模式应该有一个样板实例,用户从这个样板对象中复制一个内部属性一致的对象,这个过程也就是我们称的“克隆”。被复制的实例就是我们所称的“原型”,这个原型是可定制的。原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效。

    6.1、浅拷贝实现原型模式

    新建Book类实现Cloneable接口,复写clone方法

    //书原型(浅拷贝)
    public class Book implements Cloneable {
        //书名
        private String title;
        //书页数
        private ArrayList<String> page = new ArrayList<String>();
    
        public Book() {
            //一个实现了Cloneable并重写了clone方法的类,通过clone得到对象构造函数是不会被执行
            System.out.println("构造函数被执行了");
        }
    
        @Override
        protected Book clone() {
            try {
                return (Book) super.clone();
            } catch (CloneNotSupportedException e) {
                //异常处理
                e.printStackTrace();
                return null;
            }
        }
    
        public String getTitle() {return title;}
    
        public void setTitle(String title) {this.title = title;}
    
        public List<String> getPage() {return page;}
    
        public void addPage(String page) {this.page.add(page);}
    
        @Override
        public String toString() {
            return "Book{" +"title='" + title + '\'' +", page=" + page +'}';
        }
    }
    

    测试原型模式

    //浅拷贝测试
    Book book = new Book();
    book.setTitle("Java");
    book.addPage("Java第1章");
    System.out.println(book.toString());//Book{title='Java', page=[Java第1章]}
    
    Book cloneBook = book.clone();
    cloneBook.setTitle("Android");
    cloneBook.addPage("Android第1章");
    System.out.println(cloneBook.toString());//Book{title='Android', page=[Java第1章, Android第1章]}
    
    // 再次打印原始书本发现原书信息被修改(因为Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、集合、容器对象、引用对象等都不会拷贝,需要使用深拷贝解决)
    System.out.println(book.toString());//Book{title='Java', page=[Java第1章, Android第1章]}
    

    6.2、深拷贝实现原型模式

    新建Book类实现Cloneable接口,复写clone方法,因为Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、集合、容器对象、引用对象等都不会拷贝,需要将page进行深度拷贝.

    //书原型(深拷贝)
    public class Book2 implements Cloneable {
        //书名
        private String title;
        //书页数
        private ArrayList<String> page = new ArrayList<String>();
    
        @Override
        protected Book2 clone() {
            try {
                Book2 book2 = (Book2) super.clone();
                book2.page= (ArrayList<String>) this.page.clone();
                return book2;
            } catch (CloneNotSupportedException e) {
                //异常处理
                e.printStackTrace();
                return null;
            }
        }
    
        public String getTitle() {return title;}
    
        public void setTitle(String title) {this.title = title;}
    
        public List<String> getPage() {return page;}
    
        public void addPage(String page) {this.page.add(page);}
    
        @Override
        public String toString() {
            return "Book{" +"title='" + title + '\'' +", page=" + page +'}';
        }
    }
    

    测试原型模式

    //深拷贝测试
    Book2 book2 = new Book2();
    book2.setTitle("Java");
    book2.addPage("Java第1章");
    System.out.println(book2.toString());//Book{title='Java', page=[Java第1章]}
    
    Book2 cloneBook2 = book2.clone();
    cloneBook2.setTitle("Android");
    cloneBook2.addPage("Android第1章");
    System.out.println(cloneBook2.toString());//Book{title='Android', page=[Java第1章, Android第1章]}
    
    // 再次打印原始书本发现原书没有被改变
    System.out.println(book2.toString());//Book{title='Java', page=[Java第1章]}
    

    6.3、使用原型模式注意事项

    • 构造函数不会被执行

      通过clone复制得到对象,该对象构造函数是不会被执行的。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不 会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。在单例模式中,只要将构造方法的访问权限设置为 private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的。

    • 浅拷贝和深拷贝

      clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。在开发中,为减少错误,建议在使用原型模式时尽量使用深拷贝,避免操作副本时影响原始对象的问题。如果是在涉及类的继承时,父类有多个引用的情况就非常复杂,建议的方案是深拷贝和浅拷贝分开实现。

    • clone与final

      要使用clone方法,类的成员变量上不要增加final关键字,因为final类型是不允许重赋值的。

    七、建造者模式

    建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    7.1、建造者模式的定义

    定义产品类

    //具体产品类
    public class Product {
        private String name;
        private String desc;
        public String getName() {return name;}
        public void setName(String name) {this.name = name;}
        public String getDesc() {return desc;}
        public void setDesc(String desc) {this.desc = desc;}
        @Override
        public String toString() {
            return "Product{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';
        }
    }
    

    定义抽象建造者

    //定义抽象建造者
    public abstract class Builder {
        //设置产品名称
        abstract void setName(String name);
        //设置产品描述
        abstract void setDesc(String desc);
        //构建产品
        abstract Product builderProduct();
    }
    

    定义具体建造者

    //定义具体建造者
    public class ConcreteProduct extends Builder {
        private final Product product;
        public ConcreteProduct() { product = new Product();}
        @Override
        void setName(String name) {
            product.setName(name);
        }
        @Override
        void setDesc(String desc) {
            product.setDesc(desc);
        }
        @Override
        Product builderProduct() {
            return product;
        }
    }
    

    定义指挥者类

    //定义指挥者类
    public class Director {
        private final ConcreteProduct concreteProduct;
        public Director() {
            concreteProduct = new ConcreteProduct();
        }
        public Product getProduct(String name,String desc){
            concreteProduct.setName(name);
            concreteProduct.setDesc(desc);
           return concreteProduct.builderProduct();
        }
    }
    

    使用建造者模式

    public static void main(String[] args) {
            Director director = new Director();
            Product product = director.getProduct("产品A", "A 的描述");
            System.out.println(product);//Product{name='产品A', desc='A 的描述'}
        }
    

    7.2、Android中建造者实现

    Android中的AlertDialog.Builder就是使用了Builder模式来构建AlertDialog的。

    Android AlertDialog简单构建与使用

    AlertDialog.Builder builder = new AlertDialog.Builder(activity);//创建一个Builder对象
      builder.setIcon(R.drawable.icon);
      builder.setTitle("标题");
      builder.setMessage("内容");
      builder.setPositiveButton("确定", null);
      AlertDialog alertDialog = builder.create();//创建AlertDialog对象
      alertDialog.show();//显示AlertDialog
    

    通过Builder对象来构建Icon、Title、Message、按钮监听等,将AlertDialog的构建过程和细节隐藏了起来。

    AlertDialog部分源码:

    public class AlertDialog extends AppCompatDialog implements DialogInterface {
        final AlertController mAlert;
        protected AlertDialog(@NonNull Context context) {
            this(context, 0);
        }
        ……
        public static class Builder {
            private final AlertController.AlertParams P;//存放构建时设置的参数
            ……
            public Builder(@NonNull Context context) {
                this(context, resolveDialogTheme(context, 0));
            }
    		……
         	public Builder(@NonNull Context context) {//构建Builder
                this(context, resolveDialogTheme(context, 0));
            }
            ……
            public Builder setTitle(@Nullable CharSequence title) {//设置标题
                P.mTitle = title;
                return this;
            }
            ……
            public Builder setMessage(@Nullable CharSequence message) {//设置内容
                P.mMessage = message;
                return this;
            }
    		……
            public Builder setIcon(@DrawableRes int iconId) {//设置icon
                P.mIconId = iconId;
                return this;
            }
    		……
            public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {//设置按钮和监听
                P.mPositiveButtonText = text;
                P.mPositiveButtonListener = listener;
                return this;
            }
    		……
            public AlertDialog create() {//构建AlertDialog
                final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
                P.apply(dialog.mAlert);//将构建时参数通过AlertController运用到AlertDialog上
                dialog.setCancelable(P.mCancelable);
                if (P.mCancelable) {dialog.setCanceledOnTouchOutside(true);}
                dialog.setOnCancelListener(P.mOnCancelListener);
                dialog.setOnDismissListener(P.mOnDismissListener);
                if (P.mOnKeyListener != null) {dialog.setOnKeyListener(P.mOnKeyListener);}
                return dialog;
            }
    		……
        }
    }
    

    AlertController部分源码:

    class AlertController { 
    	public static class AlertParams {
      	……
            public void apply(AlertController dialog) {//将构建时参数通过AlertController运用到AlertDialog上
                if (mCustomTitleView != null) {
                    dialog.setCustomTitle(mCustomTitleView);
                } else {
                    if (mTitle != null) {
                        dialog.setTitle(mTitle);
                    }
                    if (mIcon != null) {
                        dialog.setIcon(mIcon);
                    }
                    if (mIconId != 0) {
                        dialog.setIcon(mIconId);
                    }
                    if (mIconAttrId != 0) {
                        dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
                    }
                }
                if (mMessage != null) {
                    dialog.setMessage(mMessage);
                }
                if (mPositiveButtonText != null || mPositiveButtonIcon != null) {
                    dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText,
                            mPositiveButtonListener, null, mPositiveButtonIcon);
                }
                ……
    

    Android中 AlertDialog使用是通过AlertDialog.Builder设置各种属性后(如:setTitle()),这些属性信息会保存在P(AlertController.AlertParams)变量中,调用create()即可返回一个AlertDialog对象,create()方法中P.apply(dialog.mAlert)是将构建时设置的参数通过AlertController运用到AlertDialog上,最后调用AlertDialog中的show()显示对话框。AlertDialog通过builder模式隐藏了这种复杂的构建过程,只需几行简单的代码就把AlertDialog给展示出来了,AlertDialogbuilder中并没有抽象建造者(Builder)、Director(指挥者类)等角色。AlertDialog.Builder同时扮演了BuilderConcreteBuilderDirector等角色,这是Android源码中使用构建者模式的一种简化。

    展开全文
  • 设计模式 ① — 创建模式

    千次阅读 2018-06-07 11:24:26
    抽象工厂模式(Abstract Factory): 解决一系列相互依赖对象的创建工作。创建者模式(Builder):解决“一些复杂对象”的创建工作。原型模式(Prototype):解决某些结构复杂的对象的创建工作。单例模式(Singleton...

    创建型模式: 负责对象的创建。

    工厂方法模式(Factory Method);解决某个对象的创建工作。

    抽象工厂模式(Abstract Factory): 解决一系列相互依赖对象的创建工作。

    创建者模式(Builder):解决“一些复杂对象”的创建工作。

    原型模式(Prototype):解决某些结构复杂的对象的创建工作。

    单例模式(Singleton):解决了实体对象的个数问题。

          单例模式(SINGLETON

    基础概念:

    介绍:

    单例对象的类保证只有一个实例存在。

    定义:

    确保某个类只有一个实例,向整个系统提供这个实例。

    使用场景:

    确保某个类只有一个对象场景,避免产生多个对象消耗过多的资源,或者某种类型的对象因该有且只有一个。

    UML图:

     

     

    Client : 高层客户端。

    Singleton : 单例类。

     

    Android源码里的实现:

    常见的写法(线程不安全):

    推荐的写法(线程安全;延迟加载;效率较高)

     

    双重检查:

    静态内部类

    枚举的写法:

    Android不推荐枚举,耗费资源:

    https://www.youtube.com/watch?t=32&v=Hzs6OBcvNQE

    在Android项目里常用于生成View的LayoutInflater,就是单例的一种实现。

         工厂方法模式(FACTORY

    介绍:

    工厂方法模式是创建型设计模式之一 。

    定义:

    工厂方法模式定义一个创建对象的接口,让子类决定实例化哪个类 。

     

    使用场景:

    需要生成复杂对象的地方适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。 

     

    UML图:

    Android源码里的实现:

    ActivityonCreate就可以看作是一个工厂方法 。 

    优点:

    减少内存开销,提高性能。

    缺点:

    每次添加新的产品就要编写一个新的产品类,导致类结构的复杂化。

      抽象工厂方法(ABSTRACT FACTORY

    介绍:

    抽象工厂模式起源于以前对不同操作系统的图形化解决方案,不同操作系统中的按钮和文本控件实现不同,展示效果也不一样。 

    定义:

    为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定它们的具体类。 

    使用场景:

    一个家族有相同的约束时可以使用抽象工厂模式。 

    UML图:

    AbstractFactory : 抽象工厂角色,声明了一组用于创建一个产品的方法,每个方法对应一种产品。

    ConcreteFactory : 具体工厂角色,实现了在抽象工厂中定义的创建产品的方法,生成一组具体产品,产品构成一个产品种类。

    AbstractProduct : 抽象产品角色,为每种产品声明接口,比如图中AbstractProductAB

    ConcreteProduct : 具体产品角色,定义具体工厂生产的具体产品对象,如图中ConcreteProductA1,A2,B1B2

     

    Android源码里的实现:

    Android里对MediaPlayer的创建。

    优点:

    分离接口和实现。

    缺点:

    1. 类文件爆炸性增加

    2. 不容易扩展新的产品类,因为每增加一个产品类就需要修改抽象工厂。

    工厂方法和抽象工厂的区别:


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

          原型模式(PROTOTYPE

    介绍:

    原型二字表明了该模式有一个样板实例,用户从这个样本实例中复制一个内部属性一致的对象,原型模式多用于创建复杂的或构造耗时的实例。 

    定义:

    原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。 

    使用场景:

    1.类初始化需要消耗非常多的资源,包括数据,硬件资源等,通过原型拷贝避免消耗。

    2.一个对象需要提供给其他对象访问,各个调用者需要修改其值时,考虑原型模式拷贝或者多个对象供调用者使用,即保护性拷贝。 

     

    UML图:

    Client : 客户端用户。

    Prototype : 抽象类或者接口,声明具备clone能力。

    ConcretePrototype : 具体原型类。

     

    Android源码里的实现:

    Intentclone()方法。

     

    优点:

    原型模式是在内存中二进制流的拷贝,比直接new一个对象性能好很多,当要在一个循环体内产生大量的对象时,原型模式可以更好体现其优点。

    缺点:

    直接在内存中拷贝时,构造器是不会执行的,优点是减少了约束,缺点也是减少了约束。

          建造者模式(BUILD

    介绍:

    Builder模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,更精细的控制对象构造流程。 

    定义:

    将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。 

    使用场景:

    1. 初始化一个对象特别复杂,参数多,很多参数都有默认值时。比如ImageLoader里的ImageLoaderConfig

    2. 类非常复杂,产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常适合。 

     

    UML图:

    Product : 产品的抽象类。

    Builder : 抽象Builder类,规范产品的组建,一般是子类实现具体的组建过程。

    ConcreteBuilder : 具体的Builder类。

    Director : 统一组装过程。

    Android源码里的实现:

    WindowManager

     

    优点: 

    1. 良好的封装性,使用建造者模式可以使客户端不必知道产品内部组成的细节。

    2. 建造者独立,容易扩展。

    缺点: 

    会产生多余的Builder对象和Director对象,消耗内存。

    展开全文
  • 设计模式创建模式

    千次阅读 2015-05-24 11:10:17
    认识创建模式创建模式(又叫生成器模式)是为创建一个产品而生的,这个产品的组装算法是确定的,但零部件可以分配给多个厂商生产。使用创建模式创建产品,可以把产品零部件的生产和组装分开了。 创建模式...

    认识创建者模式

    创建者模式(又叫生成器模式)是为创建一个产品而生的,这个产品的组装算法是确定的,但零部件可以分配给多个厂商生产。使用创建者模式来创建产品,可以把产品零部件的生产和组装分开了。
    创建者模式包含以下几个部分:

    1. 产品(Product)
    2. 厂商的接口(Builder)
    3. 具体的厂商(ConcreteBuilder1、ConcreteBuilder2、…ConcreteBuilderN),实现厂商接口,负责产品零部件的生产工作
    4. 指导者(Director),这家伙知道怎么组装产品,负责整个产品的构建算法

    示例代码

    //产品
    public class Product
    {
    	public string ProductPartA { get; set; }
    
    	public string ProductPartB { get; set; }
    
    	public string ProductPartC { get; set; }
    
    	public override string ToString()
    	{
    		return ProductPartA + "\n" + ProductPartB + "\n" + ProductPartC;
    	}
    }
    
    //厂商的接口
    public interface Builder
    {
    	void BuildePartA();
    	void BuildePartB();
    	void BuildePartC();
    
    	Product GetProduct();
    }
    
    //具体厂商1
    public class ConcreteBuilder1:Builder
    {
    	Product product = new Product();
    
    	public void BuildePartA()
    	{
    		product.ProductPartA = "part A, concreteBuilder1 制造";
    	}
    
    	public void BuildePartB()
    	{
    		product.ProductPartB = "part B, concreteBuilder1 制造";
    	}
    
    	public void BuildePartC()
    	{
    		product.ProductPartC = "part C, concreteBuilder1 制造";
    	}
    
    
    	public Product GetProduct()
    	{
    		return product;
    	}
    }
    
    //具体厂商2
    public class ConcreteBuilder2 : Builder
    {
    	Product product = new Product();
    
    	public void BuildePartA()
    	{
    		product.ProductPartA = "part A, concreteBuilder2 制造";
    	}
    
    	public void BuildePartB()
    	{
    		product.ProductPartB = "part B, concreteBuilder2 制造";
    	}
    
    	public void BuildePartC()
    	{
    		product.ProductPartC = "part C, concreteBuilder2 制造";
    	}
    
    
    	public Product GetProduct()
    	{
    		return product;
    	}
    }
    
    //指导者
    public class Director
    {
    	private Builder builder;
    	public Director(Builder builder)
    	{
    		this.builder = builder;
    	}
    
    	//组装产品的算法。将具体厂商生产的零部件组装到一起(可以加入特定的业务逻辑)
    	public void Construct()
    	{
    		builder.BuildePartA();			
    		builder.BuildePartB();
    		builder.BuildePartC();
    		Product p = builder.GetProduct();
    		Console.WriteLine(p.ToString());
    	}
    }
    

    下面是场景类

    class Program
    {
    	static void Main(string[] args)
    	{
    		Builder builder1=new ConcreteBuilder1();
    		Builder builder2=new ConcreteBuilder2();
    
    		Director director = new Director(builder1);
    		director.Construct();
    
    		director = new Director(builder2);
    		director.Construct();
    	}
    }
    

    运行结果:
    part A, concreteBuilder1 制造
    part B, concreteBuilder1 制造
    part C, concreteBuilder1 制造
    part A, concreteBuilder2 制造
    part B, concreteBuilder2 制造
    part C, concreteBuilder2 制造

    展开全文
  • 创建模式——抽象工厂模式

    千次阅读 2018-03-10 10:40:27
    这种类型的设计模式属于创建模式,它提供了一种创建对象的最佳方式。 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。 介绍 意图...
  • 创建模式——建造者模式

    千次阅读 2018-03-10 11:30:47
    这种类型的设计模式属于创建模式,它提供了一种创建对象的最佳方式。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 介绍 意图 将一个复杂的构建与其表示相分离,使得同样...
  • 创建模式——工厂方法模式

    千次阅读 2020-07-10 08:22:13
    在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被...
  • 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责...
  • 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。...的创建工作...
  • 虽然我家大业大,但也耗不住我这么折腾呢,于是我决定找份工作好好磨练下自己,为爱找份工作,为爱加上期限 – 爱你一万年。 找工作不得写简历吗,我就写呀写呀… 为了提高我投简历的准确性,我觉得简历要写的多样...
  • 创建模式

    千次阅读 2009-06-10 10:11:00
    创建模式: 创建模式抽象了实例化过程。他们帮助一个系统独立于如何创建、组合和表示他的那些对象。一个类创建模式使用继承改变被实例化的类。而一个对象创建模式将实例化委托给另一个对象。 Abstract ...
  • 设计模式汇总:创建模式

    万次阅读 2016-04-30 17:26:47
    创建模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:...
  • 这种类型的设计模式属于创建模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,...
  • 创建模式 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
  • 设计模式——创建模式

    千次阅读 2011-11-30 21:02:50
    抽象工厂模式、建造者模式、工厂方法模式、原型模式、单例模式都属于创建模式,即与对象的创建有关的模式,但是功能越接近越难以区分,他们在创建对象的过程中各自有承担着什么杨的责任,他们该在什么地方使用呢?...
  • 创建模式关注对象的创建 结构型模式关注类或对象之间的组织关系 行为型模式关注类或对象间的交互和职责分配(就是用来干什么) 模式从本质上都是简化和分解类或对象,使易于扩展或封装性更好;一些相似的模式...
  • 以形成良好的软件体系结构,主要的方式是使用继承关系来组织各个类,一个最容易的例子就是如何用多个继承组织两个以上的类,结果产生的类结合了父类所有的属性,结构型模式特别适用于和独立的类库一起工作。...
  • 设计模式--六种创建模式

    千次阅读 热门讨论 2017-04-13 16:58:25
     每几种模式之间都有一定的联系,从中发现它们的相同点和不同点,研究发生改变的节点,这就是本篇博客所要说明的创建型设计模式之间的联系。它们包括:简单工厂模式、单例模式、工厂方法模式、抽象工厂模式、建造者...
  • 创建模式总结

    千次阅读 热门讨论 2019-03-21 17:41:12
    创建模式有以下几个模式: 简单工厂:用来生产同一等级结构中的任意产品。(不支持拓展增加产品) 工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品) 抽象工厂 :用来生产不同产品族的全部...
  •  每几种模式之间都有一定的联系,从中发现它们的相同点和不同点,研究发生改变的节点,这就是本篇博客所要说明的创建型设计模式之间的联系。它们包括:简单工厂模式、单例模式、工厂方法模式、抽象工厂模式、建造者...
  • 简单工厂模式又名静态工厂方法模式,是所有工厂模式中最简单的一个,它定义一个具体的工厂类来负责创建所有类的对象并初始化创建的对象,它主要由3部分组成:工厂类、抽象类、实现抽象类的具体类,然后通过客户端...
  • JAVA设计模式之单例模式

    万次阅读 多人点赞 2014-04-16 06:51:34
    本文继续介绍23种设计模式系列之单例模式。... 2、单例类必须自己创建自己的唯一实例。  3、单例类必须给所有其他对象提供这一实例。 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例...
  • 设计模式创建模式

    千次阅读 2012-12-04 21:12:16
    抽象工厂模式:提供一个创建并返回一族相关示例的接口,而不需要指明它们具体的类。 生成器模式:将一个复杂对象的构建与呈现分开,以便相同的构造过程能够根据不同需要创建不同的形式。 工厂方法模式:提供...
  • Abstract factory模式其实就是普通factory模式的一种进化,它比较侧重于对一个系列中相关多个对象的创建工作。何谓一个系列?其实就是某种客观条件下满足特定需求的一组对象集合。当面对多个系列时,需要实现每个...
  • Java设计模式_(创建型)_原型模式

    万次阅读 2017-09-19 17:19:13
    引用百科:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。Prototype原型模式是一种创建型设计模式,Prototype模式允许一...解决什么问题:它主要面对的问题是:“某些结构复杂的对象”的创建工作
  • 创建型模式总结创建型模式总结1. 创建型模式成员温故而知新,看完前面7章的...2. 创建型模式讨论l 特点:创建型模式他主要解决的是对新类创建(New)动作的封装处理,所以我把创建型模式归结为对新实体的创建工作
  • 设计模式学习整理之创建模式

    千次阅读 2006-09-01 21:07:00
    所谓对象创建模型就是说将实例化的工作委托给另一个对象来做。与之相对应的是类创建模型,这是一种通过继承改变被实例化的类。 创建模式有两个重要的特点:1) 客户不知道创建的具体类是什么(除非看源代码)2)...
  • (1)类的初始化:是完成程序执行前的准备工作。在这个阶段,静态的(变量,方法,代码块)会被执行。同时在会开辟一块存储空间用来存放静态的数据。初始化只在类加载的时候执行一次。 (2)类的实例化:是指创建一...
  • 创建型设计模式

    千次阅读 2013-02-25 09:59:49
    一、创建模式   在软件工程中,创建模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。 基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建模式通过以某种方式...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,067,241
精华内容 426,896
关键字:

创建工作模式