多個類中有相同的字段,能夠提取到父類中。json
public class Engineer { public string name { get; set; } } public class Salesman { public string name { get; set; } }
public class Employee { public string name { get; set; } } public class Engineer:Employee { } public class Salesman : Employee { }
多個類中有相同或類似的方法時,能夠提取到父類api
class Preferred_Customer { void CreateBill(DateTime date) { double chargeAmount = ChargeFor(); AddBill(date, chargeAmount); } void AddBill(DateTime date, double amount) { } public double ChargeFor() { return 1; } }
class Regular_Customer { void CreateBill(DateTime date) { double chargeAmount = ChargeFor(); AddBill(date, chargeAmount); } void AddBill(DateTime date, double amount) { } double ChargeFor() { return 2; } }
abstract class Customer { void CreateBill(DateTime date) { double chargeAmount = ChargeFor(); AddBill(date, chargeAmount); } void AddBill(DateTime date, double amount) { } public abstract double ChargeFor(); } class Preferred_Customer: Customer { public override double ChargeFor() { return 1; } } class Regular_Customer:Customer { public override double ChargeFor() { return 2; } }
子類中的ChargeFor方法實現不一樣,父類中的ChargeFor爲抽象方法。子類經過重寫實現。ide
多個類的構造函數代碼相似,能夠提取到父類中函數
class Manager { string _name; int _id; public Manager(string name,int id) { _name = name; _id = id; Init(); } void Init() { object obj1 = new object(); } } class Manager1 { string _name; int _id; int _grade; public Manager1(string name,int id,int grade) { _name = name; _id = id; _grade = grade; Init(); } void Init() { object obj2 = new object(); _grade = 2; } }
abstract class Employee { protected string _name; protected int _id; public Employee(string name, int id) { _name = name; _id = id; Init(); } protected abstract void Init(); } class Manager:Employee { public Manager(string name, int id):base(name,id) { } protected override void Init() { object obj1 = new object(); } } class Manager1 : Employee { int _grade; public Manager1(string name, int id, int grade) : base(name, id) { _grade = grade; } protected override void Init() { object obj2 = new object(); _grade = 2; } }
子類中的構造函數中調用的Init方法實現不一樣,在父類中作成抽象方法。spa
當一個類中出現根據類型調用不一樣的方法,或者一個類中有多個職責的時候,咱們能夠考慮提煉子類3d
class PrintClass { string _path; string _jsonData; string _sourceBillFlag; List<int> _sourceBillId; int _lableType; public PrintClass(string path, string jsonData, string sourceBillFlag, List<int> sourceBillId, int lableType) { _path = path; _jsonData = jsonData; _sourceBillFlag = sourceBillFlag; _sourceBillId = sourceBillId; _lableType = lableType; } public void Print() { switch(_lableType) { case 1: PrintBartender(_path,_jsonData); break; case 2: PrintCodeSoft(_path, _jsonData); break; case 3: PrintCloud(_sourceBillFlag,_sourceBillId); break; } } void PrintBartender(string path, string jsonData) { } void PrintCodeSoft(string path, string jsonDat) { } void PrintCloud(string sourceBillFlag, List<int> sourceBillId) { } }
好比這個打印類中,根據類型,調不一樣的打印方法。code
namespace Extract_Subclass { class PrintBase { string _path; string _jsonData; public PrintBase(string path, string jsonData) { _path = path; _jsonData = jsonData; } public virtual void Print( ) { } } class BartenderPrint : PrintBase { public BartenderPrint(string path, string jsonData):base(path,jsonData) { } public override void Print() { //call bartender api } } class CodeSoftPrint : PrintBase { public CodeSoftPrint(string path, string jsonData) : base(path, jsonData) { } public override void Print() { //call CodeSoft api } } class CloudPrint:PrintBase { string _sourceBillFlag; List<int> _sourceBillId; public CloudPrint(string sourceBillFlag, List<int> sourceBillId) :base("","") { _sourceBillFlag = sourceBillFlag; _sourceBillId = sourceBillId; } public override void Print() { //Cloud print } } }
幾個類的字段,方法,構造函數等都有部分相同之處,能夠提取到父類中。orm
class Department { string _name; public Department(string name) { _name = name; } public string GetName() { return _name; } public int GetTotalaAnnualCost() { int result = 0; GetStaff().ForEach(p=> { result += p.GetAnnualCost(); }); return result; } private List<Employee> GetStaff() { return default(List<Employee>); } }
class Employee { string _name; string _id; int _annualCost; public Employee(string name,string id,int annualCost) { _name = name; _id = id; _annualCost = annualCost; } public string GetName() { return _name; } public int GetAnnualCost() { return _annualCost; } }
Department類中有個GetTotalaAnnualCost方法,獲取總費用,Employee中有個GetAnnualCost方法,獲取費用。咱們能夠提取到父類中,修改爲相同的名稱。blog
namespace RefactoringDome.Extract_Superclass { abstract class Part { string _name; public Part(string name) { _name = name; } public string GetName() { return _name; } public abstract int GetAnnualCost(); } } namespace RefactoringDome.Extract_Superclass.Dome { class Employee : Part { string _id; int _annualCost; public Employee(string name, string id, int annualCost) : base(name) { _id = id; _annualCost = annualCost; } public override int GetAnnualCost() { return _annualCost; } } class Department:Part { public Department(string name):base(name) { } public override int GetAnnualCost() { int result = 0; GetStaff().ForEach(p => { result += p.GetAnnualCost(); }); return result; } private List<Employee> GetStaff() { return default(List<Employee>); } } }
兩個方法中的流程大體相同,咱們能夠提煉成模板方法。繼承
class Customer { public string Statement() { List<string> details = GetDetails(); string result = "Rental Record for" + GetName() + "\n"; details.ForEach(p=> { result += "Details is" + p + "\n"; }); result += "Total Charge:"+GetTotalCharge(); return result; } public string HtmlStatement() { List<string> details = GetDetails(); string result = "<h1>Rental Record for<EM>" + GetName() + "</EM></h1>\n"; details.ForEach(p => { result += "<p>Details is<EM>" + p + "</EM></p>\n"; }); result += "<p>Total Charge:<EM>" + GetTotalCharge()+"</EM></p>"; return result; } public List<string> GetDetails() { return default(List<string>); } public string GetName() { return ""; } public decimal GetTotalCharge() { return 0; } }
Customer類中有兩個打印小票的方法,一個是winform調的,一個是Html調的。方法中代碼結構同樣,只是部分顯示字符串不一樣。
這種很符合提取成模板函數。
namespace RefactoringDome.Form_Template_Method { abstract class Statement { public string Value(Customer customer) { List<string> details = customer.GetDetails(); string result = HeaderString(customer); details.ForEach(p => { result += DetailString(p); }); result += FooterString(customer); return result; } protected abstract string HeaderString(Customer customer); protected abstract string DetailString(string detailInfo); protected abstract string FooterString(Customer customer); } class TextStatement : Statement { protected override string HeaderString(Customer customer) { return "Rental Record for" + customer.GetName() + "\n"; } protected override string DetailString(string detailInfo) { return "Details is" + detailInfo + "\n"; } protected override string FooterString(Customer customer) { return "Total Charge:" + customer.GetTotalCharge(); } } class HtmlStatement : Statement { protected override string HeaderString(Customer customer) { return "<h1>Rental Record for<EM>" + customer.GetName() + "</EM></h1>\n"; } protected override string DetailString(string detailInfo) { return "<p>Details is<EM>" + detailInfo + "</EM></p>\n"; } protected override string FooterString(Customer customer) { return "<p>Total Charge:<EM>" + customer.GetTotalCharge() + "</EM></p>"; } } }
把不一樣的部分,用抽象函數代替。子類中去重寫實現具體實現。
子類只用了父類一小部分方法。這種狀況能夠考慮將繼承替換爲委託。
class List { public object FirstElement() { return default(object); } public void Insert(object element) { } public void Remove(object element) { } public int FindIndex(object obj) { return 0; } public void Sort() { } } class Queue: List { public void Push(object element) { Insert(element); } public void Pop() { object obj = FirstElement(); Remove(obj); } }
Queue類繼承了List類,使用了List類的Insert、Remove、FirstElement方法。可是List類中還有Sort、FindIndex方法在子類中沒有用到。這樣父類傳達給調用端的信息並非你想要體現的。這種狀況咱們應該使用List的委託。
class Queue { List _list = new List(); public void Push(object element) { _list.Insert(element); } public void Pop() { object obj = _list.FirstElement(); _list.Remove(obj); } }
一個類中,引用了另外一個類的實例,可是當前類中的方法,委託類裏都有,這種狀況應該用繼承替換委託。
class Employee { Person _person = new Person(); public string GetName() { return _person.GetName(); } public void SetName(string name) { _person.SetName(name); } public new string ToString() { return "my name is:"+_person.GetLastName(); } } class Person { string _name; public string GetName() { return _name; } public void SetName(string name) { _name = name; } public string GetLastName() { return _name.Substring(1); } }
class Employee:Person { public new string ToString() { return "my name is:" + GetLastName(); } }
代碼結構清晰簡潔了很多。