Skip Navigation Links.
Skip Navigation Links.

.net student

microsoft

Vyhledávání v obsahu portálu


Přihlášení uživatele

Přihlášení uživatele

Členové:
  • Poslední nový uživatel Poslední: zplasek
  • Nový dnes Dnes nových 0
  • Nový včera Včera nových: 0
  • Počet uživatelů: Celkem: 4273
Lidé online:
  • Návštěvníci: Návštěvníků: 43
  • Registrovaných Členů: 1
  • Celkem Celkem: 44
Mapa Stranek

Refaktorizace aneb jak umí Visual Studio kouzlit se zdrojovým kódem

Refaktorizační techniky, které nabízí Visual Studio, jsou velmi mocným nástrojem, jež ušetří spoustu práce při úpravách větších částí zdrojových kódů. Představte si jen takovou drobnost, jakou je přejmenování jedné hojně využívané metody v rámci celého projektu tak, aby zůstala zachována funkčnost všech volání této metody. Díky refaktorizaci je to otázka doslova dvou kliknutí. Refaktorizace toho však nabízí mnohem víc a v tomto článku sami uvidíte, že to, co umí Visual Studio pomocí refaktorizace provádět se zdrojovým kódem, je doslova jako kouzlení.

Visual Studio nabízí celkem 7 refaktorizačních technik. Jsou to:

  • Přejmenování
  • Extrakce metody
  • Zapouzdření pole
  • Extrakce rozhraní
  • Povýšení lokální proměnné na parametr
  • Odstranění parametrů
  • Přeuspořádání parametrů

a je možné je vyvolat buď z nabídky Refactor, nebo přes kontextové menu a volbu Refactor.

Co budeme refaktorizovat

Pojďme si nyní ukázat, jak s těmito technikami pracovat a jak pomocí nich "zušlechtit" naprosto hrozný zdrojový kód.

Ve Visual Studiu založíme nový WinForm projekt v jazyce C# a pojmenujeme jej Refaktorizace.

Necháme si zobrazit kód Form1.cs a umístíme do něj následující:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.ComponentModel;
   4:  using System.Data;
   5:  using System.Drawing;
   6:  using System.Text;
   7:  using System.Windows.Forms;
   8:   
   9:  namespace Refaktorizace
  10:  {
  11:      // nevyhovující název třídy Form1
  12:      public partial class Form1 : Form
  13:      {
  14:          // veřejná vnitřní proměnná
  15:          public int _cislo = 1;
  16:   
  17:          public Form1()
  18:          {
  19:              InitializeComponent();
  20:   
  21:              Metoda(1, 2);
  22:   
  23:              int _a = 2;
  24:              int _b = 1;
  25:   
  26:              // opakující se kód
  27:              int _vysledek;
  28:              if (_b != 0)
  29:                  _vysledek = _a / _b;
  30:          }
  31:   
  32:          // nevhodný název metody
  33:          public int Metoda(int a, int b)
  34:          {
  35:              return a + b;
  36:          }
  37:   
  38:          // nevyhovující struktura metody
  39:          public int Mocnina(int a)
  40:          {
  41:              int _exponent = 2;
  42:              return a ^ _exponent;
  43:          }
  44:   
  45:          // nevyužité a rozházené parametry
  46:          public int Vypocet(int a, int c, int e, int b, int d)
  47:          {
  48:              int _vysledek = 0; ;
  49:              if (b != 0)
  50:                  _vysledek = a / b;
  51:   
  52:              _vysledek += Metoda(a, b) * Mocnina(c);
  53:   
  54:              return _vysledek;
  55:          }
  56:      }
  57:  }

Jak vidíte, jde o opravdu strašný kód, u nehož jsem do komentáře uvedl "závady", které se zde vyskytují. Pusťme se tedy rychle do refaktorizace.

1. Přejmenování (Rename...)
Jako první, co nám v uvedeném kódu nevyhovuje, je název samotné třídy. Vygenerovaný název Form1 není zrovna příliš vhodný. Název třídy by měl totiž vždy vystihovat záměr existence samotné třídy. Tento název však není obsažen pouze v jednom souboru a navíc se vyskytuje na spoustě míst. Přejmenování pomocí Find->Replace by tedy nebylo příliš vhodné. Nikde nemáme jistotu, že po přejmenování projde kód kompilací.

Protože třída Form1 prezentuje vizuální formulář, můžeme k přejmenování v tomto případě použít vlastnost Name. Nicméně u jiných vlastních tříd tento způsob nebude možný. Použijme tedy refaktorizaci.

Umístěme kurzor na název třídy Form1 na řádku 12 a z kontextového menu vyberme Refactor->Rename...

