java面试题factory method 模式和prototype模式 之间的区别可以理解为
原型模式虽然是创建型的模式,但是与工厂模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。
public class Prototype implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
}
javascript创建对象的几种常用模式介绍
本文介绍了javascript中创建对象常用的几种模式,包括:工厂模式,构造函数模式,原型模式,组合构造函数与原型的模式,动态原型模式。一.工厂模式看如下代码:function getMySon(name,sex){ var o={}; o.name=name; o.sex=sex; o.sayName = function(){ alert(this.name); } return o;}son1 = getMySon('li ming','male');son2 = getMySon('li hong','female');这就是工厂模式。在函数中定义一个对象,并为其添加属性与方法,最后将这个对象返回。虽然这种模式实现了方便的创建对象,但是有这样一个问题,即不能判断这个实例到底是谁创建的。 比如 son1 intanceof getMySon并不能返回 true。因为这里的实例确切来说并不是由getMySon 通过new来创建的,而是getMySon中的 o。 所以工厂模式并不适合需要创建很多种对象的情况。 那么怎么创建对象才能正确的判断实例是从哪儿来的呢?下面就要说到构造函数模式了。二.构造函数模式看如下代码 :function getMySon(name,sex){ this.name = name; this.sex = sex; this.sayName = function(){ alert(this.name); }}son1 = new getMySon('li ming','female');这就是构造函数模式,注意在调用时要用 new。在进行new调用时,进行如下几个步骤: 1. 创建一个新的对象(并把空对象的__proto__属性设置为getMySon.prototype)。 2.将构造函数的作用域赋给新对象(此时this 指向了这个新对象)。 3.执行构造函数中的代码(通过this 为这个新对象添加属性) 4.返回新对象。通过这种方式产生的实例可以使用son1 instanceof getMySon来判断实例是由谁来产生的。那么使用构造函数有什么问题呢?由于每次使用new时都会创建一个新的对象,那么所有的数据在不同实例之间是不共享的。但是对于函数sayName来说,它并没有必要创建多个。这样做浪费了空间。这样就引出了下一种,原型模式。三. 原型模式看如下代码:function getMySon(){}getMySon.prototype.name = 'li ming';getMySon.prototype.sex = 'female';getMySon.prototype.sayName = function(){ alert(this.name);}这就是原型模式(原型的相关知识这里不详细说)。原型模式将属性和方法添加到了getMySon.prototype里,prototype由所有的实例共享,它只有一份,并不是所有的实例各有一份。这种方式实现了让函数只有一份,不必占用多余的空间。但是,name,sex之类的属性并不需要在所有实例间共享,而且使用原型模式进行传参生成这些属性也不方便。那么可以合并构造函数模式与原型模式,利用它们各自的优点。让各实例间不需要进行共享且需要通过传参进行生成的属性放在构造函数模式中生成,让各实例中需要共享的(比如方法)在原型模式中生成。三. 组合构造函数与原型的模式 看如下代码:function getMySon(name,sex){ this.name=name; this.sex=sex;}getMySon.prototype.sayName(){ alert(this.name);}son1=new getMySon('li ming','female');这是 组合构造函数与原型的模式 。这种方式结合了构造函数模式与原型模式的优点。这是最常用的一种创建对象的模式。四. 动态原型模式所谓动态原型模式,其实是对 组合构造函数与原型的模式 的一种封装。 看如下代码:function getMySon(name,sex){ this.name = name; this.sex = sex; //即使有多个需要定义的方法,也只需判断一个方法。 if(typeof sayName != 'function'){ getMySon.prototype.sayName=function(){ alert(this.name); } }}son1=new getMySon('li ming','female');这里之所以命名为动态原型模式,是因为getMySon在不同的调用中会发生变化,是动态的。只有在第一次调用getMySon时才会执行对sayName函数的定义。 从本质来看,仍然是将不需共享的通过构造函数进行定义,需要共享的方法通过原型进行定义。只是将它们放在了一起,进行了封装。
Factory Method和Abstract Factory 的区别
为了区分Factory Method和Abstract Factory的区别,查阅了些资料,总算有点感悟,下面是本人的感悟的总结。
在设计模式中,Factory Method和Abstract Factory的区别并不容易理解,主要是Abstrct Factory一般情况下是要通过Factory Method来实现,或者说Abstract Factory包含Factroy Method。
从字面上来理解,Factory Method强调的是Method,Abstract Factory强调的是抽象类,也就是继承关系。
下面,将使用例子来对比Factory Method和Abstract Factory。
有两种不同的产品,分别是电视和收音机,下面分别用Factory Method和Abstract Factory模式对两种产品进行创建。
(1) Factory Method模式主要通过工厂类的方法的多态来实现对多种不同产品的创建。其C#示例代码如下所示。
namespace FactoryMethod
{
class Program
{
public interface IProduct
{
void ProductName();
}
public class CRadio : IProduct
{
public void ProductName()
{
Console.WriteLine("Radio");
}
}
public class CTV : IProduct
{
public void ProductName()
{
Console.WriteLine("TV");
}
}
public interface IFactory
{
IProduct CreateProduct(string ProductName);
}
public class CConcreteFactory
{
public IProduct CreateProduct(string ProductName)
{
if (0 == ProductName.CompareTo("TV"))
{
return new CTV();
}
else
{
return new CRadio();
}
}
}
static void Main(string[] args)
{
CConcreteFactory ConFactory = new CConcreteFactory();
IProduct TVProduct = ConFactory.CreateProduct("TV");
TVProduct.ProductName();
IProduct RadioProduct = ConFactory.CreateProduct("Radio");
RadioProduct.ProductName();
Console.Read();
}
}
}
(2) AbstractFactory模式主要是通过工厂类的不同的子类来实现不同类别的产品的创建。其C#示例代码如下所示:
namespace AbstractFactory
{
class Program
{
public interface IProduct
{
void ProductName();
}
public class CRadio : IProduct
{
public void ProductName()
{
Console.WriteLine("Radio");
}
}
public class CTV : IProduct
{
public void ProductName()
{
Console.WriteLine("TV");
}
}
public interface IFactory
{
IProduct CreateProduct(string ProductName);
}
public class CRadioFactory
{
public IProduct CreateProduct()
{
return new CRadio();
}
}
public class CTVFactory
{
public IProduct CreateProduct()
{
return new CTV();
}
}
static void Main(string[] args)
{
CTVFactory TVFactory = new CTVFactory();
IProduct TVProduct = TVFactory.CreateProduct();
TVProduct.ProductName();
CRadioFactory RadioFactory = new CRadioFactory();
IProduct RadioProduct = RadioFactory.CreateProduct();
RadioProduct.ProductName();
Console.Read();
}
}
}