一.單例及原型模式
單例:即使用一個固定對象的對象進行操作,實現起來很簡單
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// 2021 10 28 14:50
// by 黎翰
//topic:23種設計模式............
namespace DesignMode.SingleTonMode //單例模式代碼實現
{
class TestSingleOne
{
private String Atestvisbity
{
get;
set;
}
private static TestSingleOne theOne = new TestSingleOne();
private TestSingleOne()
{
this.Atestvisbity = "金坷垃";
//封死構造函數.使其不能通過構造函數進行對象的創建
}
public static TestSingleOne GetInstance() //獲取實例的唯一方法
{
return theOne;
}
}
}
測試方法:
static void Main(string[] args)
{
//單例模式測試代碼
TestSingleOne t1 = TestSingleOne.GetInstance();
TestSingleOne t2 = TestSingleOne.GetInstance();
TestSingleOne t3 = TestSingleOne.GetInstance();
Console.WriteLine(t1.Equals(t2));
Console.WriteLine(t2.Equals(t3));
Console.WriteLine(t3.Equals(t1));
Console.ReadLine();
}
結果:
True
True
True
原型模式則與單例模式相反,需要以一個對象為原型複製另一個對象,
但對象的數據里八成是有引用類型的,
由此則涉及到了深淺拷貝的問題
如果無法克隆引用類型的成員,則實際上兩個對象的引用成員是同一個地址,即同一個對象.這就是淺拷貝
如果又能夠將引用類型的成員獨立拷貝出來,則視為深拷貝
Java的Object超類自帶有clone方法,能夠進行淺拷貝(也就是只拷貝基礎數據類型),但有一個前提要調用clone方法必須讓類實現cloneable接口,該接口是一個空接口,沒有定義方法,算一個給虛擬機的標識.
如果要用Clone方法實現深拷貝也十分簡單,即可以讓引用類型也實現Cloneable接口即可,
PS:如果是循環依賴的關係進行拷貝操作,則會直接棧溢出(具體原因可以在我的設計模式文章中查看)
代碼實現:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//2021 10 28 23種設計模式-----------------原型模式代碼實現(單例模式的反例)
//C#實現, 黎翰
namespace DesignMode.SingleTonMode
{
//Java中object類中自帶clone方法,不過也需要實現cloneable接口,
//由於C#沒有這個特性,所以需要模擬一個類java的clone方法
public interface Prototype
{
//模仿克隆方法
object smultClone();
}
public class thePrototype:Prototype
{
//省略一下三個普通屬性
private String id
{
get;
set;
}
private String name
{
get;
set;
}
private String address
{
get;
set;
}
public thePrototype(String id,String name,String address)
{
this.id = id;
this.name = name;
this.address = address;
}
public thePrototype() { }
//實現模仿的克隆方法
public object smultClone()
{
thePrototype newone = new thePrototype();
newone.id = this.id;
newone.name = this.name;
newone.address = this.address;
return newone;
}
//重寫一下toString方法,方便對象的顯示
public override string ToString()
{
return "id:" + this.id + "name:" + this.name + "address:" + this.address;
}
}
}
測試代碼:
// 原型模式測試代碼
thePrototype origin = new thePrototype("10086","小明","勘察加半島");
thePrototype theSecond = (thePrototype)origin.smultClone(); //調用克隆方法實現對象的克隆
Console.WriteLine(origin.Equals(theSecond));
Console.WriteLine(theSecond);
Console.ReadLine();
結果:
False
id:10086name:小明address:勘察加半島
二:簡單工廠模式
簡單工廠模式,即通過工廠對象的(工廠方法)創造對象的方法,
含義比較簡單,直接以代碼的方式實現
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesignMode.FactoryMode
{
class FactoryMode
{
//簡單工廠模式測試代碼
}
public interface Fruit //定義一個水果接口
{
void showFruitName();
}
public class Apple : Fruit
{
public void showFruitName()
{
Console.WriteLine("Not just a Apple");
}
}
public class Banana : Fruit
{
public void showFruitName()
{
Console.WriteLine("Not just a Banana");
}
}
public class FactoryClass //工廠類,生產對象
{
public Fruit getWhichFruit(String clazz)
{
if (clazz.Equals("Apple"))
{
return new Apple();
}
else if (clazz.Equals("Banana"))
{
return new Banana();
}
else
{
Console.WriteLine("Cannot get Instance!!!!");
return null;
}
}
}
}
測試方法:
String clazz = Console.ReadLine();
FactoryClass factory = new FactoryClass();
Fruit fruit = factory.getWhichFruit(clazz);
fruit.showFruitName();
Console.ReadLine();
輸入Apple測試:
Apple
Not just a Apple
輸入Banana測試
Banana
Not just a Banana
三.建造者模式
這個模式的關係比較複雜,(在我的設計模式文章中有比較詳細的介紹)
但可以主要分為幾種角色,
- 抽象建造者
- 具體建造者
- 抽象產品接口
- 具體產品類
- Directer指導者(可以省略)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//2021 10 28 黎翰
//23種設計模式-------------建造者模式代碼實現
namespace DesignMode.BuilderMode
{
//抽象建造者類
interface HouseBuilder
{
void buildGate(); //建造們
void buildGarden(); //建造花園
void buildRoof(); //建造屋頂
void buildWall(); //建造墻
void buildLargeWindow(); //建造窗戶
void buildSmallWindow();
}
//具體建造者類
class LuxHouseBuilder :HouseBuilder
{
//產品實例
private LuxHouse luxHouse = new LuxHouse();
public void buildGarden()
{
luxHouse.appendStringToIdentity("\n建了一個花園");
Console.WriteLine("LuxGarden.....");
}
public void buildGate()
{
luxHouse.appendStringToIdentity("\n建了一個大門");
Console.WriteLine("LuxGate.....");
}
public void buildLargeWindow()
{
luxHouse.appendStringToIdentity("\n建了一個大的窗戶");
Console.WriteLine("LuxLargeWindow.....");
}
public void buildRoof()
{
luxHouse.appendStringToIdentity("\n建了一個屋頂");
Console.WriteLine("LuxRoof.....");
}
public void buildSmallWindow()
{
luxHouse.appendStringToIdentity("\n建了一個小窗戶");
Console.WriteLine("LuxSmallWindow.....");
}
public void buildWall()
{
luxHouse.appendStringToIdentity("\n建了一堵墻");
Console.WriteLine("LuxWall.....");
}
//獲取產品方法
public LuxHouse getProduct()
{
return luxHouse;
}
}
//具體建造者類
class CheHouseBulder : HouseBuilder
{
private CheHouse cheHouse = new CheHouse();
public void buildGarden()
{
cheHouse.appendStringToIdentity("\n建了一個花園");
Console.WriteLine("poorGarden........");
}
public void buildGate()
{
cheHouse.appendStringToIdentity("\n建了一個大門");
Console.WriteLine("poorGate........");
}
public void buildLargeWindow()
{
cheHouse.appendStringToIdentity("\n建了一個大的窗戶");
Console.WriteLine("poorLargeWindow........");
}
public void buildRoof()
{
cheHouse.appendStringToIdentity("\n建了一個屋頂");
Console.WriteLine("poorRoof........");
}
public void buildSmallWindow()
{
cheHouse.appendStringToIdentity("\n建了一個小的窗戶");
Console.WriteLine("poorSmallWindow........");
}
public void buildWall()
{
cheHouse.appendStringToIdentity("\n建了一個花園");
Console.WriteLine("poorWall........");
}
public CheHouse getProduct()
{
return cheHouse;
}
}
//抽象產品接口
interface House
{
void Stay();
}
//具體產品類
class LuxHouse : House
{
private StringBuilder identity = new StringBuilder("process");
public void appendStringToIdentity(String append)
{
identity.Append(append);
}
public void showIdentity()
{
Console.WriteLine(identity);
}
public void Stay()
{
Console.WriteLine("stay in LuxHouse");
}
}
//具體產品類
class CheHouse : House
{
private StringBuilder identity = new StringBuilder("process");
public void appendStringToIdentity(String append)
{
identity.Append(append);
}
public void showIdentity()
{
Console.WriteLine(identity);
}
public void Stay()
{
Console.WriteLine("stay in CheHouse");
}
}
//指揮者類,指揮對象的生產動作
class Director
{
private HouseBuilder builder;
public Director(HouseBuilder builder)
{
this.builder = builder;
}
public void setBuilder(HouseBuilder builder)
{
this.builder = builder;
}
public void setALuxHouseFristWay()
{
Console.WriteLine("第一種建造方式開始.....");
builder.buildGate();
builder.buildWall();
builder.buildRoof();
builder.buildLargeWindow();
Console.WriteLine("第一種建造方式結束.....");
}
public void setALuxHouseSecondWay(HouseBuilder builder)
{
Console.WriteLine("第二種建造方式開始.....");
builder.buildGarden();
builder.buildRoof();
builder.buildSmallWindow();
Console.WriteLine("第二種建造方式結束.....");
}
public void setACheHouseSecond(HouseBuilder builder)
{
Console.WriteLine("chehouse建造方式開始.....");
builder.buildGarden();
builder.buildRoof();
builder.buildSmallWindow();
Console.WriteLine("chehouse建造方式結束.....");
}
}
}
測試代碼
//建造者模式測試
HouseBuilder luxbuilder = new LuxHouseBuilder(); //創建具體建造者對象
HouseBuilder chebuilder = new CheHouseBulder();
Director director = new Director(luxbuilder); //設置指揮者
director.setALuxHouseFristWay(); //指揮生產方法
LuxHouse lux = ((LuxHouseBuilder)luxbuilder).getProduct(); //獲取產品
lux.showIdentity(); //顯示一下創建過程
director.setBuilder(chebuilder);
director.setACheHouseSecond(chebuilder);
CheHouse che = ((CheHouseBulder)chebuilder).getProduct();
che.showIdentity();
Console.ReadLine();
結果:
第一種建造方式開始.....
LuxGate.....
LuxWall.....
LuxRoof.....
LuxLargeWindow.....
第一種建造方式結束.....
process
建了一個大門
建了一堵墻
建了一個屋頂
建了一個大的窗戶
chehouse建造方式開始.....
poorGarden........
poorRoof........
poorSmallWindow........
chehouse建造方式結束.....
process
建了一個花園
建了一個屋頂
建了一個小的窗戶