V dialogovém okně nyní zadáme nový název třídy, např. Main. Navíc zde můžeme pomocí CheckBoxů ovlivnit způsob přejmenování:

  • Preview reference changes - zobrazení náhledu co vše bude přejmenováno
  • Search in comments - prohledávání komentářů
  • Seach in strings - prohledávání řetězců

Pokud zaškrtnete Preview reference changes, můžete v dalším dialogu zvolit, kde všude provádět přejmenování.

Stejným zůsobem přejmenujeme i metodu Metoda, která provádí součet dvou parametrů. Při přejmenovávání nemusíme Rename volat z deklarace příslušného kódu, ale klidně i z jakéhokoliv výskytu daného názvu.  Proveďme tedy refaktorizaci názvu metody Metoda, která je volána na řádku 21 tím, že na ni klikneme a zvolíme z kontextového menu Refactor->Rename... a přejmenujeme ji na Soucet.

Doslova "třešničkou na dortu" této refaktorizační techniky je možnost přejmenovávání celých namespace, tedy prostorů názvů, v nichž se naše aplikace nachází.

2. Extrakce metody (Extract Method...)

Další "závada" na uvedeném zdrojovém kódu je redundantní výskyt kódu. Přesněji jde o kód počítající podíl dvou čísel. První výskyt začíná na řádku 27, druhý na řádku 48. Mnohem lepší by bylo mít metodu pro počítání podílu a následně tuto metodu pouze volat.

Refaktorizační technika Extract Method umožňuje velmi jednoduše vytvořit takovouto metodu z vybraného zdrojového kódu. Extrahujme si tedy metodu pro počítání podílu dvou čísel.

Metodu extrahujeme tím, že se stisknutým levým tlačítkem vybereme kód, který zajišťuje potřebnou funkcionalitu (v našem případě vybereme řádky 28 a 29) a z kontextového menu vybereme Refactor->Extract Method... Následně zadáme název metody (např. Podil) a potvrdíme.

Tím došlo k vytvoření nové metody, v jejímž těle se nachází původní vybraný kód. Visual Studio navíc zajistilo, že vytvořená metoda přebírá dva parametry potřebné pro výpočet a je příslušného návratového typu.

Pozn.: Pro správnou činnost je v tomto případě nutné ve vygenerované metodě defaultně incializovat proměnnou _výsledek.

 3. Zapouzdření pole (Encapsulate Field...)

Když se podíváte hned na začátek vypsaného zdrojového kódu, uvidíte stejnou "hrubku", jako je záměna tvrdého a měkkého "i" v pravopise. Jde o řádek 15, na kterém je uvedena deklarace a inicializace vnitřní proměnné s veřejným modifikátorem přístupu.

Encapsulate Field nám umožní velmi rychlé vypořádání se s tímto problémem pomocí zapouzdření proměnné do vlastnosti.

Proměnnou zapouzdříme tím, že klikneme na její název (v našem případě na název _cislo) a z kontextové nabídky zvolímte Refactor->Encapsulate Field...

Zadáme název vlastnosti do níž bude proměnná zapouzdřena a dále můžeme zvolit několik možností jako tomu bylo i u Rename. Zajímavostí je, že Visual Studio automaticky nabídne název vlastnosti podle normy pro pojmenovávání (tedy odstranění podtržítka "_" a změna prvního písmene z malého na velké).

Potvrzením dojde ke změně modifikátoru přístupu původní proměnné na private a vygenerování veřejné vlastnosti.

4. Extrakce rozhraní (Extract Interface...)

Extrakce rozhraní umožní na základě obsahu třídy vytvořit rozhraní, které je posléze možné použít pro odvozování.

K extrakci stačí umístit kurzor kdekoliv dovnitř třídy a z kontextového menu zvolit Refactor->Extract Interface... Následně v dialogovém okně zadáme název rozhraní a vybereme veřejné členy, které budou rozhraní tvořit. Potvrzením dojde k vygenerování rozhraní a zároveň i odvození aktuální třídy od nového rozhraní.

5. Povýšení lokální proměnné na parametr (Promote Local Variable to Parameter...)

Podívejme se ne metodu Mocnina, která v aktuální podobě počítá druhou mocninu čísla vstupujícího jako parametr do metody. Současný kód je hodně neefektivní, neboť obsahuje deklaraci a inicializaci zbytečné proměnné. Navíc i podoba metody není zrovna nejlepší. Co takto vnitřní proměnnou _exponent povýšit na parametr a tím docílit, aby metoda počítala i mocniny jiných řádů než je 2?

Umístěme kurzor na název proměnné na řádku 41 a z kontextové nabídky zvolme Refactor->Promote Local Variable to Parameter...

Nyní si můžeme všimnout, že do deklarace metody Mocnina skutečně přibyl nový paramter. Navíc bylo upraveno i volání této metody na řádku 52 přidáním hodnoty parametru podle toho, jak byla původní proměnná inicializována.

6. Odstranění (Remove) a přeuspořádání (Regroup) parametrů

Jako poslední nám zbývá upravit metodu Vypocet. Jak vidíte, metoda má spoustu parametrů, které jsou zpřeházené a některé z nich dokonce nevyužité.

Pro jejich odstranění a přeuspořádání slouží refaktorizační techniky Remove Parameters a Regroup Parameters, které lze zavolat z kontextové nabídky vyvolané uvnitř metody. Můžeme tedy odstranit nevyužité parametry d, e a zbývající parametry uspořádat podle abecedy. Jako změny provedené všemi refaktorizačními technikami tak i tyto se provedou nejen u deklarace metody, ale upraví i všechna její volání.

 Závěr

Na velmi jednoduchém a krátkém kousku zdrojového kódu jsme si ukázali, co všechno dokáže refaktorizace, kterou provádí Visual Studio. Tyto techniky však nabývají mnohem větší význam při úpravách rozsáhlých projektů, kdy je jistě oceníte, a to nejen když se vám dostane do ruky kód, který je velmi "nepěkně" napsán. 

Doufám, že jsem vám tímto článkem dokázal, že Visual Studio není jen o psaní kódu, ale také poskytuje velmi vyspělou funkcionalitu, mezi níž manipulace se zdrojovým kódem pomocí refaktorizace bezesporu patří.

Lukáš Kouřil :: 13. května 2008 :: 697 shlédnutí :: 0 komentářů
kategorie: Obecná .Net témata, Vývoj webových aplikací, Vývoj Windows aplikací, Microsoft - produkty

Comments

Nyní zde nejsou žádné kometáře. Buďte první!
Musíte být přihlášen pro posílání komentářů. Přihlásit se můžete zde
Přehled posledních diskuzí

Přehled posledních diskuzí

  1. RE: Dive IN [08.07.2008 12:01 odp.]
    Dobrý den,tak jsem zjistil, že v kořenovém adresáři webu clanzone chyběl adresář "App_Themes".a tady je nový odkaz ke st...
  2. RE: Dive IN [08.06.2008 3:22 odp.]
    Tak dlouho jsem hledal na webu až jsem to stáhl. Je třeba to odladit. Tady je link ke stažení: http://uloz.to/639063/Cla...
  3. RE: slidy z akce 15.5 na MFF [05.22.2008 7:47 odp.]
    Ahoj,omlouvam se za zpozdeni. Uz je to vsechno k dispozici v sekci "Ke Stazeni".
  4. 2 cpu [05.22.2008 10:59 dop.]
    AhojNeviem ci moj dotaz pisem do spravnej sekcie fora ale asi to bude jedno.Potreboval by som poradit ako spravitwhile(t...
Novinky z klubů

Novinky z klubů

  1. Vývojářské odpoledne - Zima 2008 28. září 2008
    Každé čtvrteční odpoledne se podíváme pod pokličku nějaké technologii předevš&...
  2. Programátorské večery 26. září 2008
    Programátorské večery se v zimním semestru 08/09 konají opět ve čtvrtek od 17:20 v učebně S4...
  3. Večery: Microsoft XNA - snadný vývoj her 24. září 2008
    Microsoft XNA je platforma určená pro snadný vývoj počítačových her pro PC, Xbox 360 ...
  4. Programátorské Odpoledne na MFF UK 11. května 2008
    Ve čtvrtek 15. května proběhne na MFF UK na Malostranském nám. (v posluchárně S5) od 16:00 do 19:00...
Co se píše jinde

Co se píše jinde

Dědičnost

V tomto díle si vysvětlíme základy dědičnosti a přepisování metod z rodičovských tříd. Povíme si také, co jsou to abs...

Vydáno Mono 2.0

Dnes byla vydána dlouho očekávaná verze open source implementace .NET frameworku pro Unix, Windows, MacOS a další ope...

WebExpo 2008

Tento podzim se uskuteční první ročník dosud největšího dvoudenního veletrhu o technologiích, webdesignu a marketingu...

ImagineCup

Upoutávka na celosvětovou studentskou soutěž Imagine Cup 2009!

3) DLR - Parser

Parser je velice důležitá část kompilátoru. Jeho úkolem je sestavit abstract syntax tree (AST) z tokenů vygenerovanýc...